~ubuntu-dev/ubuntu/lucid/dovecot/lucid-201002101901

« back to all changes in this revision

Viewing changes to debian/patches/dovecot-libsieve.dpatch

  • Committer: Chuck Short
  • Date: 2010-01-21 20:21:25 UTC
  • mfrom: (4.1.11 squeeze)
  • Revision ID: zulcss@ubuntu.com-20100121202125-pme73o491kfwj5nc
* Merge from debian testing, remaining changes:
  + Add new binary pkg dovecot-postfix that integrates postfix and dovecot
    automatically: (LP: #164837)
  + debian/control:
    - add new binary with short description
    - set Architecture all for dovecot-postfix (LP: #329878)
  + debian/dovecot-postfix.postinst:
    - create initial certificate symlinks to snakeoil.
    - set up postfix with postconf to:
      - use Maildir/ as the default mailbox.
      - use dovecot as the sasl authentication server.
      - use dovecot LDA (deliver).
      - use tls for smtp{d} services.
    - fix certificates paths in postfix' main.cf
    - add reject_unauth_destination to postfix' recipient restrictions
    - add reject_unknown_sender_domain to postfix' sender restriction
    - rename configuration name on remove, delete on purge
    - restart dovecot after linking certificates
    - handle use case when postfix is unconfigurated
  + debian/dovecot-postfix.dirs: create backup directory for postfix's config
    configuration
  + restart postfix and dovecot.
  + debian/dovecot-postfix.postrm:
    - remove all dovecot related configuration from postfix.
    - restart postfix and dovecot.
  + debian/dovecot-common.init:
    - check if /etc/dovecot/dovecot-postfix.conf exists and use it
      as the configuration file if so.
  + debian/patches/warning-ubuntu-postfix.dpatch
    - add warning about dovecot-postfix.conf in dovecot default
      configuration file
  + debian/patches/dovecot-postfix.conf.diff:
    - Ubuntu server custom changes to the default dovecot configuration for
      better interfation with postfix.
    - enable sieve plugin.
    - Ubuntu server custom changes to the default dovecot configuration for
      better integration with postfix:
      - enable imap, pop3, imaps, pop3s and managesieve by default.
      - enable dovecot LDA (deliver).
      - enable SASL auth socket in postfix private directory
   + debian/rules:
     - copy, patch and install dovecot-postfix.conf in /etc/dovecot/.
     - build architecure independent packages too
   + Use Snakeoil SSL certificates by default.
     - debian/control: Depend on ssl-cert.
     - debian/patches/ssl-cert-snakeoil.dpatch: Change default SSL cert
       paths to snakeoil.
     - debian/dovecot-common.postinst: Relax grep for SSL_* a bit.
   + Add autopkgtest to debian/tests/*.
   + Fast TearDown: Update the lsb init header to not stop in level 6.
   + Add ufw integration:
     - Created debian/dovecot-common.ufw.profile.
     - debian/rules: install profile.
     - debian/control: suggest ufw.
   + debian/{control,rules}: enable PIE hardening.
   + dovecot-imapd, dovecot-pop3: Replaces dovecot-common (<< 1:1.1). (LP: #254721)
   + debian/control: Update Vcs-* headers.
   + Add SMTP-AUTH support for Outlook (login auth mechanism)
* New upstream release.
* debian/patches/gold-fix.patch: Removed. Fixed upstream.
* Moved libexec to lib corrections in dovecot-managesieve.patch and
  dovecot-managesieve-dist.patch to dovecot-example.patch
* debian/patches/dovecot-mboxlocking.patch: Regenerated to avoid FTBFS
  when quilt isn't installed.
* debian/patches/quota-mountpoint.patch: Removed. Not needed anymore.
* debian/patches/dovecot-quota.patch: Removed. Quotas aren't properly
  enabled unless mail_plugins = quota imap_quota.
* debian/patches/gold-fix.patch: Fixed configure script to build even
  with binutils-gold or --no-add-needed linker flag (Closes: #554306)
* debian/dovecot-common.init: fixed LSB headers. Thanks to Pascal Volk.
  (Closes: #558040)
* debian/changelog: added CVE references to previous changelog entry.
* debian/rules: checked up the build system. It's not fragile anymore.
  (Closes: 493803)
* debian/dovecot-common.postinst: Now invoking dpkg-reconfigure
  on dovecot-common is enough to generate new certificates
  if the previous ones were removed. (Closes: #545582)
* debian/rules: No longer install convert-tool in /usr/bin.
  It isn't an user utility and it should stay in /usr/lib/dovecot
  like all other similar tool.
* New upstream release. (Closes: #557601)
* [SECURITY] Fixes local information disclosure and denial of service.
  (see: http://www.dovecot.org/list/dovecot-news/2009-November/000143.html
  and CVE-2009-3897)
* Added myself to uploaders.
* Switched to the new source format "3.0 (quilt)":
  - removed dpatch from build-depends
  - removed debian/README.source because now we use only standard
    dpkg features
  - regenerated all patches
* Prepared to switch to multi-origin source:
  - recreated dovecot-libsieve.patch and dovecot-managesieve-dist.patch
    starting from the upstream tarball
  - removed all autotools related build-depends and build-conflict
  - renamed dovecot-libsieve and dovecot-managesieve directories
    to libsieve and managesieve.
* debian/rules: Moved the configuration of libsieve and managesieve from
  the build phase to the configuration phase
* Added dovecot-dbg package  with debugging symbols.  Thanks Stephan Bosch.
  (Closes: #554710)
* Fixed some stray libexec'isms in the default configuration.
* New upstream release.
* debian/dovecot-common.init:
  - use $CONF when starting the daemon. (Closes: #549944)
  - always output start/stop messages. (Closes: #523810)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#! /bin/sh -e
2
 
 
3
 
## DP: Adds support for SIEVE in Dovecot LDA (deliver)
4
 
## DP: Version 0.1.11 (http://www.rename-it.nl/dovecot/1.2/dovecot-1.2-sieve-0.1.12.tar.gz)
5
 
 
6
 
. $(dirname $0)/DPATCH
7
 
 
8
 
exit 0
9
 
@DPATCH@
10
 
diff -urN dovecot-1.2.4/dovecot-libsieve/AUTHORS dovecot-1.2.4.debian/dovecot-libsieve/AUTHORS
11
 
--- dovecot-1.2.4/dovecot-libsieve/AUTHORS      1970-01-01 01:00:00.000000000 +0100
12
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/AUTHORS       2008-10-29 00:59:13.000000000 +0100
13
 
@@ -0,0 +1,13 @@
14
 
+Stephan Bosch <stephan@rename-it.nl>
15
 
+
16
 
+This plugin is partly based on the original cmusieve plugin for the Dovecot 
17
 
+secure IMAP server. It is based only on code relating to interfacing the CMU 
18
 
+Sieve implementation to Dovecot, meaning that no CMU code is incorporated in 
19
 
+this implementation. 
20
 
+
21
 
+Both the cmusieve plugin and the Dovecot IMAP server are primarily written by:
22
 
+
23
 
+Timo Sirainen <tss@iki.fi>
24
 
+
25
 
+View the AUTHORS files in the Dovecot and Dovecot-Sieve distributions for other 
26
 
+contributors. 
27
 
diff -urN dovecot-1.2.4/dovecot-libsieve/ChangeLog dovecot-1.2.4.debian/dovecot-libsieve/ChangeLog
28
 
--- dovecot-1.2.4/dovecot-libsieve/ChangeLog    1970-01-01 01:00:00.000000000 +0100
29
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/ChangeLog     2009-08-21 01:04:32.000000000 +0200
30
 
@@ -0,0 +1,8114 @@
31
 
+2009-08-21  Stephan Bosch  <stephan@rename-it.nl>
32
 
+
33
 
+       * NEWS:
34
 
+       Updated NEWS file for next release.
35
 
+       [645e77f279de] [tip]
36
 
+
37
 
+2009-08-16  Stephan Bosch  <stephan@rename-it.nl>
38
 
+
39
 
+       * TODO:
40
 
+       Updated TODO.
41
 
+       [0fe00772366f]
42
 
+
43
 
+       * Makefile.am, src/testsuite/testsuite-script.c,
44
 
+       src/testsuite/testsuite.c, tests/extensions/include/execute.svtest,
45
 
+       tests/extensions/include/execute/actions-fileinto.sieve,
46
 
+       tests/extensions/include/execute/included/actions-fileinto1.sieve,
47
 
+       tests/extensions/include/execute/included/actions-fileinto2.sieve,
48
 
+       tests/extensions/include/execute/included/actions-fileinto3.sieve:
49
 
+       Testsuite: added action execution test for the include extension
50
 
+       with stored binaries.
51
 
+       [e94731815d2d]
52
 
+
53
 
+       * src/lib-sieve/sieve-script.c:
54
 
+       Made sure script can be compared to NULL.
55
 
+       [cf5487f0c81a]
56
 
+
57
 
+       * Makefile.am, src/testsuite/Makefile.am, src/testsuite/cmd-test-
58
 
+       binary.c, src/testsuite/ext-testsuite.c, src/testsuite/testsuite-
59
 
+       binary.c, src/testsuite/testsuite-binary.h, src/testsuite/testsuite-
60
 
+       common.c, src/testsuite/testsuite-common.h, src/testsuite/testsuite-
61
 
+       script.c, src/testsuite/testsuite-script.h,
62
 
+       tests/compile/examples.svtest, tests/execute/examples.svtest:
63
 
+       Testsuite: added support for testing binaries stored on disk.
64
 
+       [79d330457a69]
65
 
+
66
 
+       * src/lib-sieve/sieve-error.c:
67
 
+       Fixed bug in error reporting when binary-related script object is
68
 
+       not set.
69
 
+       [48b7ad7a35ab]
70
 
+
71
 
+2009-08-15  Stephan Bosch  <stephan@rename-it.nl>
72
 
+
73
 
+       * TODO:
74
 
+       Updated TODO list.
75
 
+       [74e061124cf3]
76
 
+
77
 
+       * README:
78
 
+       Updated documentation.
79
 
+       [329e2e31c14f]
80
 
+
81
 
+       * Makefile.am, tests/extensions/date/basic.svtest,
82
 
+       tests/extensions/date/date-parts.svtest,
83
 
+       tests/extensions/date/zones.svtest:
84
 
+       Testsuite: added tests for the new date extension.
85
 
+       [4e9e557052ff]
86
 
+
87
 
+       * src/lib-sieve/Makefile.am, src/lib-sieve/plugins/Makefile.am, src
88
 
+       /lib-sieve/plugins/date/ext-date.c, src/lib-sieve/sieve-
89
 
+       extensions.c:
90
 
+       Date extension: now included in default compile.
91
 
+       [8dfb24ac1e4c]
92
 
+
93
 
+       * src/lib-sieve/plugins/date/tst-date.c:
94
 
+       Date extension: accidentally committed debug printf.
95
 
+       [c296d6bea23e]
96
 
+
97
 
+       * src/lib-sieve/plugins/date/ext-date-common.c, src/lib-
98
 
+       sieve/plugins/date/tst-date.c:
99
 
+       Date extension: fixed problems in time zone handling.
100
 
+       [870d6b440c38]
101
 
+
102
 
+       * src/testsuite/testsuite-message.c:
103
 
+       Testsuite: added some debug code.\n
104
 
+       [f04fc584ca85]
105
 
+
106
 
+       * src/lib-sieve/plugins/date/ext-date-common.c:
107
 
+       Date extension: fixed bug in julian date calculation.
108
 
+       [addaeebef178]
109
 
+
110
 
+       * src/lib-sieve/plugins/date/ext-date-common.c, src/lib-
111
 
+       sieve/plugins/date/tst-date.c:
112
 
+       Date extension: fixed a few bugs related to date part extraction.
113
 
+       [3010ae60056c]
114
 
+
115
 
+       * src/lib-sieve/plugins/date/tst-date.c:
116
 
+       Date extension: fixed errorhandling of gmtime() call.
117
 
+       [acf485c1e359]
118
 
+
119
 
+       * src/lib-sieve/plugins/date/ext-date-common.c, src/lib-
120
 
+       sieve/plugins/date/tst-date.c:
121
 
+       Date extension: completed implementation.
122
 
+       [77fe808ea758]
123
 
+
124
 
+       * src/lib-sieve/plugins/date/ext-date-common.c:
125
 
+       Date extension: all simple integer date parts are fixed-length
126
 
+       strings.
127
 
+       [0410db763a44]
128
 
+
129
 
+       * src/lib-sieve/plugins/date/ext-date-common.c, src/lib-
130
 
+       sieve/plugins/date/ext-date-common.h, src/lib-sieve/plugins/date
131
 
+       /tst-date.c:
132
 
+       Date extension: implemented time zone handling.
133
 
+       [9cd4612b1680]
134
 
+
135
 
+       * src/lib-sieve/plugins/date/ext-date-common.c:
136
 
+       Date extension: implemented iso8601 date part.
137
 
+       [236fb0006d9c]
138
 
+
139
 
+       * src/lib-sieve/plugins/date/ext-date-common.c:
140
 
+       Date extension: implemented a few more date parts.
141
 
+       [9d81ee954315]
142
 
+
143
 
+2009-08-10  Stephan Bosch  <stephan@rename-it.nl>
144
 
+
145
 
+       * Makefile.am:
146
 
+       Fixed distribution of unfinished features.
147
 
+       [03cb0e6d4a35]
148
 
+
149
 
+2009-08-09  Stephan Bosch  <stephan@rename-it.nl>
150
 
+
151
 
+       * src/lib-sieve/plugins/date/Makefile.am, src/lib-sieve/plugins/date
152
 
+       /ext-date-common.c, src/lib-sieve/plugins/date/ext-date-common.h,
153
 
+       src/lib-sieve/plugins/date/ext-date.c, src/lib-sieve/plugins/date
154
 
+       /tst-date.c:
155
 
+       Date extension: built infrastructure for date part testing.
156
 
+       [c679aa4cb12c]
157
 
+
158
 
+2009-08-08  Stephan Bosch  <stephan@rename-it.nl>
159
 
+
160
 
+       * .hgtags:
161
 
+       Added tag 0.1.11 for changeset 82c5b529b002
162
 
+       [45be092f98c7]
163
 
+
164
 
+       * configure.in:
165
 
+       Released v0.1.11 for Dovecot v1.2.3.
166
 
+       [82c5b529b002] [0.1.11]
167
 
+
168
 
+       * NEWS, doc/man/sieve-filter.1:
169
 
+       Updated NEWS file for next release.
170
 
+       [715bb2f65e82]
171
 
+
172
 
+2009-08-07  Stephan Bosch  <stephan@rename-it.nl>
173
 
+
174
 
+       * Merged concurrent changes.
175
 
+       [0af8fa38807e]
176
 
+
177
 
+       * Makefile.am, doc/man/sieve-filter.1:
178
 
+       Sieve-filter: created man-page a design for the command line
179
 
+       options.
180
 
+       [e357bd4f02e8]
181
 
+
182
 
+       * src/lib-sieve/plugins/include/ext-include-common.c:
183
 
+       Include: compare execution result to SIEVE_EXEC_OK and not to zero.
184
 
+       [3b956913d5bc]
185
 
+
186
 
+       * src/lib-sieve/plugins/include/ext-include-common.c, src/lib-
187
 
+       sieve/plugins/include/ext-include-common.h:
188
 
+       Include: fixed return type of execution function.
189
 
+       [824048b8571c]
190
 
+
191
 
+       * src/lib-sieve/plugins/include/ext-include-binary.c:
192
 
+       Fixed erroneous comment in binary implementation.
193
 
+       [77d19dfcd085]
194
 
+
195
 
+2009-08-06  Stephan Bosch  <stephan@rename-it.nl>
196
 
+
197
 
+       * TODO:
198
 
+       Fixed typo in TODO file.
199
 
+       [d9da9d373bca]
200
 
+
201
 
+2009-08-05  Stephan Bosch  <stephan@rename-it.nl>
202
 
+
203
 
+       * TODO:
204
 
+       Updated TODO.
205
 
+       [113dd62b0111]
206
 
+
207
 
+       * configure.in, src/lib-sieve/Makefile.am, src/lib-
208
 
+       sieve/plugins/Makefile.am, src/lib-sieve/plugins/date/Makefile.am,
209
 
+       src/lib-sieve/plugins/date/ext-date-common.h, src/lib-
210
 
+       sieve/plugins/date/ext-date.c, src/lib-sieve/plugins/date/tst-
211
 
+       date.c, src/lib-sieve/sieve-extensions.c:
212
 
+       Built skeleton implementation for the date extension (RFC 5260).
213
 
+       [ccdc02029e0f]
214
 
+
215
 
+       * src/lib-sieve/plugins/body/tst-body.c:
216
 
+       Body: fixed erroneous return code for invalid optional operand.
217
 
+       [2c44457561c9]
218
 
+
219
 
+       * src/lib-sieve/sieve-binary.c, src/lib-sieve/sieve-binary.h, src/lib-
220
 
+       sieve/sieve-code.c, src/lib-sieve/sieve-code.h, src/lib-sieve/sieve-
221
 
+       interpreter.c:
222
 
+       Be explicit about signedness of data in binary code representation.
223
 
+       Some architectures, like ARM, differ in this respect.
224
 
+       [bbb2e488172f]
225
 
+
226
 
+       * src/lib-sieve/plugins/copy/ext-copy.c, src/lib-
227
 
+       sieve/plugins/imap4flags/cmd-flag.c, src/lib-
228
 
+       sieve/plugins/imap4flags/ext-imap4flags-common.c, src/lib-
229
 
+       sieve/plugins/imap4flags/tag-flags.c, src/lib-sieve/plugins/mailbox
230
 
+       /ext-mailbox.c, src/lib-sieve/sieve-actions.h, src/lib-sieve/sieve-
231
 
+       code.h:
232
 
+       Side-effect argumennt registrations were not using the
233
 
+       SIEVE_OPT_SIDE_EFFECT constant.
234
 
+       [0478be666511]
235
 
+
236
 
+       * src/lib-sieve/sieve-binary.c, src/lib-sieve/sieve-common.h:
237
 
+       Removed direct stdint.h includes to prevent portability issues.
238
 
+       [6090ba0d6f03]
239
 
+
240
 
+2009-08-04  Stephan Bosch  <stephan@rename-it.nl>
241
 
+
242
 
+       * NEWS:
243
 
+       Updated NEWS file for next release.
244
 
+       [a317da703765]
245
 
+
246
 
+       * TODO:
247
 
+       Reprioritized and reformatted TODO file.
248
 
+       [05117882b72a]
249
 
+
250
 
+       * src/lib-sieve/sieve.c:
251
 
+       Fixed segfault bug in the handling of script open failures.
252
 
+       [b33127dc5d1b]
253
 
+
254
 
+       * src/lib-sieve/plugins/include/cmd-include.c, src/lib-
255
 
+       sieve/plugins/include/ext-include-common.c:
256
 
+       Include: further adjusted log and user messages.
257
 
+       [86a000cf54d4]
258
 
+
259
 
+       * src/plugins/lda-sieve/lda-sieve-plugin.c:
260
 
+       LDA-Sieve plugin: fixed copy-paste mixup between sieve_after and
261
 
+       sieve_before. If only a sieve_after script was active, nothing would
262
 
+       have been executed. Patch by Mike Abbott.
263
 
+       [1c0543e52ed5]
264
 
+
265
 
+       * src/lib-sieve/plugins/include/ext-include-common.c:
266
 
+       Include: fixed bug in /home/stephan substitution in sieve_dir path.
267
 
+       [ab82a70d9907]
268
 
+
269
 
+       * src/lib-sieve/plugins/include/cmd-include.c, src/lib-
270
 
+       sieve/plugins/include/ext-include-common.h:
271
 
+       Include: improved error messages for include failures.
272
 
+       [205b0ec811ee]
273
 
+
274
 
+       * src/lib-sieve/plugins/include/cmd-include.c:
275
 
+       Include: removed variables-related FIXME and substituted a permanent
276
 
+       error message.
277
 
+       [069263b9f3e5]
278
 
+
279
 
+2009-08-03  Stephan Bosch  <stephan@rename-it.nl>
280
 
+
281
 
+       * .hgtags:
282
 
+       Added tag 0.1.10 for changeset 8ae9b01db362
283
 
+       [16bb88837266]
284
 
+
285
 
+       * NEWS, configure.in:
286
 
+       Released v0.1.10 for Dovecot v1.2.2.
287
 
+       [8ae9b01db362] [0.1.10]
288
 
+
289
 
+       * src/testsuite/Makefile.am:
290
 
+       Forgot to add header in Makefile.am for testsuite.
291
 
+       [7db3f5e8b7dd]
292
 
+
293
 
+       * src/lib-sieve/plugins/mailbox/Makefile.am:
294
 
+       Fixed automake bug in new maibox extension sources.
295
 
+       [56e86c8e7419]
296
 
+
297
 
+2009-08-02  Stephan Bosch  <stephan@rename-it.nl>
298
 
+
299
 
+       * NEWS:
300
 
+       Added dependency notice to the NEWS file.
301
 
+       [85caab9894a0]
302
 
+
303
 
+       * NEWS:
304
 
+       Updated NEWS file for next release.
305
 
+       [a5e590c49e86]
306
 
+
307
 
+       * Makefile.am:
308
 
+       Testsuite: made valgrind report all allocated blocks that remain at
309
 
+       program end.
310
 
+       [d206080c122b]
311
 
+
312
 
+       * src/testsuite/testsuite-common.c:
313
 
+       Testsuite: properly deallocated test name string buffer upon close.
314
 
+       [2b592e23b02f]
315
 
+
316
 
+       * src/lib-sieve/sieve-match.c:
317
 
+       Fixed memory leak in matching code caused by earlier fix.
318
 
+       [314cacead8aa]
319
 
+
320
 
+       * src/lib-sieve/sieve.c, src/lib-sieve/sieve.h, src/sieve-
321
 
+       tools/sieved.c:
322
 
+       Made proper API for loading a binary directly.
323
 
+       [f52049f1196d]
324
 
+
325
 
+       * tests/extensions/imap4flags/flagstore.svtest:
326
 
+       Testsuite: added an important test for the imap4flags extension.
327
 
+       [baf3540e80fb]
328
 
+
329
 
+       * Makefile.am, TODO, tests/extensions/imap4flags/flagstore.svtest:
330
 
+       Imap4flags: added flag storage tests using mailbox loopback.
331
 
+       [cfec3730793e]
332
 
+
333
 
+       * src/lib-sieve/plugins/imap4flags/ext-imap4flags-common.c,
334
 
+       tests/extensions/imap4flags/basic.svtest:
335
 
+       Imap4flags: now reads initial flags and keywords from supplied mail.
336
 
+       Upon delivery this is empty, which still matches the specification.
337
 
+       [bde86aa3a552]
338
 
+
339
 
+       * src/lib-sieve/sieve-result.c, src/lib-sieve/sieve-result.h:
340
 
+       Added access methods for message data en script environment to
341
 
+       result object.
342
 
+       [ba533745f5e9]
343
 
+
344
 
+       * Makefile.am, TODO, src/testsuite/cmd-test-message.c, src/testsuite
345
 
+       /testsuite-mailstore.c, tests/execute/mailstore.svtest,
346
 
+       tests/extensions/mailbox/execute.svtest:
347
 
+       Testsuite: added support for testing delivered messages by looping
348
 
+       these back as the evaluated message. Added tests for the fileinto
349
 
+       command.
350
 
+       [f4f4a6c5cba9]
351
 
+
352
 
+2009-08-01  Stephan Bosch  <stephan@rename-it.nl>
353
 
+
354
 
+       * README:
355
 
+       Updated README.
356
 
+       [2bd355dabcfb]
357
 
+
358
 
+       * TODO, src/lib-sieve/plugins/mailbox/cmd-mailboxexists.c, src/lib-
359
 
+       sieve/plugins/mailbox/ext-mailbox.c:
360
 
+       Updated TODO and added a FIXME to the mailbox extension (no ACL
361
 
+       support yet, but required by RFC).
362
 
+       [15fadac299a3]
363
 
+
364
 
+       * Makefile.am, tests/extensions/mailbox/execute.svtest:
365
 
+       Testsuite: added tests for the mailbox extension.
366
 
+       [0691a3804073]
367
 
+
368
 
+       * src/lib-sieve/plugins/mailbox/cmd-mailboxexists.c, src/lib-
369
 
+       sieve/plugins/mailbox/ext-mailbox.c:
370
 
+       Mailbox extension: finished implementation.
371
 
+       [7b772c4fa332]
372
 
+
373
 
+       * src/lib-sieve/sieve-lexer.c:
374
 
+       Small code cleanup in the lexer code.
375
 
+       [57307603b757]
376
 
+
377
 
+       * doc/man/sieve-test.1, doc/man/sievec.1, doc/man/sieved.1:
378
 
+       Updated man pages.
379
 
+       [963fe9ea3eb1]
380
 
+
381
 
+2009-07-31  Stephan Bosch  <stephan@rename-it.nl>
382
 
+
383
 
+       * src/lib-sieve/sieve-script.c:
384
 
+       Fixed bug in the derivation of the binary path from the script path.
385
 
+       A bare filename would yield a path relative to root.
386
 
+       [5d4eb8918bf8]
387
 
+
388
 
+       * src/testsuite/Makefile.am, src/testsuite/cmd-test-mailbox.c,
389
 
+       src/testsuite/ext-testsuite.c, src/testsuite/testsuite-common.h,
390
 
+       src/testsuite/testsuite-mailstore.c, src/testsuite/testsuite-
391
 
+       mailstore.h, src/testsuite/testsuite-message.c, src/testsuite
392
 
+       /testsuite-message.h, src/testsuite/testsuite.c,
393
 
+       tests/execute/actions.svtest,
394
 
+       tests/extensions/imap4flags/execute.svtest:
395
 
+       Testsuite: added support for testing mailbox operations.
396
 
+       [c71d7e59d532]
397
 
+
398
 
+       * autogen.sh, configure.in:
399
 
+       Use foreign automake option so it doesn't complain about missing
400
 
+       ChangeLog.
401
 
+       [f33c8245ef95]
402
 
+
403
 
+2009-07-30  Stephan Bosch  <stephan@rename-it.nl>
404
 
+
405
 
+       * src/lib-sieve/plugins/regex/mcht-regex.c:
406
 
+       Regex: documented source code a little better.
407
 
+       [3c9a22c28156]
408
 
+
409
 
+       * src/lib-sieve/plugins/mailbox/tag-mailbox-create.c:
410
 
+       Mailbox extension: fixed compiler warning.
411
 
+       [cc49d7080a14]
412
 
+
413
 
+       * src/lib-sieve/ext-envelope.c, src/lib-sieve/plugins/body/tst-body.c,
414
 
+       src/lib-sieve/plugins/enotify/tst-notify-method-capability.c, src
415
 
+       /lib-sieve/plugins/environment/tst-environment.c, src/lib-
416
 
+       sieve/plugins/imap4flags/tst-hasflag.c, src/lib-sieve/plugins/regex
417
 
+       /mcht-regex.c, src/lib-sieve/plugins/relational/mcht-count.c, src
418
 
+       /lib-sieve/plugins/variables/tst-string.c, src/lib-sieve/sieve-
419
 
+       match.c, src/lib-sieve/sieve-match.h, src/lib-sieve/tst-address.c,
420
 
+       src/lib-sieve/tst-header.c, src/testsuite/tst-test-error.c,
421
 
+       src/testsuite/tst-test-result.c:
422
 
+       Made sieve_match_context use a proper pool in stead of the
423
 
+       datastack.
424
 
+       [f316a10179f3]
425
 
+
426
 
+2009-07-29  Stephan Bosch  <stephan@rename-it.nl>
427
 
+
428
 
+       * TODO:
429
 
+       Added TODO item.
430
 
+       [8f2945e2714b]
431
 
+
432
 
+       * src/lib-sieve/plugins/include/ext-include.c:
433
 
+       Include: fixed assertion fail caused by missing initialization (bug
434
 
+       surfaces only for stored binaries).
435
 
+       [d989537882d0]
436
 
+
437
 
+       * src/lib-sieve/plugins/include/ext-include-common.c:
438
 
+       Include: include error message for failed :global include.
439
 
+       [449d8ecb0f34]
440
 
+
441
 
+2009-07-27  Stephan Bosch  <stephan@rename-it.nl>
442
 
+
443
 
+       * src/sieve-tools/sieve-filter.c:
444
 
+       Sieve-filter: removed unnecessary MAILBOX_TRANSACTION_FLAG_REFRESH
445
 
+       flag for mailbox_transaction_begin().
446
 
+       [6ef0cdffb66c]
447
 
+
448
 
+       * TODO:
449
 
+       Reprioritized TODO.
450
 
+       [6dcaf8d54055]
451
 
+
452
 
+       * src/lib-sieve/plugins/mailbox/tag-mailbox-create.c, src/lib-sieve
453
 
+       /sieve-actions.c, src/lib-sieve/sieve-actions.h:
454
 
+       Mailbox extension: implemented the :create tagged argument for the
455
 
+       fileinto command.
456
 
+       [b1920ece04e3]
457
 
+
458
 
+2009-07-26  Stephan Bosch  <stephan@rename-it.nl>
459
 
+
460
 
+       * src/lib-sieve/plugins/imap4flags/tag-flags.c, src/lib-sieve/sieve-
461
 
+       actions.c, src/lib-sieve/sieve-actions.h:
462
 
+       Sieve-filter: added support for setting flags on message in the
463
 
+       source folder.
464
 
+       [28badfffdc1c]
465
 
+
466
 
+       * src/sieve-tools/sieve-filter.c:
467
 
+       Sieve-filter: corrected and optimized mail filter loop.
468
 
+       [2980d32fb5ef]
469
 
+
470
 
+       * src/plugins/lda-sieve/lda-sieve-plugin.c:
471
 
+       Fixed broken wiki reference in error message.
472
 
+       [5c20969f1a50]
473
 
+
474
 
+       * configure.in, src/lib-sieve/Makefile.am, src/lib-
475
 
+       sieve/plugins/mailbox/Makefile.am, src/lib-sieve/plugins/mailbox
476
 
+       /cmd-mailboxexists.c, src/lib-sieve/plugins/mailbox/ext-mailbox-
477
 
+       common.h, src/lib-sieve/plugins/mailbox/ext-mailbox.c, src/lib-
478
 
+       sieve/plugins/mailbox/tag-mailbox-create.c, src/lib-sieve/sieve-
479
 
+       extensions.c:
480
 
+       Implemented skeleton of the mailbox extension.
481
 
+       [ffa5cd58c284]
482
 
+
483
 
+       * src/lib-sieve/plugins/Makefile.am, src/lib-sieve/plugins/notify/cmd-
484
 
+       denotify.c:
485
 
+       Notify (deprecated): fixed compiler warnings.
486
 
+       [8716323f82c4]
487
 
+
488
 
+2009-07-25  Stephan Bosch  <stephan@rename-it.nl>
489
 
+
490
 
+       * src/lib-sieve/sieve-actions.c, src/lib-sieve/sieve-types.h, src
491
 
+       /sieve-tools/sieve-filter.c:
492
 
+       Sieve-filter: implemented alternative discard actions.
493
 
+       [db78e485cbb2]
494
 
+
495
 
+       * src/lib-sieve/sieve-actions.c, src/lib-sieve/sieve-types.h, src
496
 
+       /sieve-tools/sieve-filter.c:
497
 
+       Sieve-filter: implemented expunging filtered messages in the source
498
 
+       folder (move).
499
 
+       [1ea614e1a1a6]
500
 
+
501
 
+       * src/lib-sieve/sieve.c, src/lib-sieve/sieve.h, src/plugins/lda-sieve
502
 
+       /lda-sieve-plugin.c, src/sieve-tools/sieve-filter.c, src/sieve-tools
503
 
+       /sieve-test.c:
504
 
+       Added means to get keep status from sieve execution through main
505
 
+       Sieve library API.
506
 
+       [78c065beba2d]
507
 
+
508
 
+       * src/sieve-tools/sieve-filter.c:
509
 
+       Minor changes to the sieve-filter tool.
510
 
+       [a922ed52ddd6]
511
 
+
512
 
+2009-07-24  Stephan Bosch  <stephan@rename-it.nl>
513
 
+
514
 
+       * src/lib-sieve/sieve-actions.c, src/lib-sieve/sieve-actions.h:
515
 
+       Restructured store action implementation to properly handle an
516
 
+       attempt to store (keep) a message in the folder it originates from.
517
 
+       [32f6d1c48ad4]
518
 
+
519
 
+       * src/lib-sieve/plugins/notify/Makefile.am, src/lib-
520
 
+       sieve/plugins/notify/cmd-denotify.c, src/lib-sieve/plugins/notify
521
 
+       /cmd-notify.c, src/lib-sieve/plugins/notify/ext-notify-common.c, src
522
 
+       /lib-sieve/plugins/notify/ext-notify-common.h, src/lib-
523
 
+       sieve/plugins/notify/ext-notify.c:
524
 
+       Notify (deprecated): implemented skeleton of the denotify command.
525
 
+       [d6efcfec8bb6]
526
 
+
527
 
+       * src/lib-sieve/sieve-actions.c:
528
 
+       Fallback to INBOX when storing into a namespace prefix used wrong
529
 
+       storage.
530
 
+       [a6a435654c31]
531
 
+
532
 
+       * .hgtags:
533
 
+       Merged concurrent changes.
534
 
+       [3b5ee8772a28]
535
 
+
536
 
+       * .hgtags:
537
 
+       Added tag 0.1.9 for changeset fc4b67c99918
538
 
+       [2c64466c64c5]
539
 
+
540
 
+       * NEWS, configure.in:
541
 
+       Released v0.1.9 for Dovecot v1.2.1.
542
 
+       [fc4b67c99918] [0.1.9]
543
 
+
544
 
+       * src/sieve-tools/sieve-filter.c:
545
 
+       Separated source and destination mail store for sieve-filter tool.
546
 
+       [0369e2058441]
547
 
+
548
 
+2009-07-22  Stephan Bosch  <stephan@rename-it.nl>
549
 
+
550
 
+       * .hgtags:
551
 
+       Added tag 0.1.9 for changeset 247163f96a5c
552
 
+       [ca542d793623]
553
 
+
554
 
+       * NEWS:
555
 
+       Updated NEWS file for next release.
556
 
+       [247163f96a5c]
557
 
+
558
 
+       * src/lib-sieve/sieve-actions.c:
559
 
+       Showed wrong folder name upon INBOX fallback.
560
 
+       [26d14a354b0a]
561
 
+
562
 
+       * src/lib-sieve/sieve-actions.c:
563
 
+       Fixed more code indent problems.
564
 
+       [8ddc79659a82]
565
 
+
566
 
+       * src/lib-sieve/sieve-actions.c:
567
 
+       Fixed some code indent problems.
568
 
+       [b9e1ef848f38]
569
 
+
570
 
+       * src/lib-sieve/sieve-actions.c:
571
 
+       Made attempt to store in a namespace prefix fall back into INBOX.
572
 
+       [28280cfcdc80]
573
 
+
574
 
+       * src/lib-sieve/sieve-actions.c:
575
 
+       Fixed logging of folder namespace prefix in store action.
576
 
+       [52226d811da6]
577
 
+
578
 
+       * src/lib-sieve/sieve-validator.c:
579
 
+       Fixed potential segfault argument parameter validation.
580
 
+       [b4eb3a3f1088]
581
 
+
582
 
+2009-07-21  Stephan Bosch  <stephan@rename-it.nl>
583
 
+
584
 
+       * Makefile.am, src/testsuite/testsuite.c, tests/execute/smtp.svtest,
585
 
+       tests/extensions/enotify/mailto.svtest,
586
 
+       tests/extensions/reject/smtp.svtest,
587
 
+       tests/extensions/vacation/smtp.svtest:
588
 
+       Testsuite: added tests on the envelope of outgoing messages produced
589
 
+       by redirect, enotify:mailto, reject and vacation.
590
 
+       [dd9b380fec73]
591
 
+
592
 
+       * src/lib-sieve/cmd-redirect.c, src/lib-sieve/ext-envelope.c, src/lib-
593
 
+       sieve/ext-reject.c, src/lib-sieve/plugins/enotify/cmd-notify.c, src
594
 
+       /lib-sieve/plugins/enotify/ntfy-mailto.c, src/lib-
595
 
+       sieve/plugins/enotify/sieve-ext-enotify.h, src/lib-
596
 
+       sieve/plugins/include/ext-include-common.c, src/lib-
597
 
+       sieve/plugins/notify/cmd-notify.c, src/lib-sieve/plugins/vacation
598
 
+       /cmd-vacation.c, src/lib-sieve/sieve-actions.h, src/lib-sieve/sieve-
599
 
+       address.c, src/lib-sieve/sieve-address.h, src/lib-sieve/sieve-
600
 
+       interpreter.c, src/lib-sieve/sieve-interpreter.h, src/lib-sieve
601
 
+       /sieve-message.c, src/lib-sieve/sieve-message.h, src/lib-sieve
602
 
+       /sieve-result.c, src/lib-sieve/sieve-result.h, src/lib-
603
 
+       sieve/sieve.c, src/testsuite/testsuite-common.c, src/testsuite
604
 
+       /testsuite-common.h, src/testsuite/testsuite-log.c, src/testsuite
605
 
+       /testsuite-message.c, src/testsuite/testsuite-message.h,
606
 
+       src/testsuite/testsuite-objects.c, src/testsuite/testsuite-result.c,
607
 
+       src/testsuite/testsuite-smtp.c, src/testsuite/testsuite.c:
608
 
+       Major rework of envelope address handling: a normalized version of
609
 
+       the envelope addresses is maintained in the message context and
610
 
+       message context is now also available during action execution.
611
 
+       [9ce037c114ae]
612
 
+
613
 
+2009-07-20  Stephan Bosch  <stephan@rename-it.nl>
614
 
+
615
 
+       * src/lib-sieve/plugins/enotify/ntfy-mailto.c, src/lib-
616
 
+       sieve/plugins/notify/cmd-notify.c, src/lib-sieve/sieve-address.c,
617
 
+       src/sieve-tools/sieve-test.c, src/testsuite/testsuite-smtp.c:
618
 
+       Fixed segfault bug: made sure return_path is never used without
619
 
+       checking for NULL first.
620
 
+       [673b13801182]
621
 
+
622
 
+       * src/sieve-tools/Makefile.am:
623
 
+       Removed the sieve-filter tool from the default build. Need to
624
 
+       specify --with-unfinished-features to get this tool built.
625
 
+       [6c76e13aa608]
626
 
+
627
 
+2009-07-19  Stephan Bosch  <stephan@rename-it.nl>
628
 
+
629
 
+       * src/lib-sieve/ext-reject.c, src/lib-sieve/sieve-extensions.c:
630
 
+       Added compilation support for ereject extension. It is unfinished
631
 
+       right now and performs exactly the same action as reject.
632
 
+       [7643e9831866]
633
 
+
634
 
+       * configure.in, dsieve-config.h.in:
635
 
+       Fixed bugs in the autoconf structure regarding enabling/disabling
636
 
+       unfinished features.
637
 
+       [bd0b4c044a85]
638
 
+
639
 
+       * doc/rfc/draft-ietf-sieve-refuse-reject-07.txt, doc/rfc/reject-
640
 
+       ereject.rfc5429.txt:
641
 
+       Downloaded RFC for reject and ereject extensions.
642
 
+       [15f749935cef]
643
 
+
644
 
+       * src/lib-sieve/sieve-binary.c, src/lib-sieve/sieve-error.c, src/lib-
645
 
+       sieve/sieve-script.c:
646
 
+       Improved file manipulation error messages regarding EACCES error.
647
 
+       [2a5955af450f]
648
 
+
649
 
+2009-07-18  Stephan Bosch  <stephan@rename-it.nl>
650
 
+
651
 
+       * tests/extensions/subaddress/basic.svtest:
652
 
+       Testsuite: added tests for envelope/address test behavior with non-
653
 
+       existant subaddress :detail part.
654
 
+       [d8d6a44fef3d]
655
 
+
656
 
+       * src/lib-sieve/ext-envelope.c:
657
 
+       Envelope: fixed bug in application of address parts; failure to
658
 
+       obtain the part would cause inappropriate match success (bug
659
 
+       reported by Ron Lee)
660
 
+       [d80b2a61c716]
661
 
+
662
 
+       * src/lib-sieve/tst-address.c:
663
 
+       Added additional headers to the list of allowed headers for the
664
 
+       address test.
665
 
+       [bbc9fcf1a3fb]
666
 
+
667
 
+2009-07-17  Stephan Bosch  <stephan@rename-it.nl>
668
 
+
669
 
+       * src/lib-sieve/plugins/notify/ext-notify.c:
670
 
+       Notify (deprecated): added FIXME notice with missing compatibility
671
 
+       features.
672
 
+       [aed9f105338c]
673
 
+
674
 
+       * Makefile.am, tests/deprecated/notify/basic.svtest,
675
 
+       tests/deprecated/notify/errors.svtest,
676
 
+       tests/deprecated/notify/errors/options.sieve,
677
 
+       tests/deprecated/notify/execute.svtest,
678
 
+       tests/deprecated/notify/execute/duplicates.sieve,
679
 
+       tests/deprecated/notify/mailto.svtest:
680
 
+       Testsuite: added tests for deprecated notify extension.
681
 
+       [7fcca5c65067]
682
 
+
683
 
+       * src/testsuite/testsuite.c:
684
 
+       Testsuite: added support for specifying the available extensions at
685
 
+       the commandline.
686
 
+       [e492865ee76a]
687
 
+
688
 
+       * tests/extensions/enotify/errors.svtest,
689
 
+       tests/extensions/enotify/errors/from-mailto.sieve:
690
 
+       Testsuite: Notify: added test with empty :from argument for notify
691
 
+       command.
692
 
+       [74b471ab0a90]
693
 
+
694
 
+       * src/lib-sieve/plugins/notify/cmd-notify.c:
695
 
+       Notify (deprecated): fixed segfault bug in the :options argument
696
 
+       validation.
697
 
+       [038b478613a9]
698
 
+
699
 
+       * src/lib-sieve/plugins/notify/cmd-notify.c:
700
 
+       Notify (deprecated): added runtime check for recipient limit.
701
 
+       [1cb03f029e03]
702
 
+
703
 
+       * src/lib-sieve/plugins/notify/cmd-notify.c:
704
 
+       Notify (deprecated): added runtime check for duplicate recipients.
705
 
+       [fa74bf0f35fb]
706
 
+
707
 
+       * src/lib-sieve/plugins/notify/cmd-notify.c:
708
 
+       Notify (deprecated): added support for substitutions in the
709
 
+       notification message.
710
 
+       [d54d06eee248]
711
 
+
712
 
+       * configure.in, src/lib-sieve/Makefile.am, src/lib-
713
 
+       sieve/plugins/Makefile.am, src/lib-
714
 
+       sieve/plugins/enotify/Makefile.am, src/lib-sieve/plugins/enotify
715
 
+       /ext-notify.c, src/lib-sieve/plugins/notify/Makefile.am, src/lib-
716
 
+       sieve/plugins/notify/cmd-denotify.c, src/lib-sieve/plugins/notify
717
 
+       /cmd-notify.c, src/lib-sieve/plugins/notify/ext-enotify.c, src/lib-
718
 
+       sieve/plugins/notify/ext-notify-common.h, src/lib-
719
 
+       sieve/plugins/notify/ext-notify-limits.h, src/lib-
720
 
+       sieve/plugins/notify/ext-notify.c:
721
 
+       Made deprecated notify extension implementation compatible with
722
 
+       cmusieve, except for the denotify command.
723
 
+       [68be002473f5]
724
 
+
725
 
+       * src/lib-sieve/sieve-validator.c:
726
 
+       Fixed validator extension validation. It validated the first non-
727
 
+       require command before validating the extensions, which produced
728
 
+       useless error messages.
729
 
+       [ee92d0b9f7b9]
730
 
+
731
 
+       * src/lib-sieve/cmd-discard.c:
732
 
+       Made discard action log a message to avoid confusion about
733
 
+       disappearing messages.
734
 
+       [f654353b8c13]
735
 
+
736
 
+2009-07-15  Stephan Bosch  <stephan@rename-it.nl>
737
 
+
738
 
+       * src/testsuite/Makefile.am:
739
 
+       Forgot to remove old explicit storage library dependency (patch by
740
 
+       Arkadiusz Miskiewicz).
741
 
+       [31dab511011e]
742
 
+
743
 
+       * src/lib-sieve/rfc2822.c, src/lib-sieve/rfc2822.h:
744
 
+       Inappropriately ignored return value from fwrite in outgoing message
745
 
+       construction.
746
 
+       [83f23dfd5b68]
747
 
+
748
 
+2009-07-13  Stephan Bosch  <stephan@rename-it.nl>
749
 
+
750
 
+       * .hgtags:
751
 
+       Added tag 0.1.8 for changeset fa7741359396
752
 
+       [78b12c497934]
753
 
+
754
 
+       * NEWS, configure.in:
755
 
+       Released v0.1.8 for Dovecot v1.2.1.
756
 
+       [fa7741359396] [0.1.8]
757
 
+
758
 
+2009-07-12  Stephan Bosch  <stephan@rename-it.nl>
759
 
+
760
 
+       * doc/rfc/deprecated/draft-martin-sieve-notify-01.txt,
761
 
+       doc/rfc/deprecated/draft-melnikov-sieve-imapflags-03.txt:
762
 
+       Added draft RFCs for deprecated Sieve extensions imapflags and
763
 
+       notify (as implemented by cmusieve).
764
 
+       [0a2a9e6f9478]
765
 
+
766
 
+       * src/lib-sieve/plugins/imap4flags/tag-flags.c:
767
 
+       Replaced remainng occurences of t_push() .. t_pop() with T_BEGIN {
768
 
+       .. } T_END equivalents.
769
 
+       [2bd522f7276b]
770
 
+
771
 
+2009-07-08  Stephan Bosch  <stephan@rename-it.nl>
772
 
+
773
 
+       * src/lib-sieve/plugins/enotify/Makefile.am, src/lib-
774
 
+       sieve/plugins/enotify/cmd-notify.c, src/lib-sieve/plugins/enotify
775
 
+       /ext-enotify-common.h, src/lib-sieve/plugins/enotify/ext-notify.c,
776
 
+       src/lib-sieve/sieve-ast.c, src/lib-sieve/sieve-ast.h, src/lib-sieve
777
 
+       /sieve-extensions.c:
778
 
+       Added partial support for the depricated notify extension.
779
 
+       [d44acd7f4d09]
780
 
+
781
 
+       * src/lib-sieve/plugins/imap4flags/ext-imapflags.c, src/lib-sieve
782
 
+       /sieve-extensions.c:
783
 
+       Apparently, deprecated is spelled with an 'e'.
784
 
+       [c9379480f820]
785
 
+
786
 
+2009-07-06  Stephan Bosch  <stephan@rename-it.nl>
787
 
+
788
 
+       * src/lib-sieve/sieve-ast.c:
789
 
+       Fixed AIX compile problem provisionally.
790
 
+       [bd106aa05040]
791
 
+
792
 
+2009-07-05  Stephan Bosch  <stephan@rename-it.nl>
793
 
+
794
 
+       * .hgtags:
795
 
+       Added tag 0.1.7 for changeset 5f22f0468112
796
 
+       [e86a81f4bf28]
797
 
+
798
 
+       * README, configure.in:
799
 
+       Released v0.1.7 for Dovecot v1.2.0.
800
 
+       [5f22f0468112] [0.1.7]
801
 
+
802
 
+       * NEWS:
803
 
+       Updated NEWS file for next release.
804
 
+       [6b600005be7e]
805
 
+
806
 
+       * TODO:
807
 
+       Updated TODO.
808
 
+       [e45e47df32bf]
809
 
+
810
 
+2009-07-04  Stephan Bosch  <stephan@rename-it.nl>
811
 
+
812
 
+       * .hgignore:
813
 
+       Added item to .hgignore.
814
 
+       [964951d1c9fd]
815
 
+
816
 
+       * doc/man/sieve-test.1, doc/man/sievec.1, doc/man/sieved.1, src/sieve-
817
 
+       tools/sieve-filter.c, src/sieve-tools/sieve-test.c, src/sieve-
818
 
+       tools/sievec.c, src/sieve-tools/sieved.c:
819
 
+       Improved consistency of sieve tool documentation.
820
 
+       [1b4b951a6c0a]
821
 
+
822
 
+       * src/lib-sieve/sieve-extensions.c:
823
 
+       Enhanced extensions configuration, allowing to specify the enabled
824
 
+       extensions relatively to the default.
825
 
+       [91cc9f2a2404]
826
 
+
827
 
+       * src/plugins/lda-sieve/lda-sieve-plugin.c:
828
 
+       Sieve plugin: forgot to initialize script execution status.
829
 
+       [c4af2d059871]
830
 
+
831
 
+       * src/plugins/lda-sieve/lda-sieve-plugin.c:
832
 
+       Sieve plugin: fixed logging for execution of default main script
833
 
+       (went to STDERR).
834
 
+       [70098e07fa3b]
835
 
+
836
 
+2009-06-29  Stephan Bosch  <stephan@rename-it.nl>
837
 
+
838
 
+       * NEWS:
839
 
+       Updated NEWS file for next release.
840
 
+       [2a0e9ce87006]
841
 
+
842
 
+2009-06-28  Stephan Bosch  <stephan@rename-it.nl>
843
 
+
844
 
+       * src/lib-sieve/sieve-error.c, src/lib-sieve/sieve-error.h:
845
 
+       Added support for CRLF line breaks in strbuf error handler
846
 
+       (ManageSieve fix).
847
 
+       [763f2cff0cae]
848
 
+
849
 
+2009-06-19  Stephan Bosch  <stephan@rename-it.nl>
850
 
+
851
 
+       * .hgtags:
852
 
+       Added tag 0.1.6 for changeset 6856b1027de8
853
 
+       [20d4b1c19c92]
854
 
+
855
 
+       * .hgtags:
856
 
+       Added tag 0.1.5 for changeset 61b52e4618e3
857
 
+       [6856b1027de8] [0.1.6]
858
 
+
859
 
+2009-06-18  Stephan Bosch  <stephan@rename-it.nl>
860
 
+
861
 
+       * configure.in:
862
 
+       Released v0.1.6 for Dovecot v1.2.rc5.
863
 
+       [47f83cfcc68e]
864
 
+
865
 
+       * NEWS:
866
 
+       Updated NEWS file for new release.
867
 
+       [e9db961974b1]
868
 
+
869
 
+2009-06-01  Stephan Bosch  <stephan@rename-it.nl>
870
 
+
871
 
+       * src/lib-sieve/plugins/body/ext-body-common.c:
872
 
+       Body: fixed potential problems wil NUL characters in body parts.
873
 
+       [908f479dd046]
874
 
+
875
 
+       * src/lib-sieve/plugins/body/ext-body-common.c:
876
 
+       Body: fixed assert failure caused by ugly code and a change in
877
 
+       dovecot.
878
 
+       [c9780425e011]
879
 
+
880
 
+2009-05-29  Stephan Bosch  <stephan@rename-it.nl>
881
 
+
882
 
+       * src/lib-sieve/plugins/body/ext-body-common.c:
883
 
+       Body: fixed part of the assert fail problems (Dovecot change).
884
 
+       [a14922487fd3]
885
 
+
886
 
+       * src/lib-sieve-tool/mail-raw.c:
887
 
+       Adjusted to changes in Dovecot regarding opening a raw stream.
888
 
+       [bcd66e758199]
889
 
+
890
 
+       * src/sieve-tools/Makefile.am:
891
 
+       Removed duplicate library dependencies.
892
 
+       [bdb7ac7fcbec]
893
 
+
894
 
+2009-05-18  Stephan Bosch  <stephan@rename-it.nl>
895
 
+
896
 
+       * src/lib-sieve/plugins/include/ext-include-common.c:
897
 
+       Fixed compiler warning.
898
 
+       [4c5c04dd182a]
899
 
+
900
 
+2009-05-17  Stephan Bosch  <stephan@rename-it.nl>
901
 
+
902
 
+       * src/lib-sieve/plugins/include/ext-include-common.c:
903
 
+       Made default of sieve_dir setting match the ManageSieve
904
 
+       implementation.
905
 
+       [334612126bb7]
906
 
+
907
 
+       * src/lib-sieve/plugins/include/ext-include-common.c:
908
 
+       Fixed indent problems.
909
 
+       [f949723e32ef]
910
 
+
911
 
+2009-04-18  Stephan Bosch  <stephan@rename-it.nl>
912
 
+
913
 
+       * NEWS, configure.in:
914
 
+       Released v0.1.5 for Dovecot v1.2.rc3.
915
 
+       [61b52e4618e3] [0.1.5]
916
 
+
917
 
+       * src/lib-sieve/sieve-binary.c:
918
 
+       Increased binary version number.
919
 
+       [6f3609b58136]
920
 
+
921
 
+       * src/lib-sieve/cmd-require.c, src/lib-sieve/sieve-validator.c, src
922
 
+       /lib-sieve/sieve-validator.h, tests/compile/errors.svtest,
923
 
+       tests/compile/errors/require.sieve:
924
 
+       Improved error message for unknown Sieve extension to account for
925
 
+       core commands included as an extension.
926
 
+       [c3736fb49332]
927
 
+
928
 
+2009-04-14  Stephan Bosch  <stephan@rename-it.nl>
929
 
+
930
 
+       * src/plugins/lda-sieve/lda-sieve-plugin.c:
931
 
+       Fixed bug in the Sieve plugin's return value that caused omission of
932
 
+       delivery when no Sieve scripts are present. Bug spotted by Matthijs
933
 
+       Kooijman.
934
 
+       [4c858f06b15f]
935
 
+
936
 
+2009-04-13  Stephan Bosch  <stephan@rename-it.nl>
937
 
+
938
 
+       * src/lib-sieve/plugins/environment/ext-environment-common.c:
939
 
+       Environment: fixed compiler warning.
940
 
+       [afc482d21847]
941
 
+
942
 
+       * NEWS:
943
 
+       Updated NEWS file for upcoming v1.2 release.
944
 
+       [f4230bed0845]
945
 
+
946
 
+       * tests/extensions/environment/rfc.svtest:
947
 
+       Testsuite: forgot to add new testcase file.
948
 
+       [26e1e01da8bb]
949
 
+
950
 
+2009-04-12  Stephan Bosch  <stephan@rename-it.nl>
951
 
+
952
 
+       * Makefile.am, src/lib-sieve/plugins/environment/ext-environment-
953
 
+       common.c, src/lib-sieve/plugins/environment/tst-environment.c:
954
 
+       Environment: fixed segfault and fixed some rfc deviations.
955
 
+       [831a0a96ea5b]
956
 
+
957
 
+       * src/lib-sieve/plugins/environment/ext-environment-common.c, src/lib-
958
 
+       sieve/plugins/environment/sieve-ext-environment.h,
959
 
+       src/testsuite/testsuite.c,
960
 
+       tests/extensions/environment/basic.svtest:
961
 
+       Environment: activated host environment item.
962
 
+       [01b2712fd398]
963
 
+
964
 
+       * Makefile.am, TODO, configure.in, doc/rfc/environment.rfc5183.txt,
965
 
+       src/lib-sieve/Makefile.am, src/lib-sieve/plugins/Makefile.am, src
966
 
+       /lib-sieve/plugins/environment/Makefile.am, src/lib-
967
 
+       sieve/plugins/environment/ext-environment-common.c, src/lib-
968
 
+       sieve/plugins/environment/ext-environment-common.h, src/lib-
969
 
+       sieve/plugins/environment/ext-environment.c, src/lib-
970
 
+       sieve/plugins/environment/sieve-ext-environment.h, src/lib-
971
 
+       sieve/plugins/environment/tst-environment.c, src/lib-sieve/sieve-
972
 
+       extensions.c, tests/extensions/environment/basic.svtest:
973
 
+       Implemented core support for the environment extension.
974
 
+       [9d6ceadb490a]
975
 
+
976
 
+2009-04-11  Stephan Bosch  <stephan@rename-it.nl>
977
 
+
978
 
+       * Makefile.am, tests/extensions/include/included-global/rfc-
979
 
+       ex1-spam_tests.sieve, tests/extensions/include/included/rfc-
980
 
+       ex1-always_allow.sieve, tests/extensions/include/included/rfc-
981
 
+       ex1-mailing_lists.sieve, tests/extensions/include/included/rfc-
982
 
+       ex1-spam_tests.sieve, tests/extensions/include/included/rfc-
983
 
+       ex2-spam_filter_script.sieve,
984
 
+       tests/extensions/include/included/twice-1.sieve,
985
 
+       tests/extensions/include/included/twice-2.sieve,
986
 
+       tests/extensions/include/rfc-ex1-default.sieve,
987
 
+       tests/extensions/include/rfc-ex2-default.sieve,
988
 
+       tests/extensions/include/rfc.svtest,
989
 
+       tests/extensions/include/twice.svtest:
990
 
+       Include: added various tests to the testsuite.
991
 
+       [ac4fc49c6be1]
992
 
+
993
 
+       * src/lib-sieve/plugins/include/ext-include-variables.c:
994
 
+       Include: fixed bug in binary save of global variable scope.
995
 
+       [593fe13ac0c9]
996
 
+
997
 
+2009-04-10  Stephan Bosch  <stephan@rename-it.nl>
998
 
+
999
 
+       * Makefile.am, README, TODO, src/lib-sieve/plugins/include/cmd-
1000
 
+       include.c, src/lib-sieve/plugins/include/ext-include-common.c, src
1001
 
+       /lib-sieve/plugins/include/ext-include-common.h, src/lib-
1002
 
+       sieve/plugins/include/ext-include.c,
1003
 
+       tests/extensions/include/included/once-2.sieve,
1004
 
+       tests/extensions/include/included/once-3.sieve,
1005
 
+       tests/extensions/include/included/once-4.sieve,
1006
 
+       tests/extensions/include/once.svtest:
1007
 
+       Include: implemented :once modifier for the include command.
1008
 
+       [d6e436b78853]
1009
 
+
1010
 
+       * src/testsuite/cmd-test.c:
1011
 
+       Testsuite: fixed minor result passing problem in test code
1012
 
+       generation.
1013
 
+       [4c416bcfd49c]
1014
 
+
1015
 
+       * src/lib-sieve/plugins/include/ext-include-common.c:
1016
 
+       Include: improved runtime script handling.
1017
 
+       [2fd8feba11dd]
1018
 
+
1019
 
+       * src/lib-sieve/plugins/include/ext-include-common.c:
1020
 
+       Include: added runtime check for circular include.
1021
 
+       [b21eb653f1dd]
1022
 
+
1023
 
+       * src/lib-sieve/plugins/include/ext-include-common.c:
1024
 
+       Fixed a few small indent problems.
1025
 
+       [e948085b5b67]
1026
 
+
1027
 
+       * src/lib-sieve/plugins/include/cmd-include.c, src/lib-
1028
 
+       sieve/plugins/include/ext-include-common.c, src/lib-
1029
 
+       sieve/plugins/include/ext-include-common.h, src/lib-sieve/sieve-
1030
 
+       binary-dumper.c, tests/extensions/include/included/once-1.sieve,
1031
 
+       tests/extensions/include/included/once-2.sieve,
1032
 
+       tests/extensions/include/once.svtest:
1033
 
+       Include: added skeleton :once modifier.
1034
 
+       [08f3b665caee]
1035
 
+
1036
 
+       * src/lib-sieve/plugins/include/ext-include-common.c:
1037
 
+       Include: fixed bug in sub-sub include.
1038
 
+       [f333ecabb7d4]
1039
 
+
1040
 
+       * src/plugins/lda-sieve/lda-sieve-plugin.c:
1041
 
+       Fixed warnings in revised plugin code.
1042
 
+       [a92742e9a7c1]
1043
 
+
1044
 
+       * doc/man/sieve-test.1:
1045
 
+       Minor update to the sieve-test manpage
1046
 
+       [e400b5a9e182]
1047
 
+
1048
 
+       * README, src/lib-sieve/plugins/include/ext-include.c:
1049
 
+       Include: updated implementation status.
1050
 
+       [3717f4f237d9]
1051
 
+
1052
 
+       * doc/rfc/draft-daboo-sieve-include-05.txt, doc/rfc/draft-ietf-sieve-
1053
 
+       include-01.txt:
1054
 
+       Replaced include specification with latest draft.
1055
 
+       [d8f0bdecc0e8]
1056
 
+
1057
 
+       * src/lib-sieve/plugins/include/Makefile.am, src/lib-
1058
 
+       sieve/plugins/include/cmd-global.c, src/lib-sieve/plugins/include
1059
 
+       /cmd-import.c, src/lib-sieve/plugins/include/ext-include-common.c,
1060
 
+       src/lib-sieve/plugins/include/ext-include-common.h, src/lib-
1061
 
+       sieve/plugins/include/ext-include-variables.c, src/lib-
1062
 
+       sieve/plugins/include/ext-include-variables.h, src/lib-
1063
 
+       sieve/plugins/include/ext-include.c,
1064
 
+       tests/extensions/include/errors.svtest,
1065
 
+       tests/extensions/include/errors/import-runtime.sieve,
1066
 
+       tests/extensions/include/errors/variables-inactive.sieve,
1067
 
+       tests/extensions/include/errors/variables.sieve,
1068
 
+       tests/extensions/include/included/variables-included1.sieve,
1069
 
+       tests/extensions/include/included/variables-included2.sieve,
1070
 
+       tests/extensions/include/included/variables-included3.sieve,
1071
 
+       tests/extensions/include/variables.svtest:
1072
 
+       Include: replaced import/export commands with global command as
1073
 
+       specified in latest draft. Import/export are now DEPRICATED.
1074
 
+       [6fff255fe757]
1075
 
+
1076
 
+       * src/lib-sieve/plugins/subaddress/ext-subaddress.c, src/lib-sieve
1077
 
+       /sieve-address-parts.c, tests/address.svtest,
1078
 
+       tests/extensions/subaddress/basic.svtest:
1079
 
+       Definitively fixed handling group specifications in mailbox lists of
1080
 
+       address headers.
1081
 
+       [914c3c1f5f8c]
1082
 
+
1083
 
+       * doc/man/sieve-test.1:
1084
 
+       Fixed minor typo in sieve-test man page.
1085
 
+       [b3ad017662d1]
1086
 
+
1087
 
+       * TODO:
1088
 
+       Updated TODO.
1089
 
+       [e89b270850c6]
1090
 
+
1091
 
+       * src/lib-sieve/sieve-error-private.h, src/lib-sieve/sieve-error.c,
1092
 
+       src/lib-sieve/sieve-result.c, src/lib-sieve/sieve-result.h, src/lib-
1093
 
+       sieve/sieve-script.c, src/lib-sieve/sieve.c, src/lib-sieve/sieve.h,
1094
 
+       src/plugins/lda-sieve/lda-sieve-plugin.c, src/sieve-tools/sieve-
1095
 
+       test.c:
1096
 
+       Major rework of the multiscript support for better error handling.
1097
 
+       [6dcfb15cf051]
1098
 
+
1099
 
+2009-04-09  Stephan Bosch  <stephan@rename-it.nl>
1100
 
+
1101
 
+       * src/plugins/lda-sieve/lda-sieve-plugin.c:
1102
 
+       Improved plugin debug message.
1103
 
+       [24847d4c5ef8]
1104
 
+
1105
 
+2009-04-08  Stephan Bosch  <stephan@rename-it.nl>
1106
 
+
1107
 
+       * src/plugins/lda-sieve/lda-sieve-plugin.c:
1108
 
+       Fixed problem of unexecuted before/after global scripts when user
1109
 
+       script is missing.
1110
 
+       [4d2503564c59]
1111
 
+
1112
 
+2009-04-07  Stephan Bosch  <stephan@rename-it.nl>
1113
 
+
1114
 
+       * src/lib-sieve-tool/sieve-tool.c:
1115
 
+       Adjusted to signal handler API changes in Dovecot.
1116
 
+       [b7e376b7fb07]
1117
 
+
1118
 
+2009-04-06  Stephan Bosch  <stephan@rename-it.nl>
1119
 
+
1120
 
+       * src/lib-sieve/plugins/subaddress/ext-subaddress.c, src/lib-sieve
1121
 
+       /sieve-address-parts.c:
1122
 
+       Fixed segfault bug caused by undisclosed-recipients:; when fed to
1123
 
+       the subaddress extension.
1124
 
+       [ec78123ec073]
1125
 
+
1126
 
+2009-03-21  Stephan Bosch  <stephan@rename-it.nl>
1127
 
+
1128
 
+       * .hgtags:
1129
 
+       Added tag 0.1.4 for changeset b7eb19f14fa7
1130
 
+       [38ef3a309167]
1131
 
+
1132
 
+       * NEWS, configure.in:
1133
 
+       Released v0.1.4 for Dovecot v1.2.beta3.
1134
 
+       [b7eb19f14fa7] [0.1.4]
1135
 
+
1136
 
+2009-03-20  Stephan Bosch  <stephan@rename-it.nl>
1137
 
+
1138
 
+       * doc/man/sieve-test.1:
1139
 
+       Documented vnd.dovecot.debug in the sieve-test man page.
1140
 
+       [3e4cc10a3d89]
1141
 
+
1142
 
+       * NEWS:
1143
 
+       Updated NEWS file.
1144
 
+       [9daef35779e6]
1145
 
+
1146
 
+       * src/lib-sieve/sieve-error.c, src/lib-sieve/sieve-error.h, src/sieve-
1147
 
+       tools/sieve-filter.c, src/sieve-tools/sieve-test.c, src/sieve-
1148
 
+       tools/sievec.c, src/sieve-tools/sieved.c:
1149
 
+       Improved error handling and added debug extension to all applicable
1150
 
+       Sieve tools.
1151
 
+       [ae2f39427f14]
1152
 
+
1153
 
+2009-03-14  Stephan Bosch  <stephan@rename-it.nl>
1154
 
+
1155
 
+       * NEWS, src/lib-sieve/sieve-error.c, src/lib-sieve/sieve-error.h:
1156
 
+       Created replaceable error handler for system errors.
1157
 
+       [539cfb9b9507]
1158
 
+
1159
 
+       * TODO, configure.in, src/sieve-tools/Makefile.am, src/sieve-
1160
 
+       tools/debug/Makefile.am, src/sieve-tools/debug/cmd-debug-print.c,
1161
 
+       src/sieve-tools/debug/ext-debug-common.h, src/sieve-tools/debug/ext-
1162
 
+       debug.c, src/sieve-tools/debug/sieve-ext-debug.h, src/sieve-tools
1163
 
+       /sieve-test.c:
1164
 
+       Added Dovecot-specific debug extension to the sieve-test tool.
1165
 
+       [a74dc7f32b71]
1166
 
+
1167
 
+       * TODO, src/sieve-tools/sieve-filter.c:
1168
 
+       Sieve-filter: implemented basic filtering.
1169
 
+       [8862c90bc395]
1170
 
+
1171
 
+2009-03-05  Stephan Bosch  <stephan@rename-it.nl>
1172
 
+
1173
 
+       * src/sieve-tools/Makefile.am, src/testsuite/Makefile.am:
1174
 
+       Removed unnecessary linker flags that break Solaris compilation.
1175
 
+       [45c04b2fe529]
1176
 
+
1177
 
+2009-02-24  Stephan Bosch  <stephan@rename-it.nl>
1178
 
+
1179
 
+       * src/lib-sieve/plugins/regex/ext-regex-common.h, src/lib-
1180
 
+       sieve/plugins/relational/ext-relational-common.h, src/lib-sieve
1181
 
+       /sieve-address-parts.c, src/lib-sieve/sieve-address-parts.h, src
1182
 
+       /lib-sieve/sieve-code.h, src/lib-sieve/sieve-match-types.c, src/lib-
1183
 
+       sieve/sieve-match-types.h:
1184
 
+       Fixed MAC OSX compile problems: forgot extern modifier at various
1185
 
+       places.
1186
 
+       [ab9a06342d33]
1187
 
+
1188
 
+2009-02-23  Stephan Bosch  <stephan@rename-it.nl>
1189
 
+
1190
 
+       * src/lib-sieve-tool/mail-raw.c:
1191
 
+       Fixed issue with opening relative paths as a mail file.
1192
 
+       [4d642db0b754]
1193
 
+
1194
 
+       * src/lib-sieve-tool/mail-raw.c:
1195
 
+       Fixed tmp file name for raw storage used for sieve tools.
1196
 
+       [54a07ebb8e1f]
1197
 
+
1198
 
+2009-02-19  Stephan Bosch  <stephan@rename-it.nl>
1199
 
+
1200
 
+       * TODO:
1201
 
+       Updated TODO.
1202
 
+       [7d45c1fdf9c1]
1203
 
+
1204
 
+       * doc/rfc/collation.rfc4790.txt, doc/rfc/i-ascii-numeric.rfc2244.txt:
1205
 
+       Removed inappropriate ACAP rfc for i;ascii-numeric comparator and
1206
 
+       substituted rfc4790 in stead.
1207
 
+       [cebc91cd58e1]
1208
 
+
1209
 
+2009-02-15  Stephan Bosch  <stephan@rename-it.nl>
1210
 
+
1211
 
+       * src/sieve-tools/sieve-filter.c:
1212
 
+       Sieve-filter: developed listing messages in a folder a little
1213
 
+       further.
1214
 
+       [e7dd36461c67]
1215
 
+
1216
 
+       * .hgignore, src/sieve-tools/Makefile.am, src/sieve-tools/sieve-
1217
 
+       filter.c:
1218
 
+       Started work on sieve-filter tool.
1219
 
+       [85230557972e]
1220
 
+
1221
 
+2009-02-14  Stephan Bosch  <stephan@rename-it.nl>
1222
 
+
1223
 
+       * TODO, src/lib-sieve/sieve-commands.h, src/lib-sieve/sieve-
1224
 
+       validator.c, src/testsuite/cmd-test-message.c, src/testsuite
1225
 
+       /testsuite-common.c, src/testsuite/testsuite-common.h, src/testsuite
1226
 
+       /testsuite-smtp.c, src/testsuite/testsuite-smtp.h,
1227
 
+       tests/extensions/enotify/mailto.svtest:
1228
 
+       Testsuite: added a few final important tests for the enotify
1229
 
+       extension.
1230
 
+       [75b6dac1df2a]
1231
 
+
1232
 
+2009-02-13  Stephan Bosch  <stephan@rename-it.nl>
1233
 
+
1234
 
+       * .hgtags:
1235
 
+       Added tag 0.1.3 for changeset 8bdff47ab3f0
1236
 
+       [977e30fa18c2]
1237
 
+
1238
 
+       * configure.in:
1239
 
+       Released v0.1.3 for Dovecot v1.2.beta1.
1240
 
+       [8bdff47ab3f0] [0.1.3]
1241
 
+
1242
 
+2009-02-12  Stephan Bosch  <stephan@rename-it.nl>
1243
 
+
1244
 
+       * TODO:
1245
 
+       Added items to the TODO list.
1246
 
+       [1c401bb66e52]
1247
 
+
1248
 
+       * doc/man/sievec.1:
1249
 
+       Minor changes to the sievec man page.
1250
 
+       [c8c404ceeb47]
1251
 
+
1252
 
+       * src/lib-sieve/sieve-binary.c, src/lib-sieve/sieve-script.c, src/lib-
1253
 
+       sieve/sieve-script.h:
1254
 
+       Saved binary now has at most the same permissions as the script file
1255
 
+       itself.
1256
 
+       [3bdd01261818]
1257
 
+
1258
 
+       * src/lib-sieve/sieve-binary.c, src/lib-sieve/sieve-extensions.c:
1259
 
+       Fixed bug the code generation of extensions.
1260
 
+       [3eb2562e40e8]
1261
 
+
1262
 
+       * doc/man/sieved.1, src/sieve-tools/sieved.c:
1263
 
+       Added -x parameter to sieved tool.
1264
 
+       [c98dafdf1f49]
1265
 
+
1266
 
+2009-02-11  Stephan Bosch  <stephan@rename-it.nl>
1267
 
+
1268
 
+       * src/lib-sieve/sieve-validator.c:
1269
 
+       Fixed small bug in the extension validation.
1270
 
+       [15dd897287d2]
1271
 
+
1272
 
+       * src/lib-sieve/sieve-extensions.c:
1273
 
+       Imapflags: marked as depricated and disabled by default.
1274
 
+       [95a9bb61d7ca]
1275
 
+
1276
 
+       * src/lib-sieve/sieve-validator.c:
1277
 
+       Properly implemented verification of loaded extensions after last
1278
 
+       require command is validated.
1279
 
+       [cbb12efa1f1b]
1280
 
+
1281
 
+       * tests/extensions/variables/match.svtest:
1282
 
+       Testsuite: added small test for ?* match values.
1283
 
+       [2d132b56398a]
1284
 
+
1285
 
+       * NEWS:
1286
 
+       Updated NEWS file for next release.
1287
 
+       [a57d7b6d95a8]
1288
 
+
1289
 
+2009-02-08  Stephan Bosch  <stephan@rename-it.nl>
1290
 
+
1291
 
+       * Makefile.am, tests/extensions/vacation/message.svtest,
1292
 
+       tests/extensions/vacation/references.svtest:
1293
 
+       Testsuite: added message tests for the vacation extension.
1294
 
+       [7a074a0ff5c0]
1295
 
+
1296
 
+       * src/lib-sieve/sieve-interpreter.c, src/lib-sieve/sieve-
1297
 
+       interpreter.h, src/testsuite/Makefile.am, src/testsuite/cmd-test-
1298
 
+       result-reset.c, src/testsuite/ext-testsuite.c, src/testsuite
1299
 
+       /testsuite-common.h, src/testsuite/testsuite-result.c, src/testsuite
1300
 
+       /testsuite-result.h, src/testsuite/tst-test-script-run.c,
1301
 
+       tests/extensions/enotify/mailto.svtest:
1302
 
+       Testsuite: added support for resetting the result.
1303
 
+       [42b3ec181e64]
1304
 
+
1305
 
+       * tests/extensions/enotify/mailto.svtest:
1306
 
+       Testsuite: added tests for enotify with multiple recipients.
1307
 
+       [c84f556f3115]
1308
 
+
1309
 
+       * Makefile.am, TODO, src/lib-sieve/plugins/include/cmd-import.c, src
1310
 
+       /lib-sieve/plugins/vacation/cmd-vacation.c, src/lib-sieve/tst-
1311
 
+       size.c, src/testsuite/Makefile.am, src/testsuite/cmd-test-message.c,
1312
 
+       src/testsuite/ext-testsuite.c, src/testsuite/testsuite-common.h,
1313
 
+       src/testsuite/testsuite-message.c, src/testsuite/testsuite-
1314
 
+       message.h, src/testsuite/testsuite-objects.c, src/testsuite
1315
 
+       /testsuite-result.c, src/testsuite/testsuite-smtp.c, src/testsuite
1316
 
+       /testsuite-smtp.h, src/testsuite/tst-test-result-execute.c,
1317
 
+       tests/extensions/enotify/mailto.svtest:
1318
 
+       Testsuite: added support for looping back outgoing SMTP messages
1319
 
+       back into the test.
1320
 
+       [3f857d8c403e]
1321
 
+
1322
 
+2009-02-07  Stephan Bosch  <stephan@rename-it.nl>
1323
 
+
1324
 
+       * TODO, src/lib-sieve/cmd-redirect.c, src/lib-sieve/plugins/enotify
1325
 
+       /ntfy-mailto.c, src/lib-sieve/plugins/vacation/cmd-vacation.c, src
1326
 
+       /lib-sieve/sieve-address.c, src/lib-sieve/sieve-address.h:
1327
 
+       Defined very basic function for address comparison.
1328
 
+       [e4283ec36db2]
1329
 
+
1330
 
+       * src/lib-sieve/sieve-actions.c:
1331
 
+       Adjusted store action to API changes in Dovecot.
1332
 
+       [d2ed402f1a5f]
1333
 
+
1334
 
+2009-02-06  Stephan Bosch  <stephan@rename-it.nl>
1335
 
+
1336
 
+       * src/lib-sieve/plugins/vacation/cmd-vacation.c, src/lib-sieve/sieve-
1337
 
+       address.c, tests/extensions/vacation/execute/action.sieve:
1338
 
+       Vacation: made addresses comparison case-insensitive.
1339
 
+       [b315fde89b8a]
1340
 
+
1341
 
+2009-02-05  Stephan Bosch  <stephan@rename-it.nl>
1342
 
+
1343
 
+       * README:
1344
 
+       Updated documentation.
1345
 
+       [cea5c68baa2e]
1346
 
+
1347
 
+       * src/lib-sieve/plugins/imap4flags/tag-flags.c,
1348
 
+       tests/extensions/imap4flags/execute/imapflags.sieve:
1349
 
+       Imap4flags: fixed dumping of \flagged flag in flags side effect.
1350
 
+       [a1ad7bbd3ef7]
1351
 
+
1352
 
+       * Makefile.am, src/lib-sieve/plugins/imap4flags/Makefile.am, src/lib-
1353
 
+       sieve/plugins/imap4flags/ext-imapflags.c, src/lib-sieve/sieve-ast.c,
1354
 
+       src/lib-sieve/sieve-ast.h, src/lib-sieve/sieve-extensions.c, src
1355
 
+       /lib-sieve/sieve-extensions.h, src/lib-sieve/sieve-validator.c,
1356
 
+       src/testsuite/testsuite.c,
1357
 
+       tests/extensions/imap4flags/errors.svtest,
1358
 
+       tests/extensions/imap4flags/errors/imapflags.sieve,
1359
 
+       tests/extensions/imap4flags/execute/imapflags.sieve:
1360
 
+       Imap4flags: added support for obsolete imapflags extension for
1361
 
+       backwards compatibility with CMUSieve.
1362
 
+       [4e58445b4f87]
1363
 
+
1364
 
+2009-02-04  Stephan Bosch  <stephan@rename-it.nl>
1365
 
+
1366
 
+       * src/lib-sieve/sieve-validator.c, src/lib-sieve/sieve-validator.h:
1367
 
+       Validator: added support for checking loaded extensions.
1368
 
+       [ab9545a27bbf]
1369
 
+
1370
 
+       * src/lib-sieve/cmd-require.c, src/lib-sieve/sieve-extensions.c, src
1371
 
+       /lib-sieve/sieve-extensions.h, src/lib-sieve/sieve-validator.c, src
1372
 
+       /lib-sieve/sieve-validator.h:
1373
 
+       Added facilities for requiring extensions and making extensions
1374
 
+       mutually exclusive.
1375
 
+       [37fc919d3450]
1376
 
+
1377
 
+       * Makefile.am, tests/extensions/imap4flags/basic.svtest,
1378
 
+       tests/extensions/imap4flags/execute.svtest,
1379
 
+       tests/extensions/imap4flags/execute/flags-side-effect.sieve,
1380
 
+       tests/extensions/imap4flags/hasflag.svtest,
1381
 
+       tests/extensions/imapflags/basic.svtest,
1382
 
+       tests/extensions/imapflags/execute.svtest,
1383
 
+       tests/extensions/imapflags/execute/flags-side-effect.sieve,
1384
 
+       tests/extensions/imapflags/hasflag.svtest:
1385
 
+       Imap4flags: gave testsuite directory proper name.
1386
 
+       [f0299c1886fe]
1387
 
+
1388
 
+       * src/lib-sieve/plugins/imap4flags/cmd-flag.c, src/lib-
1389
 
+       sieve/plugins/imap4flags/ext-imap4flags-common.c, src/lib-
1390
 
+       sieve/plugins/imap4flags/ext-imap4flags-common.h, src/lib-
1391
 
+       sieve/plugins/imap4flags/ext-imap4flags.c, src/lib-
1392
 
+       sieve/plugins/imap4flags/tag-flags.c, src/lib-
1393
 
+       sieve/plugins/imap4flags/tst-hasflag.c, src/lib-sieve/sieve-
1394
 
+       extensions.c:
1395
 
+       Imap4flags: properly named extension objects.
1396
 
+       [581df7c170d1]
1397
 
+
1398
 
+       * src/lib-sieve/plugins/imap4flags/cmd-flag.c, src/lib-
1399
 
+       sieve/plugins/imap4flags/ext-imap4flags-common.c, src/lib-
1400
 
+       sieve/plugins/imap4flags/ext-imap4flags-common.h, src/lib-
1401
 
+       sieve/plugins/imap4flags/ext-imap4flags.c, src/lib-
1402
 
+       sieve/plugins/imap4flags/tag-flags.c, src/lib-
1403
 
+       sieve/plugins/imap4flags/tst-hasflag.c:
1404
 
+       Imap4flags: properly named functions.
1405
 
+       [debaa7e5a036]
1406
 
+
1407
 
+       * configure.in, src/lib-sieve/Makefile.am, src/lib-
1408
 
+       sieve/plugins/Makefile.am, src/lib-
1409
 
+       sieve/plugins/imap4flags/Makefile.am, src/lib-
1410
 
+       sieve/plugins/imap4flags/cmd-flag.c, src/lib-
1411
 
+       sieve/plugins/imap4flags/ext-imap4flags-common.c, src/lib-
1412
 
+       sieve/plugins/imap4flags/ext-imap4flags-common.h, src/lib-
1413
 
+       sieve/plugins/imap4flags/ext-imap4flags.c, src/lib-
1414
 
+       sieve/plugins/imap4flags/tag-flags.c, src/lib-
1415
 
+       sieve/plugins/imap4flags/tst-hasflag.c, src/lib-
1416
 
+       sieve/plugins/imapflags/Makefile.am, src/lib-sieve/plugins/imapflags
1417
 
+       /cmd-flag.c, src/lib-sieve/plugins/imapflags/ext-imapflags-common.c,
1418
 
+       src/lib-sieve/plugins/imapflags/ext-imapflags-common.h, src/lib-
1419
 
+       sieve/plugins/imapflags/ext-imapflags.c, src/lib-
1420
 
+       sieve/plugins/imapflags/tag-flags.c, src/lib-sieve/plugins/imapflags
1421
 
+       /tst-hasflag.c:
1422
 
+       Imap4flags: properly named extension directory and source files.
1423
 
+       [c8d2f78230f9]
1424
 
+
1425
 
+2009-02-03  Stephan Bosch  <stephan@rename-it.nl>
1426
 
+
1427
 
+       * README:
1428
 
+       Fixed README: now mentions the naming differences of the imap4flags
1429
 
+       and enotify extensions compared to the old CMU Sieve plugin.
1430
 
+       [f33ee1af3bdb]
1431
 
+
1432
 
+2009-02-02  Stephan Bosch  <stephan@rename-it.nl>
1433
 
+
1434
 
+       * src/lib-sieve/cmd-redirect.c:
1435
 
+       Fixed compile warning caused by missing include.
1436
 
+       [c0a84cf64bbd]
1437
 
+
1438
 
+2009-02-01  Stephan Bosch  <stephan@rename-it.nl>
1439
 
+
1440
 
+       * doc/rfc/draft-ietf-sieve-notify-12.txt, doc/rfc/draft-ietf-sieve-
1441
 
+       notify-mailto-10.txt, doc/rfc/notify-mailto.rfc5436.txt,
1442
 
+       doc/rfc/notify.rfc5435.txt, src/lib-sieve/plugins/enotify/ext-
1443
 
+       enotify.c, src/lib-sieve/plugins/enotify/ntfy-mailto.c:
1444
 
+       Installed RFC documents for notify extension and corresponding
1445
 
+       mailto method.
1446
 
+       [b11bd3479721]
1447
 
+
1448
 
+       * src/lib-sieve/mcht-matches.c, tests/match-types/matches.svtest:
1449
 
+       Cleaned up :matches match-type code.
1450
 
+       [ca2edcc58fba]
1451
 
+
1452
 
+       * src/lib-sieve/mcht-matches.c, tests/match-types/matches.svtest:
1453
 
+       Fixed bug in the :matches match type.
1454
 
+       [88cc4bf1c396]
1455
 
+
1456
 
+2009-01-27  Stephan Bosch  <stephan@rename-it.nl>
1457
 
+
1458
 
+       * TODO:
1459
 
+       Added important TODO item.
1460
 
+       [42e154b8792e]
1461
 
+
1462
 
+       * src/lib-sieve/cmd-redirect.c, src/lib-sieve/rfc2822.c:
1463
 
+       Changed SMTP message generation back to CRLF, because the Sieve
1464
 
+       engine uses CRLF internally.
1465
 
+       [082216ad12d6]
1466
 
+
1467
 
+       * src/lib-sieve/sieve-binary-dumper.c, src/lib-sieve/sieve-code-
1468
 
+       dumper.c, src/lib-sieve/sieve-code.c:
1469
 
+       Fixed use of data stack by binary dumping code.
1470
 
+       [258e357cfbf7]
1471
 
+
1472
 
+       * src/lib-sieve/plugins/regex/mcht-regex.c:
1473
 
+       Regex: fixed segfault bug occuring when regex is freed.
1474
 
+       [6ed559a5f677]
1475
 
+
1476
 
+       * src/testsuite/tst-test-script-compile.c:
1477
 
+       Testsuite: fixed warning.
1478
 
+       [abc7331b2124]
1479
 
+
1480
 
+       * src/lib-sieve/sieve-ast.c, src/lib-sieve/sieve-validator.c:
1481
 
+       Increased various initial pool sizes.
1482
 
+       [cdb4b96e70a8]
1483
 
+
1484
 
+2009-01-26  Stephan Bosch  <stephan@rename-it.nl>
1485
 
+
1486
 
+       * src/lib-sieve/sieve-binary.c:
1487
 
+       Increased initial size of binary's lazy_file pool.
1488
 
+       [7caaa891d5f4]
1489
 
+
1490
 
+       * src/lib-sieve/rfc2822.c:
1491
 
+       Fixed error in the SMTP message composition that caused mixing of
1492
 
+       CRLF and LF in redirected messages.
1493
 
+       [2ae233b6f5ad]
1494
 
+
1495
 
+2009-01-22  Stephan Bosch  <stephan@rename-it.nl>
1496
 
+
1497
 
+       * NEWS:
1498
 
+       Updated NEWS file.
1499
 
+       [a8e587b0409e]
1500
 
+
1501
 
+       * NEWS:
1502
 
+       Updated NEWS file.
1503
 
+       [b93c8d7802a3]
1504
 
+
1505
 
+       * README:
1506
 
+       Updated README file.
1507
 
+       [171133900f9b]
1508
 
+
1509
 
+       * NEWS:
1510
 
+       Prepared NEWS file for next release.
1511
 
+       [42ef7e546072]
1512
 
+
1513
 
+       * INSTALL:
1514
 
+       Updated documentation.
1515
 
+       [32812e4f4722]
1516
 
+
1517
 
+       * Makefile.am, tests/extensions/regex/match-values.svtest:
1518
 
+       Testsuite: added simple tests for the match values produced by the
1519
 
+       :regex match.
1520
 
+       [7a91f98d0be1]
1521
 
+
1522
 
+       * src/lib-sieve/plugins/regex/mcht-regex.c:
1523
 
+       Regex: fixed bug in the match value indexes.
1524
 
+       [de6db6757418]
1525
 
+
1526
 
+2009-01-18  Stephan Bosch  <stephan@rename-it.nl>
1527
 
+
1528
 
+       * doc/rfc/draft-degener-sieve-multiscript-00.txt:
1529
 
+       Added multiscript draft to the doc/rfc directory.
1530
 
+       [fa223cfeaa35]
1531
 
+
1532
 
+       * src/testsuite/Makefile.am, src/testsuite/testsuite-common.c,
1533
 
+       src/testsuite/testsuite-common.h, src/testsuite/testsuite-message.c,
1534
 
+       src/testsuite/testsuite-smtp.c, src/testsuite/testsuite-smtp.h,
1535
 
+       src/testsuite/testsuite.c, src/testsuite/tst-test-script-run.c:
1536
 
+       Testsuite: added storage of outgoing SMTP messages.
1537
 
+       [3fd7e83720fb]
1538
 
+
1539
 
+       * src/testsuite/Makefile.am, src/testsuite/testsuite-common.c,
1540
 
+       src/testsuite/testsuite-common.h, src/testsuite/testsuite-message.c,
1541
 
+       src/testsuite/testsuite-message.h, src/testsuite/testsuite-
1542
 
+       objects.c, src/testsuite/testsuite.c:
1543
 
+       Testsuite: exported message handling to separate module.
1544
 
+       [b15cfe188d87]
1545
 
+
1546
 
+2009-01-16  Stephan Bosch  <stephan@rename-it.nl>
1547
 
+
1548
 
+       * TODO, src/lib-sieve/plugins/enotify/cmd-notify.c, src/lib-
1549
 
+       sieve/plugins/enotify/ext-enotify-common.c, src/lib-
1550
 
+       sieve/plugins/enotify/ext-enotify-common.h, src/lib-
1551
 
+       sieve/plugins/enotify/ntfy-mailto.c, src/lib-sieve/plugins/enotify
1552
 
+       /sieve-ext-enotify.h, src/lib-sieve/sieve-result.c, src/lib-sieve
1553
 
+       /sieve-result.h:
1554
 
+       Enotify: cleaned up method API.
1555
 
+       [466e57aedb29]
1556
 
+
1557
 
+       * tests/extensions/imapflags/basic.svtest,
1558
 
+       tests/extensions/imapflags/hasflag.svtest:
1559
 
+       Testsuite: improved testsuite with respect to testing of setflag,
1560
 
+       addflag and removeflag commands.
1561
 
+       [18b4ee74fc9c]
1562
 
+
1563
 
+       * TODO, src/lib-sieve/plugins/imapflags/Makefile.am, src/lib-
1564
 
+       sieve/plugins/imapflags/cmd-addflag.c, src/lib-
1565
 
+       sieve/plugins/imapflags/cmd-flag.c, src/lib-sieve/plugins/imapflags
1566
 
+       /cmd-removeflag.c, src/lib-sieve/plugins/imapflags/cmd-setflag.c,
1567
 
+       src/lib-sieve/plugins/imapflags/ext-imapflags-common.c, src/lib-
1568
 
+       sieve/plugins/imapflags/ext-imapflags-common.h:
1569
 
+       Imap4flags: merged setflag, addflag and removeflag implementations.
1570
 
+       [38189d0d5785]
1571
 
+
1572
 
+       * INSTALL, src/lib-sieve/plugins/subaddress/ext-subaddress.c:
1573
 
+       Added sieve_subaddress_sep setting.
1574
 
+       [fac1579a1164]
1575
 
+
1576
 
+2009-01-11  Stephan Bosch  <stephan@rename-it.nl>
1577
 
+
1578
 
+       * src/lib-sieve/sieve-address.c, tests/compile/errors.svtest,
1579
 
+       tests/compile/errors/out-address.sieve:
1580
 
+       Fixed bug in the outgoing mail address verification.
1581
 
+       [60b3f236c3bc]
1582
 
+
1583
 
+       * TODO, src/lib-sieve/plugins/enotify/ntfy-mailto.c,
1584
 
+       tests/extensions/enotify/execute.svtest,
1585
 
+       tests/extensions/enotify/execute/duplicates.sieve:
1586
 
+       Enotify/Mailto: prevented single recipient from receiving multiple
1587
 
+       notifications on the same message.
1588
 
+       [38b1269f8e10]
1589
 
+
1590
 
+       * src/testsuite/testsuite.c:
1591
 
+       Testsuite: fixed segfault bugs in the error handling.
1592
 
+       [31804bc166e3]
1593
 
+
1594
 
+2009-01-10  Stephan Bosch  <stephan@rename-it.nl>
1595
 
+
1596
 
+       * README:
1597
 
+       Small project status update to the README.
1598
 
+       [31fb740ce85c]
1599
 
+
1600
 
+       * TODO, src/lib-sieve/plugins/enotify/cmd-notify.c, src/lib-
1601
 
+       sieve/plugins/enotify/ntfy-mailto.c, src/lib-sieve/plugins/enotify
1602
 
+       /sieve-ext-enotify.h, tests/extensions/enotify/execute.svtest,
1603
 
+       tests/extensions/enotify/execute/duplicates.sieve:
1604
 
+       Enotify: added API for detecting and killing duplicate notification
1605
 
+       recipients.
1606
 
+       [975614b641aa]
1607
 
+
1608
 
+       * TODO, src/plugins/lda-sieve/lda-sieve-plugin.c:
1609
 
+       Multiscript: implemented sorting of script files in script
1610
 
+       directories for Sieve plugin.
1611
 
+       [c13464cb4fe3]
1612
 
+
1613
 
+       * INSTALL, README, TODO, src/plugins/lda-sieve/lda-sieve-plugin.c:
1614
 
+       Updated documentation.
1615
 
+       [17a66023e259]
1616
 
+
1617
 
+       * TODO:
1618
 
+       Reprioritized TODO.
1619
 
+       [bcbae5e0e63d]
1620
 
+
1621
 
+       * src/lib-sieve/plugins/enotify/ntfy-mailto.c:
1622
 
+       Got array_get_pool() integrated into Dovecot.
1623
 
+       [3929bef582c0]
1624
 
+
1625
 
+       * README, TODO:
1626
 
+       Updated documentation.
1627
 
+       [aec958653b9f]
1628
 
+
1629
 
+       * src/plugins/lda-sieve/lda-sieve-plugin.c:
1630
 
+       Fixed segfault in lda sieve plugin.
1631
 
+       [902ee7cc9588]
1632
 
+
1633
 
+       * src/lib-sieve/plugins/enotify/ntfy-mailto.c:
1634
 
+       Enotify/Mailto: fixed bug in the generation of the SMTP envelope
1635
 
+       sender.
1636
 
+       [e124dfa5388c]
1637
 
+
1638
 
+       * src/lib-sieve/plugins/enotify/ntfy-mailto.c:
1639
 
+       Enotify: fixed various indent mishaps in ntfy-mailto.c.
1640
 
+       [f958c97ec9dc]
1641
 
+
1642
 
+       * src/lib-sieve/sieve.c, src/lib-sieve/sieve.h, src/plugins/lda-sieve
1643
 
+       /lda-sieve-plugin.c, src/sieve-tools/sieve-test.c:
1644
 
+       Multiscript: added untested multiscript support to the lda sieve
1645
 
+       plugin.
1646
 
+       [2777abb69dd0]
1647
 
+
1648
 
+2009-01-09  Stephan Bosch  <stephan@rename-it.nl>
1649
 
+
1650
 
+       * src/lib-sieve/sieve-binary.c, src/lib-sieve/sieve-binary.h:
1651
 
+       Added a few accessors to the binary object for convenience.
1652
 
+       [374039e9194e]
1653
 
+
1654
 
+       * src/testsuite/testsuite.c:
1655
 
+       Testsuite: fixed warning.
1656
 
+       [15bc0d5d27a5]
1657
 
+
1658
 
+       * src/testsuite/testsuite.c:
1659
 
+       Testsuite: fixed result handling.
1660
 
+       [8d63ff17d7e8]
1661
 
+
1662
 
+       * TODO:
1663
 
+       Removed remaining references to sieve-exec.
1664
 
+       [1eca558676df]
1665
 
+
1666
 
+2009-01-07  Stephan Bosch  <stephan@rename-it.nl>
1667
 
+
1668
 
+       * doc/man/sievec.1, src/lib-sieve-tool/sieve-tool.c, src/lib-sieve-
1669
 
+       tool/sieve-tool.h, src/lib-sieve/sieve-script-private.h, src/lib-
1670
 
+       sieve/sieve-script.c, src/lib-sieve/sieve-script.h, src/lib-
1671
 
+       sieve/sieve.c, src/lib-sieve/sieve.h, src/plugins/lda-sieve/lda-
1672
 
+       sieve-plugin.c, src/sieve-tools/sieve-test.c, src/sieve-
1673
 
+       tools/sievec.c, src/testsuite/testsuite-script.c,
1674
 
+       src/testsuite/testsuite.c:
1675
 
+       Extended sievec command to allow compiling an entire directory.
1676
 
+       [a56dfe862df4]
1677
 
+
1678
 
+2009-01-06  Stephan Bosch  <stephan@rename-it.nl>
1679
 
+
1680
 
+       * doc/man/sieved.1:
1681
 
+       Minor revisions to the sieved man page.
1682
 
+       [df54062cbf77]
1683
 
+
1684
 
+       * doc/man/sievec.1, src/sieve-tools/sievec.c:
1685
 
+       Made outfile argument of the sievec command optional.
1686
 
+       [b7ae0b1d7399]
1687
 
+
1688
 
+       * README:
1689
 
+       Updated README.
1690
 
+       [7cb784bf0c4c]
1691
 
+
1692
 
+       * doc/man/sieve-test.1, doc/man/sievec.1, doc/man/sieved.1, src/lib-
1693
 
+       sieve/cmd-discard.c, src/lib-sieve/sieve-result.c, src/lib-sieve
1694
 
+       /sieve-result.h, src/lib-sieve/sieve.c, src/sieve-tools/Makefile.am,
1695
 
+       src/sieve-tools/sieve-exec.c, src/sieve-tools/sieve-test.c:
1696
 
+       Merged sieve-exec tool into sieve-test.
1697
 
+       [030d37107e10]
1698
 
+
1699
 
+       * src/lib-sieve/plugins/enotify/ntfy-mailto.c, src/lib-
1700
 
+       sieve/plugins/imapflags/tag-flags.c, src/lib-sieve/plugins/vacation
1701
 
+       /cmd-vacation.c:
1702
 
+       Fixed various result error messages.
1703
 
+       [02697b1b4311]
1704
 
+
1705
 
+       * src/lib-sieve/sieve-binary.c:
1706
 
+       Fixed a theoretical security hole occuring when directory is opened
1707
 
+       as a Sieve binary.
1708
 
+       [d2a7caa5566f]
1709
 
+
1710
 
+2009-01-04  Stephan Bosch  <stephan@rename-it.nl>
1711
 
+
1712
 
+       * TODO, src/sieve-tools/sieve-test.c:
1713
 
+       Updated TODO.
1714
 
+       [2c64b5e5db89]
1715
 
+
1716
 
+       * src/lib-sieve/sieve-result.c, src/sieve-tools/sieve-test.c:
1717
 
+       Multiscript: fixed small bug in result printing.
1718
 
+       [0a5938f5e88c]
1719
 
+
1720
 
+       * src/lib-sieve/cmd-redirect.c, src/lib-sieve/ext-reject.c, src/lib-
1721
 
+       sieve/plugins/enotify/cmd-notify.c, src/lib-sieve/plugins/vacation
1722
 
+       /cmd-vacation.c, src/lib-sieve/sieve-actions.c, src/lib-sieve/sieve-
1723
 
+       actions.h, src/lib-sieve/sieve-result.c, src/lib-sieve/sieve-
1724
 
+       result.h, src/lib-sieve/sieve.c, src/lib-sieve/sieve.h, src/sieve-
1725
 
+       tools/sieve-test.c:
1726
 
+       Multiscript: improved handling of the keep action.
1727
 
+       [5d251b577e56]
1728
 
+
1729
 
+       * TODO:
1730
 
+       Updated TODO.
1731
 
+       [511e2770304c]
1732
 
+
1733
 
+       * src/lib-sieve/ext-reject.c, src/lib-sieve/plugins/vacation/cmd-
1734
 
+       vacation.c, src/lib-sieve/sieve-result.c, src/lib-sieve/sieve.c, src
1735
 
+       /lib-sieve/sieve.h, src/sieve-tools/sieve-test.c:
1736
 
+       Multiscript: implemented execution of multiple scripts for the
1737
 
+       sieve-test command.
1738
 
+       [d20619f44dc0]
1739
 
+
1740
 
+2009-01-03  Stephan Bosch  <stephan@rename-it.nl>
1741
 
+
1742
 
+       * src/lib-sieve/sieve.c, src/lib-sieve/sieve.h:
1743
 
+       Multiscript: implemented API.
1744
 
+       [50f5d81b9507]
1745
 
+
1746
 
+       * doc/man/sieve-test.1, src/lib-sieve/cmd-redirect.c, src/lib-
1747
 
+       sieve/plugins/imapflags/tag-flags.c, src/lib-sieve/plugins/include
1748
 
+       /ext-include-common.c, src/lib-sieve/sieve-actions.c, src/lib-sieve
1749
 
+       /sieve-actions.h, src/lib-sieve/sieve-interpreter.c, src/lib-sieve
1750
 
+       /sieve-interpreter.h, src/lib-sieve/sieve-result.c, src/lib-sieve
1751
 
+       /sieve-result.h, src/lib-sieve/sieve-types.h, src/lib-sieve/sieve.c,
1752
 
+       src/lib-sieve/sieve.h, src/plugins/lda-sieve/lda-sieve-plugin.c, src
1753
 
+       /sieve-tools/sieve-exec.c, src/sieve-tools/sieve-test.c,
1754
 
+       src/testsuite/testsuite-result.c, src/testsuite/testsuite-script.c,
1755
 
+       src/testsuite/testsuite.c:
1756
 
+       Multiscript: various changes to the interpreter to facilitate
1757
 
+       multiscript support.
1758
 
+       [1e54353fd486]
1759
 
+
1760
 
+2009-01-02  Stephan Bosch  <stephan@rename-it.nl>
1761
 
+
1762
 
+       * src/lib-sieve/sieve-result.c, src/lib-sieve/sieve-result.h:
1763
 
+       Multiscript: added keep status evaluation to result object.
1764
 
+       [70b008a20600]
1765
 
+
1766
 
+       * src/lib-sieve-tool/mail-raw.c, src/lib-sieve-tool/mail-raw.h, src
1767
 
+       /lib-sieve-tool/sieve-tool.c, src/lib-sieve-tool/sieve-tool.h, src
1768
 
+       /lib-sieve/cmd-discard.c, src/lib-sieve/cmd-if.c, src/lib-sieve/cmd-
1769
 
+       keep.c, src/lib-sieve/cmd-redirect.c, src/lib-sieve/cmd-require.c,
1770
 
+       src/lib-sieve/cmd-stop.c, src/lib-sieve/cmp-i-ascii-casemap.c, src
1771
 
+       /lib-sieve/cmp-i-octet.c, src/lib-sieve/ext-encoded-character.c, src
1772
 
+       /lib-sieve/ext-envelope.c, src/lib-sieve/ext-fileinto.c, src/lib-
1773
 
+       sieve/ext-reject.c, src/lib-sieve/mcht-contains.c, src/lib-sieve
1774
 
+       /mcht-is.c, src/lib-sieve/mcht-matches.c, src/lib-sieve/plugins/body
1775
 
+       /ext-body-common.c, src/lib-sieve/plugins/body/ext-body-common.h,
1776
 
+       src/lib-sieve/plugins/body/ext-body.c, src/lib-sieve/plugins/body
1777
 
+       /tst-body.c, src/lib-sieve/plugins/comparator-i-ascii-numeric/ext-
1778
 
+       cmp-i-ascii-numeric.c, src/lib-sieve/plugins/copy/ext-copy.c, src
1779
 
+       /lib-sieve/plugins/enotify/cmd-notify.c, src/lib-
1780
 
+       sieve/plugins/enotify/ext-enotify-common.c, src/lib-
1781
 
+       sieve/plugins/enotify/ext-enotify-common.h, src/lib-
1782
 
+       sieve/plugins/enotify/ext-enotify-limits.h, src/lib-
1783
 
+       sieve/plugins/enotify/ext-enotify.c, src/lib-sieve/plugins/enotify
1784
 
+       /ntfy-mailto.c, src/lib-sieve/plugins/enotify/sieve-ext-enotify.h,
1785
 
+       src/lib-sieve/plugins/enotify/tst-notify-method-capability.c, src
1786
 
+       /lib-sieve/plugins/enotify/tst-valid-notify-method.c, src/lib-
1787
 
+       sieve/plugins/enotify/vmodf-encodeurl.c, src/lib-
1788
 
+       sieve/plugins/imapflags/cmd-addflag.c, src/lib-
1789
 
+       sieve/plugins/imapflags/cmd-removeflag.c, src/lib-
1790
 
+       sieve/plugins/imapflags/cmd-setflag.c, src/lib-
1791
 
+       sieve/plugins/imapflags/ext-imapflags-common.c, src/lib-
1792
 
+       sieve/plugins/imapflags/ext-imapflags-common.h, src/lib-
1793
 
+       sieve/plugins/imapflags/ext-imapflags.c, src/lib-
1794
 
+       sieve/plugins/imapflags/tag-flags.c, src/lib-sieve/plugins/imapflags
1795
 
+       /tst-hasflag.c, src/lib-sieve/plugins/include/cmd-import.c, src/lib-
1796
 
+       sieve/plugins/include/cmd-include.c, src/lib-sieve/plugins/include
1797
 
+       /cmd-return.c, src/lib-sieve/plugins/include/ext-include-binary.c,
1798
 
+       src/lib-sieve/plugins/include/ext-include-binary.h, src/lib-
1799
 
+       sieve/plugins/include/ext-include-common.c, src/lib-
1800
 
+       sieve/plugins/include/ext-include-common.h, src/lib-
1801
 
+       sieve/plugins/include/ext-include-limits.h, src/lib-
1802
 
+       sieve/plugins/include/ext-include-variables.c, src/lib-
1803
 
+       sieve/plugins/include/ext-include-variables.h, src/lib-
1804
 
+       sieve/plugins/include/ext-include.c, src/lib-sieve/plugins/regex
1805
 
+       /ext-regex-common.c, src/lib-sieve/plugins/regex/ext-regex-common.h,
1806
 
+       src/lib-sieve/plugins/regex/ext-regex.c, src/lib-sieve/plugins/regex
1807
 
+       /mcht-regex.c, src/lib-sieve/plugins/relational/ext-relational-
1808
 
+       common.c, src/lib-sieve/plugins/relational/ext-relational-common.h,
1809
 
+       src/lib-sieve/plugins/relational/ext-relational.c, src/lib-
1810
 
+       sieve/plugins/relational/mcht-count.c, src/lib-
1811
 
+       sieve/plugins/relational/mcht-value.c, src/lib-
1812
 
+       sieve/plugins/subaddress/ext-subaddress.c, src/lib-
1813
 
+       sieve/plugins/vacation/cmd-vacation.c, src/lib-
1814
 
+       sieve/plugins/vacation/ext-vacation-common.h, src/lib-
1815
 
+       sieve/plugins/vacation/ext-vacation.c, src/lib-
1816
 
+       sieve/plugins/variables/cmd-set.c, src/lib-sieve/plugins/variables
1817
 
+       /ext-variables-arguments.c, src/lib-sieve/plugins/variables/ext-
1818
 
+       variables-arguments.h, src/lib-sieve/plugins/variables/ext-
1819
 
+       variables-common.c, src/lib-sieve/plugins/variables/ext-variables-
1820
 
+       common.h, src/lib-sieve/plugins/variables/ext-variables-dump.c, src
1821
 
+       /lib-sieve/plugins/variables/ext-variables-dump.h, src/lib-
1822
 
+       sieve/plugins/variables/ext-variables-limits.h, src/lib-
1823
 
+       sieve/plugins/variables/ext-variables-modifiers.c, src/lib-
1824
 
+       sieve/plugins/variables/ext-variables-modifiers.h, src/lib-
1825
 
+       sieve/plugins/variables/ext-variables-name.c, src/lib-
1826
 
+       sieve/plugins/variables/ext-variables-name.h, src/lib-
1827
 
+       sieve/plugins/variables/ext-variables-operands.c, src/lib-
1828
 
+       sieve/plugins/variables/ext-variables-operands.h, src/lib-
1829
 
+       sieve/plugins/variables/ext-variables.c, src/lib-
1830
 
+       sieve/plugins/variables/sieve-ext-variables.h, src/lib-
1831
 
+       sieve/plugins/variables/tst-string.c, src/lib-sieve/rfc2822.c, src
1832
 
+       /lib-sieve/rfc2822.h, src/lib-sieve/sieve-actions.c, src/lib-sieve
1833
 
+       /sieve-actions.h, src/lib-sieve/sieve-address-parts.c, src/lib-sieve
1834
 
+       /sieve-address-parts.h, src/lib-sieve/sieve-address.c, src/lib-sieve
1835
 
+       /sieve-address.h, src/lib-sieve/sieve-ast.c, src/lib-sieve/sieve-
1836
 
+       ast.h, src/lib-sieve/sieve-binary-dumper.c, src/lib-sieve/sieve-
1837
 
+       binary-dumper.h, src/lib-sieve/sieve-binary.c, src/lib-sieve/sieve-
1838
 
+       binary.h, src/lib-sieve/sieve-code-dumper.c, src/lib-sieve/sieve-
1839
 
+       code-dumper.h, src/lib-sieve/sieve-code.c, src/lib-sieve/sieve-
1840
 
+       code.h, src/lib-sieve/sieve-commands.c, src/lib-sieve/sieve-
1841
 
+       commands.h, src/lib-sieve/sieve-common.h, src/lib-sieve/sieve-
1842
 
+       comparators.c, src/lib-sieve/sieve-comparators.h, src/lib-sieve
1843
 
+       /sieve-config.h, src/lib-sieve/sieve-dump.h, src/lib-sieve/sieve-
1844
 
+       error-private.h, src/lib-sieve/sieve-error.c, src/lib-sieve/sieve-
1845
 
+       error.h, src/lib-sieve/sieve-extensions.c, src/lib-sieve/sieve-
1846
 
+       extensions.h, src/lib-sieve/sieve-generator.c, src/lib-sieve/sieve-
1847
 
+       generator.h, src/lib-sieve/sieve-interpreter.c, src/lib-sieve/sieve-
1848
 
+       interpreter.h, src/lib-sieve/sieve-lexer.c, src/lib-sieve/sieve-
1849
 
+       lexer.h, src/lib-sieve/sieve-limits.c, src/lib-sieve/sieve-limits.h,
1850
 
+       src/lib-sieve/sieve-match-types.c, src/lib-sieve/sieve-match-
1851
 
+       types.h, src/lib-sieve/sieve-match.c, src/lib-sieve/sieve-match.h,
1852
 
+       src/lib-sieve/sieve-message.c, src/lib-sieve/sieve-message.h, src
1853
 
+       /lib-sieve/sieve-objects.c, src/lib-sieve/sieve-objects.h, src/lib-
1854
 
+       sieve/sieve-parser.c, src/lib-sieve/sieve-parser.h, src/lib-sieve
1855
 
+       /sieve-result.c, src/lib-sieve/sieve-result.h, src/lib-sieve/sieve-
1856
 
+       script-private.h, src/lib-sieve/sieve-script.c, src/lib-sieve/sieve-
1857
 
+       script.h, src/lib-sieve/sieve-types.h, src/lib-sieve/sieve-
1858
 
+       validator.c, src/lib-sieve/sieve-validator.h, src/lib-sieve/sieve.c,
1859
 
+       src/lib-sieve/sieve.h, src/lib-sieve/tst-address.c, src/lib-sieve
1860
 
+       /tst-allof.c, src/lib-sieve/tst-anyof.c, src/lib-sieve/tst-exists.c,
1861
 
+       src/lib-sieve/tst-header.c, src/lib-sieve/tst-not.c, src/lib-sieve
1862
 
+       /tst-size.c, src/lib-sieve/tst-truefalse.c, src/plugins/lda-sieve
1863
 
+       /lda-sieve-plugin.c, src/plugins/lda-sieve/lda-sieve-plugin.h, src
1864
 
+       /sieve-tools/sieve-exec.c, src/sieve-tools/sieve-test.c, src/sieve-
1865
 
+       tools/sievec.c, src/sieve-tools/sieved.c, src/testsuite/cmd-test-
1866
 
+       fail.c, src/testsuite/cmd-test-result-print.c, src/testsuite/cmd-
1867
 
+       test-set.c, src/testsuite/cmd-test.c, src/testsuite/ext-testsuite.c,
1868
 
+       src/testsuite/testsuite-arguments.c, src/testsuite/testsuite-
1869
 
+       arguments.h, src/testsuite/testsuite-common.c, src/testsuite
1870
 
+       /testsuite-common.h, src/testsuite/testsuite-log.c, src/testsuite
1871
 
+       /testsuite-log.h, src/testsuite/testsuite-objects.c, src/testsuite
1872
 
+       /testsuite-objects.h, src/testsuite/testsuite-result.c,
1873
 
+       src/testsuite/testsuite-result.h, src/testsuite/testsuite-script.c,
1874
 
+       src/testsuite/testsuite-script.h, src/testsuite/testsuite-
1875
 
+       substitutions.c, src/testsuite/testsuite-substitutions.h,
1876
 
+       src/testsuite/testsuite.c, src/testsuite/tst-test-error.c,
1877
 
+       src/testsuite/tst-test-result-execute.c, src/testsuite/tst-test-
1878
 
+       result.c, src/testsuite/tst-test-script-compile.c, src/testsuite
1879
 
+       /tst-test-script-run.c:
1880
 
+       Updated copyright messages to 2009.
1881
 
+       [9e7bde020990]
1882
 
+
1883
 
+       * src/lib-sieve/sieve-actions.c, src/lib-sieve/sieve-result.c, src
1884
 
+       /lib-sieve/sieve-result.h, src/lib-sieve/sieve.c, src/testsuite
1885
 
+       /testsuite-result.c, tests/multiscript/conflicts.svtest,
1886
 
+       tests/multiscript/fileinto-frop.sieve, tests/multiscript/keep.sieve:
1887
 
+       Testsuite: extended multiscript testing.
1888
 
+       [fd189b1545ce]
1889
 
+
1890
 
+       * Makefile.am, src/lib-sieve/ext-reject.c, src/lib-
1891
 
+       sieve/plugins/vacation/cmd-vacation.c, src/testsuite/Makefile.am,
1892
 
+       src/testsuite/cmd-test-result-print.c, src/testsuite/ext-
1893
 
+       testsuite.c, src/testsuite/testsuite-common.h, src/testsuite
1894
 
+       /testsuite-log.c, src/testsuite/testsuite-result.c, src/testsuite
1895
 
+       /testsuite-result.h, src/testsuite/tst-test-result-execute.c,
1896
 
+       src/testsuite/tst-test-script-compile.c, src/testsuite/tst-test-
1897
 
+       script-run.c, tests/multiscript/basic.svtest,
1898
 
+       tests/multiscript/conflicts.svtest, tests/multiscript/fileinto-
1899
 
+       inbox.sieve, tests/multiscript/notify.sieve,
1900
 
+       tests/multiscript/reject-1.sieve, tests/multiscript/reject-2.sieve,
1901
 
+       tests/multiscript/vacation.sieve:
1902
 
+       Testsuite: added multiscript tests and required support.
1903
 
+       [55a8d5467bb7]
1904
 
+
1905
 
+       * src/lib-sieve/plugins/enotify/cmd-notify.c:
1906
 
+       Enotify: removed conflicting action flag.
1907
 
+       [507b4e15de60]
1908
 
+
1909
 
+       * src/testsuite/testsuite-log.c, src/testsuite/testsuite-log.h,
1910
 
+       src/testsuite/testsuite-script.c, src/testsuite/testsuite-script.h:
1911
 
+       Testsuite: forgot to add new files.
1912
 
+       [706e67f38fe1]
1913
 
+
1914
 
+       * src/testsuite/Makefile.am, src/testsuite/testsuite-common.c,
1915
 
+       src/testsuite/testsuite-result.c, src/testsuite/tst-test-error.c,
1916
 
+       tests/extensions/enotify/basic.svtest:
1917
 
+       Testsuite: split off script and error handler implementations into
1918
 
+       separate modules.
1919
 
+       [934cd4598d45]
1920
 
+
1921
 
+2009-01-01  Stephan Bosch  <stephan@rename-it.nl>
1922
 
+
1923
 
+       * src/lib-sieve/plugins/enotify/cmd-notify.c:
1924
 
+       Fixed warning caused by previous changes.
1925
 
+       [b1878ff375d3]
1926
 
+
1927
 
+       * src/lib-sieve/ext-reject.c, src/lib-sieve/plugins/vacation/cmd-
1928
 
+       vacation.c, src/lib-sieve/sieve-result.c:
1929
 
+       Multiscript: resolved inter-script action conflict situations.
1930
 
+       [cf3dacb0427f]
1931
 
+
1932
 
+       * src/lib-sieve/cmd-redirect.c, src/lib-sieve/ext-reject.c, src/lib-
1933
 
+       sieve/plugins/vacation/cmd-vacation.c, src/lib-sieve/sieve-
1934
 
+       actions.c, src/lib-sieve/sieve-actions.h, src/lib-sieve/sieve-
1935
 
+       result.c:
1936
 
+       Cleaned up action interface.
1937
 
+       [9aa51ae533c0]
1938
 
+
1939
 
+       * TODO, src/lib-sieve/cmd-keep.c, src/lib-sieve/sieve-actions.c, src
1940
 
+       /lib-sieve/sieve-result.c, src/lib-sieve/sieve-result.h,
1941
 
+       src/testsuite/tst-test-result.c, tests/execute/actions.svtest,
1942
 
+       tests/extensions/vacation/execute.svtest:
1943
 
+       Multiscript: adjusted result object for sequential execution.
1944
 
+       [091473d12b22]
1945
 
+
1946
 
+2008-12-29  Stephan Bosch  <stephan@rename-it.nl>
1947
 
+
1948
 
+       * TODO:
1949
 
+       Updated TODO.
1950
 
+       [61bdad87a347]
1951
 
+
1952
 
+2008-12-28  Stephan Bosch  <stephan@rename-it.nl>
1953
 
+
1954
 
+       * src/lib-sieve/plugins/vacation/cmd-vacation.c, src/lib-sieve/sieve-
1955
 
+       actions.c, src/lib-sieve/sieve-result.c, src/testsuite/testsuite-
1956
 
+       result.c, tests/execute/actions.svtest,
1957
 
+       tests/extensions/imapflags/execute.svtest,
1958
 
+       tests/extensions/reject/execute.svtest,
1959
 
+       tests/extensions/vacation/execute.svtest:
1960
 
+       Testsuite: added basic result execution tests for various
1961
 
+       extensions.
1962
 
+       [a3db8c51ef35]
1963
 
+
1964
 
+       * src/lib-sieve/sieve-result.h, src/testsuite/Makefile.am,
1965
 
+       src/testsuite/ext-testsuite.c, src/testsuite/testsuite-common.c,
1966
 
+       src/testsuite/testsuite-common.h, src/testsuite/testsuite-result.c,
1967
 
+       src/testsuite/testsuite-result.h, src/testsuite/tst-test-result-
1968
 
+       execute.c, tests/extensions/enotify/execute.svtest:
1969
 
+       Testsuite: added support for executing results.
1970
 
+       [7b6167bd595c]
1971
 
+
1972
 
+       * src/testsuite/tst-test-compile.c, src/testsuite/tst-test-execute.c,
1973
 
+       src/testsuite/tst-test-script-compile.c, src/testsuite/tst-test-
1974
 
+       script-run.c:
1975
 
+       Testsuite: forgot committing rename in previous commit.
1976
 
+       [f8e21027c484]
1977
 
+
1978
 
+       * src/testsuite/Makefile.am, src/testsuite/ext-testsuite.c,
1979
 
+       src/testsuite/testsuite-common.c, src/testsuite/testsuite-common.h,
1980
 
+       src/testsuite/tst-test-result.c, tests/compile/compile.svtest,
1981
 
+       tests/compile/errors.svtest, tests/compile/examples.svtest,
1982
 
+       tests/execute/actions.svtest, tests/execute/errors.svtest,
1983
 
+       tests/extensions/enotify/errors.svtest,
1984
 
+       tests/extensions/enotify/execute.svtest,
1985
 
+       tests/extensions/imapflags/execute.svtest,
1986
 
+       tests/extensions/include/errors.svtest,
1987
 
+       tests/extensions/regex/errors.svtest,
1988
 
+       tests/extensions/reject/execute.svtest,
1989
 
+       tests/extensions/relational/errors.svtest,
1990
 
+       tests/extensions/vacation/errors.svtest,
1991
 
+       tests/extensions/vacation/execute.svtest,
1992
 
+       tests/extensions/variables/errors.svtest, tests/testsuite.svtest:
1993
 
+       Testsuite: renamed script compile and run commands to be more
1994
 
+       intuitive.
1995
 
+       [f52cf8c2e033]
1996
 
+
1997
 
+       * src/lib-sieve/sieve-code.c, src/testsuite/Makefile.am, src/testsuite
1998
 
+       /ext-testsuite.c, src/testsuite/testsuite-arguments.c, src/testsuite
1999
 
+       /testsuite-arguments.h, src/testsuite/testsuite-common.h,
2000
 
+       src/testsuite/testsuite-substitutions.c, src/testsuite/testsuite-
2001
 
+       substitutions.h, tests/testsuite.svtest:
2002
 
+       Testsuite: started implementing support for testsuite-specific
2003
 
+       string substitutions.
2004
 
+       [93c9cf02290f]
2005
 
+
2006
 
+       * src/lib-sieve/plugins/variables/ext-variables-arguments.c, src/lib-
2007
 
+       sieve/sieve-ast.c, src/lib-sieve/sieve-ast.h, src/lib-sieve/sieve-
2008
 
+       commands.c, src/lib-sieve/sieve-commands.h:
2009
 
+       Exported variable string argument into the Sieve engine itself as
2010
 
+       'catenated string' (for similar use in other extensions like the
2011
 
+       testsuite).
2012
 
+       [0b0b3ab3967f]
2013
 
+
2014
 
+       * src/lib-sieve/plugins/variables/ext-variables-arguments.c, src/lib-
2015
 
+       sieve/plugins/variables/ext-variables-common.h, src/lib-
2016
 
+       sieve/plugins/variables/ext-variables-operands.c, src/lib-
2017
 
+       sieve/plugins/variables/ext-variables-operands.h, src/lib-
2018
 
+       sieve/plugins/variables/ext-variables.c, src/lib-sieve/sieve-code.c,
2019
 
+       src/lib-sieve/sieve-code.h:
2020
 
+       Exported variable string operand into the Sieve engine itself as
2021
 
+       'catenated string' (for similar use in other extensions like the
2022
 
+       testsuite).
2023
 
+       [75d44b76a63e]
2024
 
+
2025
 
+       * TODO:
2026
 
+       Updated TODO.
2027
 
+       [4da90917e551]
2028
 
+
2029
 
+       * src/lib-sieve/plugins/enotify/ntfy-mailto.c:
2030
 
+       Enotify: mailto: forgot to add 'from' header to list of reserved
2031
 
+       headers.
2032
 
+       [504ba37c919c]
2033
 
+
2034
 
+       * TODO:
2035
 
+       Updated TODO list.
2036
 
+       [da6447787785]
2037
 
+
2038
 
+       * Makefile.am, TODO, configure.in, dsieve-config.h.in, src/lib-
2039
 
+       sieve/Makefile.am, src/lib-sieve/plugins/Makefile.am, src/lib-sieve
2040
 
+       /sieve-extensions.c:
2041
 
+       Enotify: added enotify extension to default compile.
2042
 
+       [1a69b463d9ad]
2043
 
+
2044
 
+       * TODO, src/lib-sieve/plugins/enotify/ntfy-mailto.c:
2045
 
+       Enotify: mailto: enforced limits on number of recipients and
2046
 
+       headers.
2047
 
+       [78fdf4f59ff2]
2048
 
+
2049
 
+       * TODO, src/lib-sieve/plugins/enotify/ntfy-mailto.c,
2050
 
+       tests/extensions/enotify/errors.svtest,
2051
 
+       tests/extensions/enotify/errors/uri-mailto.sieve:
2052
 
+       Enotify: mailto: finished URI parsing.
2053
 
+       [30a272720d99]
2054
 
+
2055
 
+2008-12-27  Stephan Bosch  <stephan@rename-it.nl>
2056
 
+
2057
 
+       * src/lib-sieve/plugins/enotify/ntfy-mailto.c:
2058
 
+       Enotify: mailto: fixed various bugs introduced by previous
2059
 
+       enthousiastic commit.
2060
 
+       [bfc6b485e5bc]
2061
 
+
2062
 
+       * TODO, src/lib-sieve/plugins/enotify/ntfy-mailto.c:
2063
 
+       Enotify: mailto: added check for duplicates of unique headers in the
2064
 
+       mailto URI.
2065
 
+       [92b60e522c1e]
2066
 
+
2067
 
+       * src/lib-sieve/plugins/enotify/ntfy-mailto.c:
2068
 
+       Enotify: previous change did not distinguish Cc recipients.
2069
 
+       [4eded3dc6a8a]
2070
 
+
2071
 
+       * src/lib-sieve/plugins/enotify/ntfy-mailto.c:
2072
 
+       Enotify: added check for duplicate recipients within URI.
2073
 
+       [453e9f5ab425]
2074
 
+
2075
 
+       * TODO:
2076
 
+       Updated TODO.
2077
 
+       [6b666e5ef348]
2078
 
+
2079
 
+       * src/lib-sieve/plugins/enotify/ext-enotify-common.c:
2080
 
+       Enotify: added FIXME.
2081
 
+       [ee257412d8ba]
2082
 
+
2083
 
+       * src/lib-sieve/plugins/enotify/cmd-notify.c, src/lib-
2084
 
+       sieve/plugins/enotify/ext-enotify-common.c, src/lib-
2085
 
+       sieve/plugins/enotify/ext-enotify-common.h, src/lib-
2086
 
+       sieve/plugins/enotify/ntfy-mailto.c, src/lib-sieve/plugins/enotify
2087
 
+       /sieve-ext-enotify.h:
2088
 
+       Enotify: added runtime support for options and performed some minor
2089
 
+       cleanups.
2090
 
+       [08b6a2984d57]
2091
 
+
2092
 
+       * TODO, src/lib-sieve/plugins/enotify/cmd-notify.c, src/lib-
2093
 
+       sieve/plugins/enotify/ext-enotify-common.c, src/lib-
2094
 
+       sieve/plugins/enotify/ext-enotify-common.h, src/lib-
2095
 
+       sieve/plugins/enotify/ntfy-mailto.c, src/lib-sieve/plugins/enotify
2096
 
+       /sieve-ext-enotify.h, tests/extensions/enotify/errors.svtest,
2097
 
+       tests/extensions/enotify/errors/options.sieve:
2098
 
+       Enotify: added parsing support for the :options argument.
2099
 
+       [e7c9fab2e100]
2100
 
+
2101
 
+       * src/lib-sieve/sieve-extensions.c:
2102
 
+       Fixed semantic bug in extension handling.
2103
 
+       [e806506c8e7c]
2104
 
+
2105
 
+       * src/lib-sieve/sieve-extensions.c:
2106
 
+       Fixed segfault bug in extension handling.
2107
 
+       [f7666442e384]
2108
 
+
2109
 
+       * src/lib-sieve/ext-reject.c, src/lib-sieve/plugins/enotify/ntfy-
2110
 
+       mailto.c, src/lib-sieve/plugins/vacation/cmd-vacation.c, src/lib-
2111
 
+       sieve/sieve-actions.c, src/lib-sieve/sieve-actions.h, src/lib-sieve
2112
 
+       /sieve-message.c, src/lib-sieve/sieve-message.h:
2113
 
+       Moved new_message_id function to sieve-message.c where it is more
2114
 
+       appropriate.
2115
 
+       [acf8bc97e74c]
2116
 
+
2117
 
+       * README, src/lib-sieve/plugins/enotify/ext-enotify.c:
2118
 
+       Updated documentation.
2119
 
+       [b577aab39b21]
2120
 
+
2121
 
+2008-12-25  Stephan Bosch  <stephan@rename-it.nl>
2122
 
+
2123
 
+       * TODO:
2124
 
+       Updated TODO.
2125
 
+       [7de9c6687512]
2126
 
+
2127
 
+       * Makefile.am, TODO, src/lib-sieve/plugins/enotify/ext-enotify-
2128
 
+       common.c, src/lib-sieve/plugins/enotify/ext-enotify-common.h, src
2129
 
+       /lib-sieve/plugins/enotify/ntfy-mailto.c, src/lib-
2130
 
+       sieve/plugins/enotify/sieve-ext-enotify.h, src/lib-
2131
 
+       sieve/plugins/enotify/tst-notify-method-capability.c,
2132
 
+       tests/extensions/enotify/notify_method_capability.svtest,
2133
 
+       tests/extensions/enotify/valid-notify-method.svtest,
2134
 
+       tests/extensions/enotify/valid_notify_method.svtest:
2135
 
+       Enotify: implemented notify_method_capability test.
2136
 
+       [33c97930469f]
2137
 
+
2138
 
+       * TODO, src/lib-sieve/plugins/enotify/ext-enotify-common.c, src/lib-
2139
 
+       sieve/plugins/enotify/ext-enotify-common.h, src/lib-
2140
 
+       sieve/plugins/enotify/ntfy-mailto.c, src/lib-sieve/plugins/enotify
2141
 
+       /tst-valid-notify-method.c, tests/extensions/enotify/errors.svtest,
2142
 
+       tests/extensions/enotify/errors/uri-mailto.sieve,
2143
 
+       tests/extensions/enotify/errors/uri.sieve,
2144
 
+       tests/extensions/enotify/errors/url-mailto.sieve,
2145
 
+       tests/extensions/enotify/errors/url.sieve, tests/extensions/enotify
2146
 
+       /valid-notify-method.svtest:
2147
 
+       Enotify: implemented the valid_notify_method test.
2148
 
+       [c504a425e11d]
2149
 
+
2150
 
+       * src/lib-sieve/ext-encoded-character.c, src/lib-sieve/ext-envelope.c,
2151
 
+       src/lib-sieve/ext-fileinto.c, src/lib-sieve/ext-reject.c, src/lib-
2152
 
+       sieve/plugins/body/ext-body.c, src/lib-sieve/plugins/comparator-i
2153
 
+       -ascii-numeric/ext-cmp-i-ascii-numeric.c, src/lib-sieve/plugins/copy
2154
 
+       /ext-copy.c, src/lib-sieve/plugins/enotify/ext-enotify-common.c, src
2155
 
+       /lib-sieve/plugins/enotify/ext-enotify.c, src/lib-
2156
 
+       sieve/plugins/imapflags/ext-imapflags.c, src/lib-
2157
 
+       sieve/plugins/include/ext-include.c, src/lib-sieve/plugins/regex
2158
 
+       /ext-regex.c, src/lib-sieve/plugins/relational/ext-relational.c, src
2159
 
+       /lib-sieve/plugins/subaddress/ext-subaddress.c, src/lib-
2160
 
+       sieve/plugins/vacation/ext-vacation.c, src/lib-
2161
 
+       sieve/plugins/variables/ext-variables-common.c, src/lib-
2162
 
+       sieve/plugins/variables/ext-variables-dump.c, src/lib-
2163
 
+       sieve/plugins/variables/ext-variables.c, src/lib-sieve/sieve-
2164
 
+       address-parts.c, src/lib-sieve/sieve-ast.c, src/lib-sieve/sieve-
2165
 
+       binary-dumper.c, src/lib-sieve/sieve-binary.c, src/lib-sieve/sieve-
2166
 
+       code-dumper.c, src/lib-sieve/sieve-comparators.c, src/lib-sieve
2167
 
+       /sieve-extensions.c, src/lib-sieve/sieve-extensions.h, src/lib-sieve
2168
 
+       /sieve-generator.c, src/lib-sieve/sieve-interpreter.c, src/lib-sieve
2169
 
+       /sieve-match-types.c, src/lib-sieve/sieve-message.c, src/lib-sieve
2170
 
+       /sieve-result.c, src/lib-sieve/sieve-validator.c, src/testsuite/ext-
2171
 
+       testsuite.c:
2172
 
+       Simplified handling of extension ids.
2173
 
+       [91a1ac721a68]
2174
 
+
2175
 
+       * src/lib-sieve/plugins/comparator-i-ascii-numeric/ext-cmp-i-ascii-
2176
 
+       numeric.c, src/lib-sieve/plugins/copy/ext-copy.c, src/lib-
2177
 
+       sieve/plugins/enotify/vmodf-encodeurl.c, src/lib-
2178
 
+       sieve/plugins/imapflags/tag-flags.c, src/lib-sieve/plugins/regex
2179
 
+       /ext-regex-common.c, src/lib-sieve/plugins/relational/ext-
2180
 
+       relational-common.c, src/lib-sieve/plugins/subaddress/ext-
2181
 
+       subaddress.c, src/lib-sieve/plugins/variables/ext-variables-
2182
 
+       modifiers.c, src/lib-sieve/sieve-address-parts.c, src/lib-sieve
2183
 
+       /sieve-binary.c, src/lib-sieve/sieve-binary.h, src/lib-sieve/sieve-
2184
 
+       common.h, src/lib-sieve/sieve-comparators.c, src/lib-sieve/sieve-
2185
 
+       extensions.h, src/lib-sieve/sieve-match-types.c, src/lib-sieve
2186
 
+       /sieve-objects.c, src/testsuite/testsuite-objects.c, src/testsuite
2187
 
+       /testsuite-objects.h:
2188
 
+       Renamed extension object registry.
2189
 
+       [0d7c3b514b9d]
2190
 
+
2191
 
+2008-12-21  Stephan Bosch  <stephan@rename-it.nl>
2192
 
+
2193
 
+       * Merged concurrent changes.
2194
 
+       [6e22db2771a9]
2195
 
+
2196
 
+       * TODO, doc/man/sieve-test.1, doc/man/sievec.1, src/lib-sieve-tool
2197
 
+       /sieve-tool.c, src/lib-sieve/sieve-extensions.c, src/lib-sieve
2198
 
+       /sieve-extensions.h, src/lib-sieve/sieve.c, src/lib-sieve/sieve.h,
2199
 
+       src/plugins/lda-sieve/lda-sieve-plugin.c, src/sieve-tools/sieve-
2200
 
+       test.c, src/sieve-tools/sievec.c:
2201
 
+       Implemented support for configuring the available extensions.
2202
 
+       [fb0ba83175f5]
2203
 
+
2204
 
+       * src/lib-sieve/plugins/vacation/cmd-vacation.c:
2205
 
+       Vacation: changed location of X-Sieve header.
2206
 
+       [0760764e19ce]
2207
 
+
2208
 
+       * src/lib-sieve/plugins/vacation/cmd-vacation.c:
2209
 
+       Vacation: last change used wrong address.
2210
 
+       [481a04fbfa9c]
2211
 
+
2212
 
+       * src/lib-sieve/plugins/vacation/cmd-vacation.c:
2213
 
+       Vacation: properly implemented use of :from address argument.
2214
 
+       [51b40d48e6ea]
2215
 
+
2216
 
+       * src/lib-sieve/sieve-address.c:
2217
 
+       Fixed accidental paste in sieve-address.c.
2218
 
+       [baab6e581455]
2219
 
+
2220
 
+       * TODO, src/lib-sieve/plugins/enotify/ntfy-mailto.c, src/lib-sieve
2221
 
+       /sieve-address.c, src/lib-sieve/sieve-address.h,
2222
 
+       tests/extensions/enotify/errors.svtest,
2223
 
+       tests/extensions/enotify/errors/url-mailto.sieve:
2224
 
+       Enotify: added recipient verification and implemented proper To and
2225
 
+       Cc header composition.
2226
 
+       [05b5b209c013]
2227
 
+
2228
 
+       * tests/extensions/enotify/errors/from-mailto.sieve:
2229
 
+       Enotify: forgot to add new file to the test suite.
2230
 
+       [41cef5314a94]
2231
 
+
2232
 
+       * TODO, src/lib-sieve/plugins/enotify/cmd-notify.c, src/lib-
2233
 
+       sieve/plugins/enotify/ext-enotify-common.c, src/lib-
2234
 
+       sieve/plugins/enotify/ext-enotify-common.h, src/lib-
2235
 
+       sieve/plugins/enotify/ntfy-mailto.c, src/lib-sieve/plugins/enotify
2236
 
+       /sieve-ext-enotify.h, tests/extensions/enotify/errors.svtest:
2237
 
+       Enotify: implemented verification of the :from address.
2238
 
+       [52ec54e6d86a]
2239
 
+
2240
 
+       * src/lib-sieve/plugins/enotify/cmd-notify.c, src/lib-
2241
 
+       sieve/plugins/enotify/ext-enotify-common.c, src/lib-
2242
 
+       sieve/plugins/enotify/ext-enotify-common.h, src/lib-
2243
 
+       sieve/plugins/enotify/ntfy-mailto.c, src/lib-sieve/plugins/enotify
2244
 
+       /sieve-ext-enotify.h:
2245
 
+       Enotify: made log struct name shorter.
2246
 
+       [595a03fe94c5]
2247
 
+
2248
 
+       * src/lib-sieve/rfc2822.c:
2249
 
+       Fixed compiler warning about signed char.
2250
 
+       [e8f9a89974cd]
2251
 
+
2252
 
+       * src/lib-sieve/plugins/enotify/ext-enotify-common.c, src/lib-
2253
 
+       sieve/plugins/enotify/ext-enotify-common.h, src/lib-
2254
 
+       sieve/plugins/enotify/ntfy-mailto.c:
2255
 
+       Enotify: corrected mailto URI error messages.
2256
 
+       [3e4bb8701786]
2257
 
+
2258
 
+       * src/lib-sieve/plugins/enotify/ntfy-mailto.c:
2259
 
+       Enotify: cleaned up URI error handling.
2260
 
+       [543b25d99edf]
2261
 
+
2262
 
+       * src/lib-sieve/plugins/enotify/cmd-notify.c, src/lib-
2263
 
+       sieve/plugins/enotify/ext-enotify-common.c, src/lib-
2264
 
+       sieve/plugins/enotify/ext-enotify-common.h, src/lib-
2265
 
+       sieve/plugins/enotify/ntfy-mailto.c, src/lib-sieve/plugins/enotify
2266
 
+       /sieve-ext-enotify.h, src/lib-sieve/sieve-actions.c, src/lib-sieve
2267
 
+       /sieve-actions.h, src/lib-sieve/sieve-error.c, src/lib-sieve/sieve-
2268
 
+       error.h, src/lib-sieve/sieve-result.c, src/lib-sieve/sieve-result.h,
2269
 
+       src/lib-sieve/sieve-script.c, src/lib-sieve/sieve-script.h:
2270
 
+       Enotify: shielded most of the method API from compiler internals.
2271
 
+       [996e60017ae1]
2272
 
+
2273
 
+2008-12-20  Stephan Bosch  <stephan@rename-it.nl>
2274
 
+
2275
 
+       * TODO, src/lib-sieve/plugins/enotify/ntfy-mailto.c:
2276
 
+       Enotify: added owner email to auto-submitted header.
2277
 
+       [c2568b13b4c5]
2278
 
+
2279
 
+2008-12-19  Stephan Bosch  <stephan@rename-it.nl>
2280
 
+
2281
 
+       * TODO:
2282
 
+       Updated TODO.
2283
 
+       [4b85554381de]
2284
 
+
2285
 
+       * src/lib-sieve/sieve-lexer.c:
2286
 
+       Small cosmetic changes to lexer sources.
2287
 
+       [304d0952005f]
2288
 
+
2289
 
+       * src/lib-sieve/plugins/enotify/ntfy-mailto.c:
2290
 
+       Enotify: mailto: excluded body 'header' in URI from the header field
2291
 
+       body verification.
2292
 
+       [675dcf5550b8]
2293
 
+
2294
 
+       * TODO, src/lib-sieve/plugins/enotify/ntfy-mailto.c, src/lib-
2295
 
+       sieve/rfc2822.c, src/lib-sieve/rfc2822.h:
2296
 
+       Enotify: mailto: implemented verification of (unstructured) header
2297
 
+       field bodies and improved URI syntax checking.
2298
 
+       [6993557e1579]
2299
 
+
2300
 
+       * src/lib-sieve/plugins/enotify/ntfy-mailto.c, src/lib-
2301
 
+       sieve/plugins/vacation/cmd-vacation.c, src/lib-sieve/tst-exists.c:
2302
 
+       Substituted mail_get_headers for mail_get_headers_utf8 for those
2303
 
+       occasions where utf8 is of no concern.
2304
 
+       [33ff0356a8d0]
2305
 
+
2306
 
+       * src/lib-sieve/cmd-redirect.c, src/lib-sieve/plugins/copy/ext-copy.c,
2307
 
+       src/lib-sieve/sieve-actions.c, src/lib-sieve/sieve-actions.h, src
2308
 
+       /lib-sieve/sieve-result.c:
2309
 
+       Improved result execution and prevented failure on store action on
2310
 
+       dry run (with no specified namespace).
2311
 
+       [85fbe163f73e]
2312
 
+
2313
 
+       * TODO, src/lib-sieve/plugins/enotify/ntfy-mailto.c:
2314
 
+       Enotify: avoided sending notifications on auto-submitted messages.
2315
 
+       [03ba5acfb863]
2316
 
+
2317
 
+       * src/lib-sieve/plugins/include/ext-include-binary.c, src/lib-
2318
 
+       sieve/plugins/variables/ext-variables-common.c, src/lib-sieve/sieve-
2319
 
+       extensions.c, src/lib-sieve/sieve-result.c, src/lib-sieve/sieve-
2320
 
+       validator.c:
2321
 
+       Adapted to changes in the Dovecot API.
2322
 
+       [e290c9a5b8d1]
2323
 
+
2324
 
+2008-12-18  Stephan Bosch  <stephan@rename-it.nl>
2325
 
+
2326
 
+       * TODO:
2327
 
+       Merged concurrent changes.
2328
 
+       [7c970d2e18c4]
2329
 
+
2330
 
+2008-12-14  Stephan Bosch  <stephan@rename-it.nl>
2331
 
+
2332
 
+       * src/lib-sieve/plugins/enotify/ntfy-mailto.c:
2333
 
+       Enotify: mailto: added filtering of reserved headers.
2334
 
+       [2dc8040cc0ca]
2335
 
+
2336
 
+       * src/lib-sieve/plugins/enotify/ntfy-mailto.c:
2337
 
+       Enotify: changed notify message to match the latest draft
2338
 
+       specification better (not yet compliant).
2339
 
+       [78088c8352ee]
2340
 
+
2341
 
+       * src/lib-sieve/plugins/enotify/ntfy-mailto.c:
2342
 
+       Enotify: now using new message composition functions.
2343
 
+       [5105e03885bd]
2344
 
+
2345
 
+       * src/sieve-tools/sieve-exec.c:
2346
 
+       Fixed message typo in sieve-exec tool.
2347
 
+       [8aeef1355af5]
2348
 
+
2349
 
+       * src/lib-sieve/ext-reject.c, src/lib-sieve/rfc2822.c:
2350
 
+       Reject: now using new message composition functions.
2351
 
+       [2c8c7d6c51e0]
2352
 
+
2353
 
+       * configure.in:
2354
 
+       Change to configure.in caused compile error.
2355
 
+       [0285d0ef1b5a]
2356
 
+
2357
 
+       * configure.in:
2358
 
+       Fixed bug in configure script that emitted Dovecot version in config
2359
 
+       header in stead of Sieve version.
2360
 
+       [33b8e83d57d0]
2361
 
+
2362
 
+       * src/lib-sieve/cmd-redirect.c:
2363
 
+       Added X-Sieve header to redirected messages.
2364
 
+       [073514b8b521]
2365
 
+
2366
 
+       * src/lib-sieve/plugins/vacation/cmd-vacation.c:
2367
 
+       Vacation: now using new message composition functions.
2368
 
+       [46f1c431076a]
2369
 
+
2370
 
+       * src/lib-sieve/rfc2822.c, src/lib-sieve/rfc2822.h:
2371
 
+       Created basic internet mail message composition functionality.
2372
 
+       [f6ae429a7256]
2373
 
+
2374
 
+       * Makefile.am, TODO, src/lib-sieve/plugins/enotify/ntfy-mailto.c, src
2375
 
+       /lib-sieve/plugins/vacation/cmd-vacation.c, src/lib-sieve/rfc2822.c,
2376
 
+       src/lib-sieve/rfc2822.h, tests/extensions/vacation/references.sieve,
2377
 
+       tests/extensions/vacation/references.svtest:
2378
 
+       Vacation: added support for properly updating references header.
2379
 
+       [12399f096262]
2380
 
+
2381
 
+2008-12-13  Stephan Bosch  <stephan@rename-it.nl>
2382
 
+
2383
 
+       * src/lib-sieve/plugins/enotify/cmd-notify.c, src/lib-
2384
 
+       sieve/plugins/enotify/ntfy-mailto.c:
2385
 
+       Enotify: implemented basic notify mailto: execution.
2386
 
+       [71a3f5b90533]
2387
 
+
2388
 
+       * src/lib-sieve/plugins/enotify/cmd-notify.c, src/lib-
2389
 
+       sieve/plugins/enotify/ntfy-mailto.c, src/lib-sieve/plugins/enotify
2390
 
+       /sieve-ext-enotify.h:
2391
 
+       Enotify: implemented construction and printing of action object.
2392
 
+       [ae144360043a]
2393
 
+
2394
 
+       * src/lib-sieve/plugins/enotify/cmd-notify.c, src/lib-
2395
 
+       sieve/plugins/enotify/ext-enotify-common.c, src/lib-
2396
 
+       sieve/plugins/enotify/ext-enotify-common.h, src/lib-
2397
 
+       sieve/plugins/enotify/ntfy-mailto.c, src/lib-sieve/plugins/enotify
2398
 
+       /sieve-ext-enotify.h:
2399
 
+       Enotify: implemented runtime part.
2400
 
+       [84c05cf58119]
2401
 
+
2402
 
+2008-12-12  Stephan Bosch  <stephan@rename-it.nl>
2403
 
+
2404
 
+       * src/lib-sieve/plugins/enotify/ntfy-mailto.c:
2405
 
+       Enotify: restructured mailto url parsing to use arrays for the
2406
 
+       results.
2407
 
+       [e02c5e441ca2]
2408
 
+
2409
 
+       * Makefile.am, src/lib-sieve/plugins/enotify/ntfy-mailto.c,
2410
 
+       tests/extensions/enotify/errors.svtest,
2411
 
+       tests/extensions/enotify/errors/url-mailto.sieve,
2412
 
+       tests/extensions/enotify/errors/url.sieve:
2413
 
+       Enotify: added verification of header field names in mailto url.
2414
 
+       [9972da3b72b5]
2415
 
+
2416
 
+2008-12-18  Stephan Bosch  <stephan@rename-it.nl>
2417
 
+
2418
 
+       * TODO:
2419
 
+       Updated TODO: listed what remains to be done for the enotify
2420
 
+       extension and its mailto method.
2421
 
+       [b502f54d24ea]
2422
 
+
2423
 
+       * doc/rfc/draft-ietf-sieve-notify-mailto-09.txt, doc/rfc/draft-ietf-
2424
 
+       sieve-notify-mailto-10.txt:
2425
 
+       Updated enotify:mailto draft RFC.
2426
 
+       [a9992d1abeb1]
2427
 
+
2428
 
+2008-12-10  Stephan Bosch  <stephan@rename-it.nl>
2429
 
+
2430
 
+       * src/lib-sieve/ext-reject.c:
2431
 
+       Reject: improved message rejection log message.
2432
 
+       [2758742b1a0f]
2433
 
+
2434
 
+2008-12-09  Stephan Bosch  <stephan@rename-it.nl>
2435
 
+
2436
 
+       * TODO, src/lib-sieve/rfc2822.c, src/lib-sieve/rfc2822.h, src/lib-
2437
 
+       sieve/sieve-commands.c, src/lib-sieve/sieve-commands.h, src/lib-
2438
 
+       sieve/tst-address.c, src/lib-sieve/tst-exists.c, src/lib-sieve/tst-
2439
 
+       header.c, tests/compile/warnings/invalid-headers.sieve:
2440
 
+       Compiler now warns about syntactically invalid header field names.
2441
 
+       [67f94b204982]
2442
 
+
2443
 
+       * src/lib-sieve/Makefile.am, src/lib-sieve/sieve-commands.c, src/lib-
2444
 
+       sieve/sieve-commands.h, src/lib-sieve/tst-truefalse.c:
2445
 
+       Exported true and false commands to separate file.
2446
 
+       [fae455ed3f25]
2447
 
+
2448
 
+2008-11-30  Stephan Bosch  <stephan@rename-it.nl>
2449
 
+
2450
 
+       * src/lib-sieve/sieve-extensions.c:
2451
 
+       Fixed bug in improved capability string composition.
2452
 
+       [6f2f1b51ce19]
2453
 
+
2454
 
+       * src/lib-sieve/plugins/enotify/ext-enotify-limits.h, src/lib-
2455
 
+       sieve/plugins/enotify/ntfy-mailto.c:
2456
 
+       Enotify: further developed URI parsing.
2457
 
+       [e0f21b538123]
2458
 
+
2459
 
+       * src/lib-sieve/Makefile.am, src/lib-sieve/rfc2822.c, src/lib-
2460
 
+       sieve/rfc2822.h:
2461
 
+       Added support for header verification.
2462
 
+       [5661acb85286]
2463
 
+
2464
 
+       * src/lib-sieve/plugins/enotify/ntfy-mailto.c,
2465
 
+       tests/extensions/enotify/basic.svtest:
2466
 
+       Enotify: implemented coarse mailto URI parsing.
2467
 
+       [f7fba9671c6b]
2468
 
+
2469
 
+       * doc/rfc/draft-duerst-mailto-bis-05.txt:
2470
 
+       Added new draft-bis version of mailto RFC to doc/rfc.
2471
 
+       [cbecc1c67646]
2472
 
+
2473
 
+       * src/lib-sieve/sieve-extensions.c:
2474
 
+       Activated unload handler for extensions.
2475
 
+       [478f0bcdb6ff]
2476
 
+
2477
 
+       * src/lib-sieve/plugins/enotify/Makefile.am, src/lib-
2478
 
+       sieve/plugins/enotify/cmd-notify.c, src/lib-sieve/plugins/enotify
2479
 
+       /ext-enotify-common.c, src/lib-sieve/plugins/enotify/ext-enotify-
2480
 
+       common.h, src/lib-sieve/plugins/enotify/ext-enotify-limits.h, src
2481
 
+       /lib-sieve/plugins/enotify/ext-enotify.c, src/lib-
2482
 
+       sieve/plugins/enotify/ntfy-mailto.c, src/lib-sieve/plugins/enotify
2483
 
+       /sieve-ext-enotify.h, tests/extensions/enotify/execute.svtest:
2484
 
+       Enotify: implemented uri scheme verification.
2485
 
+       [0572076ad26f]
2486
 
+
2487
 
+2008-11-29  Stephan Bosch  <stephan@rename-it.nl>
2488
 
+
2489
 
+       * src/lib-sieve/ext-encoded-character.c, src/lib-sieve/ext-envelope.c,
2490
 
+       src/lib-sieve/ext-fileinto.c, src/lib-sieve/ext-reject.c, src/lib-
2491
 
+       sieve/plugins/body/ext-body.c, src/lib-sieve/plugins/comparator-i
2492
 
+       -ascii-numeric/ext-cmp-i-ascii-numeric.c, src/lib-sieve/plugins/copy
2493
 
+       /ext-copy.c, src/lib-sieve/plugins/enotify/ext-enotify-common.c, src
2494
 
+       /lib-sieve/plugins/enotify/ext-enotify.c, src/lib-
2495
 
+       sieve/plugins/enotify/ntfy-mailto.c, src/lib-sieve/plugins/enotify
2496
 
+       /sieve-ext-enotify.h, src/lib-sieve/plugins/imapflags/ext-
2497
 
+       imapflags.c, src/lib-sieve/plugins/include/ext-include.c, src/lib-
2498
 
+       sieve/plugins/regex/ext-regex.c, src/lib-sieve/plugins/relational
2499
 
+       /ext-relational.c, src/lib-sieve/plugins/subaddress/ext-
2500
 
+       subaddress.c, src/lib-sieve/plugins/vacation/ext-vacation.c, src
2501
 
+       /lib-sieve/plugins/variables/ext-variables.c, src/lib-sieve/sieve-
2502
 
+       address-parts.c, src/lib-sieve/sieve-comparators.c, src/lib-sieve
2503
 
+       /sieve-extensions.c, src/lib-sieve/sieve-extensions.h, src/lib-sieve
2504
 
+       /sieve-match-types.c, src/testsuite/ext-testsuite.c:
2505
 
+       Added unload method to extension object.
2506
 
+       [27b8f617ddd9]
2507
 
+
2508
 
+2008-11-28  Stephan Bosch  <stephan@rename-it.nl>
2509
 
+
2510
 
+       * TODO:
2511
 
+       Reprioritized TODO.
2512
 
+       [cbe0a7182be8]
2513
 
+
2514
 
+2008-11-26  Stephan Bosch  <stephan@rename-it.nl>
2515
 
+
2516
 
+       * .hgtags:
2517
 
+       Added tag 0.1.2 for changeset f01fe5f1e816
2518
 
+       [ec695f863a30]
2519
 
+
2520
 
+       * .hgtags:
2521
 
+       Added tag 0.1.1 for changeset e534276ecf10
2522
 
+       [f01fe5f1e816] [0.1.2]
2523
 
+
2524
 
+       * NEWS, configure.in:
2525
 
+       Released v0.1.2 for Dovecot v1.2.alpha4.
2526
 
+       [3f1ca3de6312]
2527
 
+
2528
 
+       * src/lib-sieve/plugins/vacation/cmd-vacation.c:
2529
 
+       Vacation: improved log message for discarded vacation response.
2530
 
+       [346b7c072b0a]
2531
 
+
2532
 
+       * src/lib-sieve/sieve-result.c:
2533
 
+       Fixed bug in the handling of context during result execution, which
2534
 
+       resulted in broken redirect action.
2535
 
+       [28e3144b79d1]
2536
 
+
2537
 
+2008-11-25  Stephan Bosch  <stephan@rename-it.nl>
2538
 
+
2539
 
+       * configure.in:
2540
 
+       Released v0.1.1 for Dovecot v1.2.alpha4.
2541
 
+       [e534276ecf10] [0.1.1]
2542
 
+
2543
 
+2008-11-24  Stephan Bosch  <stephan@rename-it.nl>
2544
 
+
2545
 
+       * NEWS:
2546
 
+       Updated NEWS file.
2547
 
+       [4dfeda80d78d]
2548
 
+
2549
 
+2008-11-22  Stephan Bosch  <stephan@rename-it.nl>
2550
 
+
2551
 
+       * src/lib-sieve/plugins/enotify/Makefile.am, src/lib-
2552
 
+       sieve/plugins/enotify/ext-enotify-common.c, src/lib-
2553
 
+       sieve/plugins/enotify/ext-enotify-common.h, src/lib-
2554
 
+       sieve/plugins/enotify/ext-enotify.c, src/lib-sieve/plugins/enotify
2555
 
+       /ntfy-mailto.c, src/lib-sieve/sieve-address.c, src/lib-sieve/sieve-
2556
 
+       address.h, src/lib-sieve/sieve-extensions.c, src/lib-sieve/sieve-
2557
 
+       extensions.h, src/lib-sieve/sieve.c, src/lib-sieve/sieve.h:
2558
 
+       Added registry for extension capabilities like the available notify
2559
 
+       methods and adjusted the enotify extension accordingly.
2560
 
+       [007bb75439a8]
2561
 
+
2562
 
+2008-11-21  Stephan Bosch  <stephan@rename-it.nl>
2563
 
+
2564
 
+       * doc/rfc/i-ascii-numeric.rfc2244.txt, src/lib-
2565
 
+       sieve/plugins/comparator-i-ascii-numeric/rfc2244.txt:
2566
 
+       Forgot to move RFC 2244 to proper place in doc/rfc.
2567
 
+       [9605841f6f27]
2568
 
+
2569
 
+       * Makefile.am, doc/rfc/uri.rfc3986.txt, src/lib-sieve/plugins/enotify
2570
 
+       /vmodf-encodeurl.c, tests/extensions/enotify/encodeurl.svtest:
2571
 
+       Enotify: implemented :encodeurl variables modifier.
2572
 
+       [68bae1330f0c]
2573
 
+
2574
 
+       * TODO:
2575
 
+       Added TODO item.
2576
 
+       [2ab9a8390108]
2577
 
+
2578
 
+       * src/lib-sieve-tool/mail-raw.c, src/lib-sieve-tool/sieve-tool.c, src
2579
 
+       /lib-sieve/sieve-actions.c, src/sieve-tools/sieve-exec.c, src/sieve-
2580
 
+       tools/sieve-test.c, src/testsuite/testsuite.c:
2581
 
+       Adapted to changes in the mailbox_open() API.
2582
 
+       [def28c3fc40c]
2583
 
+
2584
 
+2008-11-20  Stephan Bosch  <stephan@rename-it.nl>
2585
 
+
2586
 
+       * Makefile.am:
2587
 
+       Merged concurrent changes.
2588
 
+       [0cdeefe057f7]
2589
 
+
2590
 
+       * doc/rfc/mailto.rfc2368.txt, src/lib-
2591
 
+       sieve/plugins/enotify/Makefile.am, src/lib-sieve/plugins/enotify
2592
 
+       /cmd-notify.c, src/lib-sieve/plugins/enotify/ntfy-mailto.c, src/lib-
2593
 
+       sieve/plugins/enotify/sieve-ext-enotify.h, src/lib-
2594
 
+       sieve/plugins/enotify/vmodf-encodeurl.c:
2595
 
+       Enotify: copied action implementation from old plugin.
2596
 
+       [f4a1cf59f9ce]
2597
 
+
2598
 
+       * src/lib-sieve/cmd-redirect.c, src/lib-sieve/ext-reject.c, src/lib-
2599
 
+       sieve/plugins/vacation/cmd-vacation.c, src/plugins/lda-sieve/lda-
2600
 
+       sieve-plugin.c:
2601
 
+       Fixed error handling of actions that send mail.
2602
 
+       [eb88535b1b04]
2603
 
+
2604
 
+2008-11-16  Stephan Bosch  <stephan@rename-it.nl>
2605
 
+
2606
 
+       * doc/rfc/draft-ietf-sieve-notify-mailto-09.txt:
2607
 
+       Added notify mailto draft.
2608
 
+       [c32f0e1a2ab1]
2609
 
+
2610
 
+       * src/lib-sieve/plugins/enotify/Makefile.am, src/lib-
2611
 
+       sieve/plugins/enotify/ext-enotify-common.h, src/lib-
2612
 
+       sieve/plugins/enotify/ext-enotify.c, src/lib-sieve/plugins/enotify
2613
 
+       /vmodf-encodeurl.c, src/lib-sieve/plugins/variables/ext-variables-
2614
 
+       common.c, src/lib-sieve/plugins/variables/ext-variables-common.h,
2615
 
+       src/lib-sieve/plugins/variables/ext-variables-modifiers.c, src/lib-
2616
 
+       sieve/plugins/variables/ext-variables-modifiers.h, src/lib-
2617
 
+       sieve/plugins/variables/sieve-ext-variables.h,
2618
 
+       tests/extensions/enotify/execute.svtest:
2619
 
+       Enotify: finished skeleton by addin empty :encodeurl implementation.
2620
 
+       [1468452b4a29]
2621
 
+
2622
 
+       * Makefile.am, tests/extensions/enotify/execute.svtest,
2623
 
+       tests/extensions/enotify/execute/draft-rfc-ex1.sieve,
2624
 
+       tests/extensions/enotify/execute/draft-rfc-ex2.sieve,
2625
 
+       tests/extensions/enotify/execute/draft-rfc-ex3.sieve,
2626
 
+       tests/extensions/enotify/execute/draft-rfc-ex5.sieve,
2627
 
+       tests/extensions/enotify/execute/draft-rfc-ex6.sieve:
2628
 
+       Testsuite: added draft RFC examples as execution tests.
2629
 
+       [45464b463539]
2630
 
+
2631
 
+2008-11-20  Stephan Bosch  <stephan@rename-it.nl>
2632
 
+
2633
 
+       * Makefile.am, configure.in, src/lib-sieve/plugins/include/ext-
2634
 
+       include-binary.c, src/lib-sieve/plugins/include/ext-include-
2635
 
+       common.c, src/lib-sieve/plugins/include/ext-include.c, src/lib-sieve
2636
 
+       /sieve-binary.c, src/lib-sieve/sieve-binary.h:
2637
 
+       Enabled (optional) support for Valgrind in the testsuite and fixed a
2638
 
+       few intricate bugs in the process.
2639
 
+       [0d0571b7b81c]
2640
 
+
2641
 
+2008-11-19  Stephan Bosch  <stephan@rename-it.nl>
2642
 
+
2643
 
+       * src/lib-sieve-tool/sieve-tool.c:
2644
 
+       Changed acquisition of usernames in sieve command line tools.
2645
 
+       [4fcbcffe14c3]
2646
 
+
2647
 
+       * tests/header.svtest:
2648
 
+       Testsuite: added test for header folding.
2649
 
+       [bca59633ce16]
2650
 
+
2651
 
+       * src/lib-sieve-tool/mail-raw.c:
2652
 
+       Fixed bug in mail_raw implementation: mail_namespaces_deinit() must
2653
 
+       not be called explicitly for v1.2.
2654
 
+       [d9a73ee95b2c]
2655
 
+
2656
 
+2008-11-17  Stephan Bosch  <stephan@rename-it.nl>
2657
 
+
2658
 
+       * src/lib-sieve/sieve-actions.c:
2659
 
+       Previous change did not compile.
2660
 
+       [80aa797d9521]
2661
 
+
2662
 
+       * src/lib-sieve/sieve-actions.c:
2663
 
+       Matched changes in Dovecot to properly handle/ignore the new mailbox
2664
 
+       ACL support.
2665
 
+       [0e7868a06c20]
2666
 
+
2667
 
+2008-11-15  Stephan Bosch  <stephan@rename-it.nl>
2668
 
+
2669
 
+       * src/lib-sieve/plugins/include/ext-include-variables.c:
2670
 
+       Merged concurrent changes.
2671
 
+       [d999e9b1f138]
2672
 
+
2673
 
+       * src/lib-sieve/plugins/include/ext-include-variables.c:
2674
 
+       Fixed small indentation error.
2675
 
+       [dbef1b96761a]
2676
 
+
2677
 
+2008-11-14  Stephan Bosch  <stephan@rename-it.nl>
2678
 
+
2679
 
+       * src/lib-sieve/sieve-script.c:
2680
 
+       Fixed bug in handling of non-existent scripts.
2681
 
+       [bb9602e98abb]
2682
 
+
2683
 
+       * NEWS:
2684
 
+       Prepared NEWS file for next release.
2685
 
+       [ce33eb8c29d3]
2686
 
+
2687
 
+       * INSTALL, README:
2688
 
+       Slightly improved documentation.
2689
 
+       [e957f2fc38ef]
2690
 
+
2691
 
+2008-11-15  Stephan Bosch  <stephan@rename-it.nl>
2692
 
+
2693
 
+       * src/lib-sieve/plugins/include/ext-include-variables.c:
2694
 
+       Include: fixed bug in import/export commands.
2695
 
+       [49b0d4a70dab]
2696
 
+
2697
 
+2008-11-12  Stephan Bosch  <stephan@rename-it.nl>
2698
 
+
2699
 
+       * src/lib-sieve/plugins/imapflags/ext-imapflags-common.c, src/lib-
2700
 
+       sieve/plugins/imapflags/tag-flags.c, src/lib-sieve/sieve-code.c, src
2701
 
+       /lib-sieve/sieve-code.h, src/lib-sieve/sieve-validator.c:
2702
 
+       Imap4flags: fixed bug in the handling of the internal variable.
2703
 
+
2704
 
+       Previously the final value of internal variable was for every store
2705
 
+       action that didn't specify a :flags argument explicitly. This
2706
 
+       results in out-of order assignment/removal of flags, e.g. also the
2707
 
+       flags assigned keep actions that were executed before the
2708
 
+       addflag/setflag command were modified.
2709
 
+       [94ad1f1aa91b]
2710
 
+
2711
 
+       * TODO:
2712
 
+       Updated TODO.
2713
 
+       [56ddfa9b2d3b]
2714
 
+
2715
 
+       * README:
2716
 
+       Removed man page issue from README file.
2717
 
+       [b9a138e1a781]
2718
 
+
2719
 
+       * README:
2720
 
+       Updated README.
2721
 
+       [f4a59b2c82b2]
2722
 
+
2723
 
+       * Makefile.am, doc/man/sieve-test.1:
2724
 
+       Created man page for the sieve-test command.
2725
 
+       [f4c64a82078b]
2726
 
+
2727
 
+2008-11-11  Stephan Bosch  <stephan@rename-it.nl>
2728
 
+
2729
 
+       * Makefile.am, doc/man/sieved.1:
2730
 
+       Created man page for the sieved command.
2731
 
+       [837bc0ccab02]
2732
 
+
2733
 
+       * Makefile.am:
2734
 
+       Enabled installation of man pages.
2735
 
+       [6439050d232d]
2736
 
+
2737
 
+       * src/lib-sieve/Makefile.am:
2738
 
+       Forgot to add new sieve-config.h to the distribution.
2739
 
+       [9fa6336ed90c]
2740
 
+
2741
 
+       * doc/man/sievec.1:
2742
 
+       Created (currently uninstalled) man page for the sievec command.
2743
 
+       [95478625a6ce]
2744
 
+
2745
 
+       * Makefile.am:
2746
 
+       Testsuite: fail with informative error if compiled against dovecot
2747
 
+       headers only.
2748
 
+       [4510184ed680]
2749
 
+
2750
 
+       * configure.in, src/Makefile.am:
2751
 
+       Re-enabled support for compiling against Dovecot headers.
2752
 
+       [36e00217bdd2]
2753
 
+
2754
 
+2008-11-10  Stephan Bosch  <stephan@rename-it.nl>
2755
 
+
2756
 
+       * src/lib-sieve/plugins/enotify/Makefile.am, src/lib-
2757
 
+       sieve/plugins/enotify/ext-enotify-common.h, src/lib-
2758
 
+       sieve/plugins/enotify/ext-enotify.c, src/lib-sieve/plugins/enotify
2759
 
+       /tst-notify-method-capability.c:
2760
 
+       Enotify: added skeleton implementation of notify_method_capability
2761
 
+       test.
2762
 
+       [89259cdff750]
2763
 
+
2764
 
+2008-11-09  Stephan Bosch  <stephan@rename-it.nl>
2765
 
+
2766
 
+       * src/lib-sieve/plugins/enotify/Makefile.am, src/lib-
2767
 
+       sieve/plugins/enotify/ext-enotify-common.h, src/lib-
2768
 
+       sieve/plugins/enotify/ext-enotify.c, src/lib-sieve/plugins/enotify
2769
 
+       /tst-valid-notify-method.c, tests/extensions/enotify/basic.svtest:
2770
 
+       Enotify: added skeleton implementation of valid_notify_method test.
2771
 
+       [c9a597e248ab]
2772
 
+
2773
 
+2008-11-07  Stephan Bosch  <stephan@rename-it.nl>
2774
 
+
2775
 
+       * Makefile.am, src/lib-sieve/plugins/enotify/cmd-notify.c, src/lib-
2776
 
+       sieve/plugins/enotify/ext-enotify-common.h, src/lib-
2777
 
+       sieve/plugins/enotify/ext-enotify.c, src/lib-sieve/sieve-ast.c, src
2778
 
+       /lib-sieve/sieve-ast.h, tests/extensions/enotify/basic.svtest:
2779
 
+       Enotify: implemented skeleton for the notify command.
2780
 
+       [a004b31bcc08]
2781
 
+
2782
 
+2008-11-02  Stephan Bosch  <stephan@rename-it.nl>
2783
 
+
2784
 
+       * src/lib-sieve/Makefile.am, src/lib-sieve/sieve-extensions.c:
2785
 
+       ENotify: activated empty implementation.
2786
 
+       [63e099d7edf7]
2787
 
+
2788
 
+       * .hgignore, configure.in, dsieve-config.h.in, src/lib-
2789
 
+       sieve/Makefile.am, src/lib-sieve/sieve-common.h, src/lib-sieve
2790
 
+       /sieve-config.h, src/lib-sieve/sieve-types.h, src/lib-sieve/sieve.h:
2791
 
+       Started using autoconf output.
2792
 
+       [c5ff061ac5f4]
2793
 
+
2794
 
+       * src/lib-sieve/Makefile.am, src/lib-sieve/cmd-keep.c, src/lib-sieve
2795
 
+       /ext-fileinto.c, src/lib-sieve/sieve-actions.h:
2796
 
+       Added UTF-8 to modified UTF-7 folder name conversion for
2797
 
+       compatibility with IMAP.
2798
 
+       [fc0395d50d04]
2799
 
+
2800
 
+       * .hgignore, src/sieve-tools/sieve-exec, src/sieve-tools/sieve-test,
2801
 
+       src/sieve-tools/sievec, src/sieve-tools/sieved:
2802
 
+       Accidentally added binaries for sieve tools.
2803
 
+       [99b09b8a310a]
2804
 
+
2805
 
+2008-11-01  Stephan Bosch  <stephan@rename-it.nl>
2806
 
+
2807
 
+       * doc/rfc/draft-ietf-sieve-notify-12.txt, src/lib-
2808
 
+       sieve/plugins/enotify/Makefile.am, src/lib-sieve/plugins/enotify
2809
 
+       /cmd-notify.c, src/lib-sieve/plugins/enotify/ext-enotify-common.h,
2810
 
+       src/lib-sieve/plugins/enotify/ext-enotify.c:
2811
 
+       Enotify: built skeleton for the notify command.
2812
 
+       [482517b70a32]
2813
 
+
2814
 
+       * README, TODO, configure.in, src/Makefile.am, src/lib-sieve-
2815
 
+       tool/Makefile.am, src/lib-sieve-tool/mail-raw.c, src/lib-sieve-tool
2816
 
+       /mail-raw.h, src/lib-sieve-tool/sieve-tool.c, src/lib-sieve-tool
2817
 
+       /sieve-tool.h, src/lib-util/Makefile.am, src/lib-util/mail-raw.c,
2818
 
+       src/lib-util/mail-raw.h, src/sieve-bin/Makefile.am, src/sieve-bin
2819
 
+       /bin-common.c, src/sieve-bin/bin-common.h, src/sieve-bin/sieve-
2820
 
+       exec.c, src/sieve-bin/sieve-test.c, src/sieve-bin/sievec.c, src
2821
 
+       /sieve-bin/sieved.c, src/sieve-tools/Makefile.am, src/sieve-tools
2822
 
+       /sieve-exec, src/sieve-tools/sieve-exec.c, src/sieve-tools/sieve-
2823
 
+       test, src/sieve-tools/sieve-test.c, src/sieve-tools/sievec, src
2824
 
+       /sieve-tools/sievec.c, src/sieve-tools/sieved, src/sieve-
2825
 
+       tools/sieved.c, src/testsuite/Makefile.am,
2826
 
+       src/testsuite/testsuite.c:
2827
 
+       Removed code duplication between testsuite and commandline tools.
2828
 
+       Also restructured source code of the tools.
2829
 
+       [bf8ca24d25ef]
2830
 
+
2831
 
+2008-10-30  Stephan Bosch  <stephan@rename-it.nl>
2832
 
+
2833
 
+       * src/sieve-bin/Makefile.am, src/sieve-bin/namespaces.c, src/sieve-
2834
 
+       bin/namespaces.h, src/sieve-bin/sieve-exec.c, src/sieve-bin/sieve-
2835
 
+       test.c, src/testsuite/Makefile.am, src/testsuite/namespaces.c,
2836
 
+       src/testsuite/namespaces.h, src/testsuite/testsuite-common.c,
2837
 
+       src/testsuite/testsuite-objects.c, src/testsuite/testsuite.c:
2838
 
+       Removed now obsolete namespaces.c/h from testsuite and commandline
2839
 
+       tools.
2840
 
+       [937eb9e8e043]
2841
 
+
2842
 
+       * src/sieve-bin/Makefile.am, src/sieve-bin/namespaces.c,
2843
 
+       src/testsuite/Makefile.am, src/testsuite/namespaces.c:
2844
 
+       Enabled all available mail storage types (those compiled in Dovecot)
2845
 
+       for the commandline tools and the testsuite.
2846
 
+       [3d96a883bda0]
2847
 
+
2848
 
+       * configure.in, src/Makefile.am, src/lib-util/Makefile.am, src/lib-
2849
 
+       util/mail-raw.c, src/lib-util/mail-raw.h, src/sieve-bin/Makefile.am,
2850
 
+       src/sieve-bin/bin-common.c, src/sieve-bin/mail-raw.c, src/sieve-bin
2851
 
+       /mail-raw.h, src/sieve-bin/sieve-exec.c, src/sieve-bin/sieve-test.c,
2852
 
+       src/testsuite/Makefile.am, src/testsuite/mail-raw.c, src/testsuite
2853
 
+       /mail-raw.h, src/testsuite/testsuite-common.c:
2854
 
+       Merged mail-raw implementations of sieve commandline tools and the
2855
 
+       testsuite, thus removing duplicate code.
2856
 
+       [7e82c26a38bd]
2857
 
+
2858
 
+       * src/lib-sieve/sieve.c, src/lib-sieve/sieve.h, src/plugins/lda-sieve
2859
 
+       /lda-sieve-plugin.c, src/sieve-bin/bin-common.c:
2860
 
+       Made lda plugin properly refer to the main script as 'main script'
2861
 
+       and not the basename of the sieve file (which is of no interest to
2862
 
+       the user for the main script).
2863
 
+       [bc09d2616c36]
2864
 
+
2865
 
+       * src/lib-sieve/sieve-script.c, src/plugins/lda-sieve/lda-sieve-
2866
 
+       plugin.c:
2867
 
+       Improved logging of failed script load.
2868
 
+       [32c0b5cc77af]
2869
 
+
2870
 
+2008-10-29  Stephan Bosch  <stephan@rename-it.nl>
2871
 
+
2872
 
+       * src/lib-sieve/sieve-actions.c:
2873
 
+       Now using folder name as specified by user in log messages in stead
2874
 
+       of internal representation.
2875
 
+       [5d6f65468c6d]
2876
 
+
2877
 
+       * src/plugins/lda-sieve/lda-sieve-plugin.c:
2878
 
+       Added mail_debug messages to plugin to find problems in the sieve
2879
 
+       path specification more easily.
2880
 
+       [91a3f25c3df5]
2881
 
+
2882
 
+       * TODO:
2883
 
+       Added TODO item.
2884
 
+       [747107b816dc]
2885
 
+
2886
 
+       * src/sieve-bin/sievec.c:
2887
 
+       Command sievec -d always wrote to std out.
2888
 
+       [e92ec8bbd16a]
2889
 
+
2890
 
+       * src/sieve-bin/bin-common.c, src/testsuite/testsuite.c:
2891
 
+       Fixed missing mask argument in two open calls (bug found by Sergey
2892
 
+       Ivanov).
2893
 
+       [8dcba4f38a67]
2894
 
+
2895
 
+2008-10-25  Stephan Bosch  <stephan@rename-it.nl>
2896
 
+
2897
 
+       * configure.in, src/lib-sieve/plugins/Makefile.am, src/lib-
2898
 
+       sieve/plugins/enotify/Makefile.am, src/lib-sieve/plugins/enotify
2899
 
+       /ext-enotify.c:
2900
 
+       Started development of enotify extension.
2901
 
+       [85d6ef932c4f]
2902
 
+
2903
 
+2008-10-23  Stephan Bosch  <stephan@rename-it.nl>
2904
 
+
2905
 
+       * .hgtags:
2906
 
+       Added tag 0.1.0 for changeset 065c12acdcc0
2907
 
+       [b7d9c5e026b6]
2908
 
+
2909
 
+       * TODO, configure.in:
2910
 
+       Released v0.1.0 for Dovecot v1.2.alpha3.
2911
 
+       [065c12acdcc0] [0.1.0]
2912
 
+
2913
 
+       * AUTHORS, NEWS, README:
2914
 
+       Minor revisions to the package documentation.
2915
 
+       [9e487fec9dce]
2916
 
+
2917
 
+2008-10-22  Stephan Bosch  <stephan@rename-it.nl>
2918
 
+
2919
 
+       * src/lib-sieve/sieve-types.h:
2920
 
+       Fixed warning caused by mixup between mail_storage and
2921
 
+       sieve_storage.
2922
 
+       [aa3e90f621b1]
2923
 
+
2924
 
+       * src/lib-sieve/sieve-actions.c:
2925
 
+       Improved execution of store action.
2926
 
+       [2877fa93580c]
2927
 
+
2928
 
+2008-10-21  Stephan Bosch  <stephan@rename-it.nl>
2929
 
+
2930
 
+       * src/lib-sieve/sieve-actions.c, src/lib-sieve/sieve-types.h,
2931
 
+       src/plugins/lda-sieve/lda-sieve-plugin.c:
2932
 
+       Properly set storage_r in plugin function to prevent double errors.
2933
 
+       [a679d84dff88]
2934
 
+
2935
 
+2008-10-20  Stephan Bosch  <stephan@rename-it.nl>
2936
 
+
2937
 
+       * src/lib-sieve/sieve-actions.c, src/lib-sieve/sieve-result.c:
2938
 
+       Prevented transaction context from becoming NULL in execution of
2939
 
+       store action.
2940
 
+       [2402b1499813]
2941
 
+
2942
 
+       * src/lib-sieve/sieve-result.c:
2943
 
+       Fixed context handling bug in the result execution.
2944
 
+       [a88276bff812]
2945
 
+
2946
 
+2008-10-19  Stephan Bosch  <stephan@rename-it.nl>
2947
 
+
2948
 
+       * src/lib-sieve/sieve-validator.c, tests/compile/errors.svtest,
2949
 
+       tests/compile/errors/typos.sieve:
2950
 
+       Clarified errors occurring when colon is missing.
2951
 
+       [3366b70ef4e3]
2952
 
+
2953
 
+       * src/lib-sieve/sieve-validator.c, tests/compile/errors.svtest:
2954
 
+       Corrected error message.
2955
 
+       [84dfe8d5a47a]
2956
 
+
2957
 
+       * README, src/lib-sieve/sieve-validator.c,
2958
 
+       tests/compile/errors.svtest:
2959
 
+       Clarified error messages for missing semicolon.
2960
 
+       [b78529976e65]
2961
 
+
2962
 
+       * Makefile.am, src/lib-sieve/plugins/body/Makefile.am, src/lib-
2963
 
+       sieve/plugins/body/body.sieve, src/lib-sieve/plugins/comparator-i
2964
 
+       -ascii-numeric/Makefile.am, src/lib-sieve/plugins/comparator-i
2965
 
+       -ascii-numeric/cmp-i-ascii-numeric.sieve, src/lib-
2966
 
+       sieve/plugins/copy/Makefile.am, src/lib-
2967
 
+       sieve/plugins/copy/copy.sieve, src/lib-
2968
 
+       sieve/plugins/imapflags/Makefile.am, src/lib-
2969
 
+       sieve/plugins/imapflags/imapflags-2.sieve, src/lib-
2970
 
+       sieve/plugins/imapflags/imapflags-errors.sieve, src/lib-
2971
 
+       sieve/plugins/imapflags/imapflags-implicit.sieve, src/lib-
2972
 
+       sieve/plugins/imapflags/imapflags-variables.sieve, src/lib-
2973
 
+       sieve/plugins/imapflags/imapflags.sieve, src/lib-
2974
 
+       sieve/plugins/regex/Makefile.am, src/lib-
2975
 
+       sieve/plugins/relational/Makefile.am, src/lib-
2976
 
+       sieve/plugins/relational/relational.sieve, src/lib-
2977
 
+       sieve/plugins/subaddress/Makefile.am, src/lib-
2978
 
+       sieve/plugins/subaddress/subaddress.sieve, src/lib-
2979
 
+       sieve/plugins/vacation/Makefile.am, src/lib-sieve/plugins/vacation
2980
 
+       /vacation-errors.sieve, src/lib-
2981
 
+       sieve/plugins/vacation/vacation.sieve, src/lib-
2982
 
+       sieve/plugins/variables/Makefile.am, src/lib-sieve/plugins/variables
2983
 
+       /variables-errors.sieve, src/lib-sieve/plugins/variables/variables-
2984
 
+       match.sieve, src/lib-sieve/plugins/variables/variables-nspace.sieve,
2985
 
+       src/lib-sieve/plugins/variables/variables-regex.sieve, src/lib-
2986
 
+       sieve/plugins/variables/variables.sieve, src/testsuite/Makefile.am:
2987
 
+       Repaired 'make dist' tarball output.
2988
 
+       [28b57e7024b7]
2989
 
+
2990
 
+       * INSTALL, README, configure.in:
2991
 
+       Revised README.
2992
 
+       [dd3cdd379693]
2993
 
+
2994
 
+       * TODO, src/lib-sieve/sieve-result.c, src/lib-sieve/sieve-result.h,
2995
 
+       src/testsuite/Makefile.am, src/testsuite/ext-testsuite.c,
2996
 
+       src/testsuite/testsuite-common.c, src/testsuite/testsuite-common.h,
2997
 
+       src/testsuite/testsuite-result.c, src/testsuite/testsuite-result.h,
2998
 
+       src/testsuite/tst-test-error.c, src/testsuite/tst-test-result.c,
2999
 
+       tests/execute/actions.svtest, tests/execute/actions/fileinto.sieve,
3000
 
+       tests/execute/actions/redirect.sieve,
3001
 
+       tests/extensions/reject/execute.svtest,
3002
 
+       tests/extensions/vacation/execute.svtest,
3003
 
+       tests/extensions/vacation/execute/action.sieve:
3004
 
+       Testsuite: added support for basic result checking.
3005
 
+       [ff43885270f0]
3006
 
+
3007
 
+       * TODO, doc/rfc/RFC Controversy.txt, doc/rfc/RFC-questions.txt:
3008
 
+       Reported RFC questions to the ietf-mta-filters mailinglist.
3009
 
+       [c878efb32b9d]
3010
 
+
3011
 
+       * TODO, src/lib-sieve/plugins/include/cmd-include.c, src/lib-
3012
 
+       sieve/plugins/regex/mcht-regex.c, src/lib-sieve/sieve-comparators.c,
3013
 
+       tests/compile/errors.svtest, tests/compile/errors/unsupported.sieve:
3014
 
+       Added explicit messages and tests for unsupported use of variables.
3015
 
+       [6d1c5ca0d75c]
3016
 
+
3017
 
+2008-10-12  Stephan Bosch  <stephan@rename-it.nl>
3018
 
+
3019
 
+       * TODO:
3020
 
+       Updated TODO.
3021
 
+       [56dc772ca475]
3022
 
+
3023
 
+       * TODO, src/lib-sieve/plugins/variables/ext-variables-dump.c:
3024
 
+       Fixed TODO: made sure main scope used in variables dumping is
3025
 
+       unreferenced when code dumper is freed.
3026
 
+       [58f57ad4f723]
3027
 
+
3028
 
+       * TODO:
3029
 
+       Tested replacing cmusieve with sieve.
3030
 
+       [3a82ec3361db]
3031
 
+
3032
 
+       * src/lib-sieve/sieve-binary.c:
3033
 
+       Function t_str_new_const got moved to its proper place in Dovecot.
3034
 
+       [7f5fc7f2e8cc]
3035
 
+
3036
 
+2008-10-11  Stephan Bosch  <stephan@rename-it.nl>
3037
 
+
3038
 
+       * src/lib-sieve/sieve-code-dumper.c, src/lib-sieve/sieve-code-
3039
 
+       dumper.h:
3040
 
+       Added extension support to code dumper.
3041
 
+       [59f5b7074e34]
3042
 
+
3043
 
+       * src/lib-sieve/plugins/imapflags/ext-imapflags-common.c, src/lib-
3044
 
+       sieve/sieve-binary.c, src/lib-sieve/sieve-parser.c:
3045
 
+       Removed/solved minor TODOs.
3046
 
+       [f16ab5f94f51]
3047
 
+
3048
 
+       * TODO:
3049
 
+       Merged concurrent changes.
3050
 
+       [d061ae363863]
3051
 
+
3052
 
+       * TODO, src/lib-sieve/plugins/include/ext-include-binary.c, src/lib-
3053
 
+       sieve/plugins/include/ext-include-binary.h, src/lib-
3054
 
+       sieve/plugins/include/ext-include.c, src/lib-sieve/plugins/variables
3055
 
+       /ext-variables-dump.c, src/lib-sieve/plugins/variables/sieve-ext-
3056
 
+       variables.h:
3057
 
+       Variables/Include: added support for dumping variables declared in
3058
 
+       extension scopes.
3059
 
+       [d514f5e3a5f4]
3060
 
+
3061
 
+2008-10-09  Stephan Bosch  <stephan@rename-it.nl>
3062
 
+
3063
 
+       * TODO, src/lib-sieve/sieve-error.c:
3064
 
+       Fixed amd64 logging segfault; turns out using same va_args in
3065
 
+       multiple vprintf calls is not possible.
3066
 
+       [139edcdd3820]
3067
 
+
3068
 
+2008-10-05  Stephan Bosch  <stephan@rename-it.nl>
3069
 
+
3070
 
+       * src/lib-sieve/sieve-actions.c:
3071
 
+       Added support for mailbox autocreate and autosubscribe.
3072
 
+       [79da56ccfdc5]
3073
 
+
3074
 
+       * TODO, src/lib-sieve/cmd-keep.c, src/lib-sieve/cmd-redirect.c, src
3075
 
+       /lib-sieve/plugins/include/ext-include-common.c, src/lib-sieve
3076
 
+       /sieve-actions.c, src/lib-sieve/sieve-actions.h, src/lib-sieve
3077
 
+       /sieve-interpreter.c, src/lib-sieve/sieve-interpreter.h, src/lib-
3078
 
+       sieve/sieve-result.c, src/lib-sieve/sieve-result.h, src/lib-sieve
3079
 
+       /sieve-types.h, src/lib-sieve/sieve.c, src/lib-sieve/sieve.h,
3080
 
+       src/plugins/lda-sieve/lda-sieve-plugin.c, src/sieve-bin/sieve-
3081
 
+       exec.c, src/sieve-bin/sieve-test.c, src/testsuite/testsuite-
3082
 
+       common.c, src/testsuite/testsuite.c:
3083
 
+       Made plugin use tried_default_save indicator to prevent duplicate
3084
 
+       error messages.
3085
 
+       [f0a7278c5645]
3086
 
+
3087
 
+2008-10-04  Stephan Bosch  <stephan@rename-it.nl>
3088
 
+
3089
 
+       * TODO:
3090
 
+       Updated TODO.
3091
 
+       [0896583c34c1]
3092
 
+
3093
 
+2008-09-28  Stephan Bosch  <stephan@rename-it.nl>
3094
 
+
3095
 
+       * src/lib-sieve/plugins/variables/ext-variables-common.c, src/lib-
3096
 
+       sieve/plugins/variables/ext-variables-common.h, src/lib-
3097
 
+       sieve/plugins/variables/ext-variables-dump.c, src/lib-
3098
 
+       sieve/plugins/variables/ext-variables-dump.h, src/lib-
3099
 
+       sieve/plugins/variables/ext-variables-operands.c, src/lib-
3100
 
+       sieve/plugins/variables/ext-variables.c, src/lib-
3101
 
+       sieve/plugins/variables/sieve-ext-variables.h, src/lib-sieve/sieve-
3102
 
+       code-dumper.c, src/lib-sieve/sieve-code-dumper.h:
3103
 
+       Variables: added identifier dump support for main scope.
3104
 
+       [87841459a7ee]
3105
 
+
3106
 
+2008-09-18  Stephan Bosch  <stephan@rename-it.nl>
3107
 
+
3108
 
+       * src/lib-sieve/plugins/variables/Makefile.am, src/lib-
3109
 
+       sieve/plugins/variables/ext-variables-common.c, src/lib-
3110
 
+       sieve/plugins/variables/ext-variables-common.h, src/lib-
3111
 
+       sieve/plugins/variables/ext-variables-dump.c, src/lib-
3112
 
+       sieve/plugins/variables/ext-variables-dump.h, src/lib-
3113
 
+       sieve/plugins/variables/ext-variables.c, src/lib-sieve/sieve-code-
3114
 
+       dumper.c, src/lib-sieve/sieve-code-dumper.h:
3115
 
+       Variables: added dumptime context.
3116
 
+       [7cd99ac6219f]
3117
 
+
3118
 
+2008-09-15  Stephan Bosch  <stephan@rename-it.nl>
3119
 
+
3120
 
+       * Merged concurrent changes.
3121
 
+       [f61d20c07954]
3122
 
+
3123
 
+2008-09-14  Stephan Bosch  <stephan@rename-it.nl>
3124
 
+
3125
 
+       * NEWS:
3126
 
+       Started NEWS file.
3127
 
+       [32f5a1ed47c6]
3128
 
+
3129
 
+       * DESIGN, Makefile.am, doc/devel/DESIGN:
3130
 
+       Moved design description to doc/devel directory.
3131
 
+       [1673630bb79d]
3132
 
+
3133
 
+       * README, examples/elvey.sieve, examples/jerry.sieve,
3134
 
+       examples/mjohnson.sieve, examples/mklose.sieve,
3135
 
+       examples/relational.rfc5231.sieve, examples/rfc3028.sieve,
3136
 
+       examples/sanjay.sieve, examples/sieve_examples.sieve,
3137
 
+       examples/subaddress.rfc5233.sieve, examples/vacation.sieve,
3138
 
+       examples/vivil.sieve, sieve/examples/elvey.sieve,
3139
 
+       sieve/examples/jerry.sieve, sieve/examples/mjohnson.sieve,
3140
 
+       sieve/examples/mklose.sieve,
3141
 
+       sieve/examples/relational.rfc5231.sieve,
3142
 
+       sieve/examples/rfc3028.sieve, sieve/examples/sanjay.sieve,
3143
 
+       sieve/examples/sieve_examples.sieve,
3144
 
+       sieve/examples/subaddress.rfc5233.sieve,
3145
 
+       sieve/examples/vacation.sieve, sieve/examples/vivil.sieve,
3146
 
+       sieve/tests/actions.sieve, sieve/tests/address-part.sieve,
3147
 
+       sieve/tests/basic.sieve, sieve/tests/comparator.sieve, sieve/tests
3148
 
+       /encoded-character.sieve, sieve/tests/envelope.sieve,
3149
 
+       sieve/tests/extensions.sieve, sieve/tests/if.sieve, sieve/tests
3150
 
+       /match-type.sieve, sieve/tests/matches.sieve,
3151
 
+       sieve/tests/stop.sieve, sieve/tests/vacation.sieve,
3152
 
+       tests/compile/examples.svtest:
3153
 
+       Restructured Sieve example scripts.
3154
 
+       [a1962f923e34]
3155
 
+
3156
 
+       * Makefile.am, sieve/tests/fileinto.sieve, sieve/tests/redirect.sieve,
3157
 
+       tests/execute/actions.svtest, tests/execute/actions/fileinto.sieve,
3158
 
+       tests/execute/actions/redirect.sieve,
3159
 
+       tests/extensions/reject/execute.svtest:
3160
 
+       Testsuite: added execution tests for core actions (to find
3161
 
+       segfaults).
3162
 
+       [a1dd8113e9d3]
3163
 
+
3164
 
+       * Makefile.am, sieve/tests/reject.sieve,
3165
 
+       tests/extensions/reject/execute.svtest,
3166
 
+       tests/extensions/reject/execute/basic.sieve:
3167
 
+       Testsuite: added trivial reject action execution test.
3168
 
+       [f319f06ede13]
3169
 
+
3170
 
+2008-09-13  Stephan Bosch  <stephan@rename-it.nl>
3171
 
+
3172
 
+       * sieve/errors/address-errors.sieve, sieve/errors/address-part-
3173
 
+       errors.sieve, sieve/errors/encoded-character.sieve, sieve/errors
3174
 
+       /envelope-errors.sieve, sieve/errors/header-errors.sieve,
3175
 
+       sieve/errors/if-errors.sieve, sieve/errors/interesting.sieve,
3176
 
+       sieve/errors/keep-errors.sieve, sieve/errors/out-address-
3177
 
+       errors.sieve, sieve/errors/parse-errors.sieve, sieve/errors/require-
3178
 
+       errors.sieve, sieve/errors/size-errors.sieve, sieve/errors/stop-
3179
 
+       errors.sieve, sieve/errors/tag-errors.sieve,
3180
 
+       tests/compile/errors.svtest, tests/compile/errors/out-address.sieve,
3181
 
+       tests/compile/errors/tag.sieve:
3182
 
+       Testsuite: added final existing error tests.
3183
 
+       [08769a713018]
3184
 
+
3185
 
+       * README:
3186
 
+       Improved README to be more readable.
3187
 
+       [e6c4a1fdfb42]
3188
 
+
3189
 
+2008-09-12  Stephan Bosch  <stephan@rename-it.nl>
3190
 
+
3191
 
+       * src/lib-sieve/sieve-error.c:
3192
 
+       Removed useless PTR_OFFSET from logfile error handler
3193
 
+       implementation.
3194
 
+       [6f8a49489e5e]
3195
 
+
3196
 
+       * TODO:
3197
 
+       Added pre-release TODO item.
3198
 
+       [4b4ef898598d]
3199
 
+
3200
 
+       * TODO, src/lib-sieve/cmd-redirect.c, src/lib-sieve/cmd-require.c, src
3201
 
+       /lib-sieve/ext-encoded-character.c, src/lib-sieve/ext-envelope.c,
3202
 
+       src/lib-sieve/plugins/body/tst-body.c, src/lib-
3203
 
+       sieve/plugins/imapflags/ext-imapflags-common.c, src/lib-
3204
 
+       sieve/plugins/include/cmd-import.c, src/lib-sieve/plugins/include
3205
 
+       /cmd-include.c, src/lib-sieve/plugins/regex/mcht-regex.c, src/lib-
3206
 
+       sieve/plugins/relational/ext-relational-common.c, src/lib-
3207
 
+       sieve/plugins/vacation/cmd-vacation.c, src/lib-
3208
 
+       sieve/plugins/variables/cmd-set.c, src/lib-sieve/plugins/variables
3209
 
+       /ext-variables-arguments.c, src/lib-sieve/sieve-commands.h, src/lib-
3210
 
+       sieve/sieve-comparators.c, src/lib-sieve/sieve-match-types.c, src
3211
 
+       /lib-sieve/sieve-match-types.h, src/lib-sieve/sieve-validator.c, src
3212
 
+       /lib-sieve/tst-address.c, src/lib-sieve/tst-size.c, src/testsuite
3213
 
+       /testsuite-objects.c:
3214
 
+       Improved argument error reporting.
3215
 
+       [ad5905fa16bc]
3216
 
+
3217
 
+       * src/lib-sieve/sieve-ast.c, src/lib-sieve/sieve-ast.h, src/lib-sieve
3218
 
+       /sieve-commands.h, src/lib-sieve/sieve-generator.c, src/lib-sieve
3219
 
+       /sieve-generator.h, src/lib-sieve/sieve-validator.c, src/lib-sieve
3220
 
+       /sieve-validator.h:
3221
 
+       Restructured error reporting in validator and code generator.
3222
 
+       [d54dfe15ad5f]
3223
 
+
3224
 
+       * src/lib-sieve/plugins/vacation/cmd-vacation.c, src/lib-sieve/tst-
3225
 
+       size.c, src/testsuite/tst-test-error.c:
3226
 
+       Fixed new ia64 warnings.
3227
 
+       [191eabe91f70]
3228
 
+
3229
 
+       * src/lib-sieve/sieve-code.c, src/lib-sieve/sieve-code.h:
3230
 
+       Fixed new ia64 warnings in sieve-code.
3231
 
+       [bc8e86291ec7]
3232
 
+
3233
 
+       * src/lib-sieve/sieve-code.h:
3234
 
+       Fixed new ia64 warnings in sieve-code.
3235
 
+       [f655f4d28eb2]
3236
 
+
3237
 
+       * src/lib-sieve/sieve-code.c, src/lib-sieve/sieve-code.h:
3238
 
+       Fixed ia64 warnings in sieve-code.
3239
 
+       [4f2b18823f75]
3240
 
+
3241
 
+       * src/lib-sieve/plugins/variables/ext-variables-arguments.c:
3242
 
+       Variables: fixed ia64 compiler warnings.
3243
 
+       [04859d48e9f6]
3244
 
+
3245
 
+       * src/lib-sieve/sieve-error.c:
3246
 
+       Forgot to handle return value of o_stream_send in logfile error
3247
 
+       hander implementation.
3248
 
+       [50f6194d644e]
3249
 
+
3250
 
+       * src/lib-sieve/sieve-error.c:
3251
 
+       Forgot O_TRUNC in logfile error handler's second logfile open()
3252
 
+       call.
3253
 
+       [9f7e64968d61]
3254
 
+
3255
 
+       * src/lib-sieve/plugins/include/cmd-import.c:
3256
 
+       Include: improved trace verbosity for import command.
3257
 
+       [6618ab99e32a]
3258
 
+
3259
 
+       * src/lib-sieve/plugins/include/cmd-import.c, src/lib-
3260
 
+       sieve/plugins/include/cmd-include.c, src/lib-sieve/plugins/include
3261
 
+       /ext-include-binary.c, src/lib-sieve/plugins/include/ext-include-
3262
 
+       variables.c, src/lib-sieve/plugins/variables/ext-variables-common.c,
3263
 
+       src/lib-sieve/plugins/variables/ext-variables-modifiers.c, src/lib-
3264
 
+       sieve/plugins/variables/ext-variables-operands.c, src/lib-sieve
3265
 
+       /sieve-binary.c, src/lib-sieve/sieve-binary.h, src/lib-sieve/sieve-
3266
 
+       code-dumper.c, src/lib-sieve/sieve-code.c, src/lib-sieve/sieve-
3267
 
+       code.h, src/lib-sieve/sieve-generator.c, src/lib-sieve/sieve-
3268
 
+       interpreter.c:
3269
 
+       Hopefully resolved various type cast warnings surfacing on ia_64 and
3270
 
+       not on i386.
3271
 
+       [0e9312deb8ea]
3272
 
+
3273
 
+       * tests/address.svtest:
3274
 
+       Testsuite: added address test case for specific strange situation.
3275
 
+       [5bc7b863ba0b]
3276
 
+
3277
 
+       * src/lib-sieve/plugins/relational/mcht-count.c:
3278
 
+       Relational: fixed portability issue in count match type (warning).
3279
 
+       [910812bf8e80]
3280
 
+
3281
 
+2008-09-10  Stephan Bosch  <stephan@rename-it.nl>
3282
 
+
3283
 
+       * README:
3284
 
+       Updated documentation.
3285
 
+       [11408405fac3]
3286
 
+
3287
 
+       * TODO, src/lib-sieve/sieve-error.c:
3288
 
+       Devised simple log rotation to prevent per-user sieve processing
3289
 
+       logs to grow indefinitely.
3290
 
+       [9d42eeb8ce8f]
3291
 
+
3292
 
+2008-09-09  Stephan Bosch  <stephan@rename-it.nl>
3293
 
+
3294
 
+       * TODO:
3295
 
+       Updated TODO list.
3296
 
+       [a589169c1870]
3297
 
+
3298
 
+       * TODO, src/lib-sieve/cmd-redirect.c, src/lib-sieve/ext-envelope.c,
3299
 
+       src/lib-sieve/ext-fileinto.c, src/lib-sieve/ext-reject.c, src/lib-
3300
 
+       sieve/mcht-is.c, src/lib-sieve/plugins/body/tst-body.c, src/lib-
3301
 
+       sieve/plugins/imapflags/ext-imapflags-common.c, src/lib-
3302
 
+       sieve/plugins/imapflags/tag-flags.c, src/lib-sieve/plugins/imapflags
3303
 
+       /tst-hasflag.c, src/lib-sieve/plugins/include/cmd-include.c, src
3304
 
+       /lib-sieve/plugins/vacation/cmd-vacation.c, src/lib-
3305
 
+       sieve/plugins/variables/cmd-set.c, src/lib-sieve/plugins/variables
3306
 
+       /ext-variables-common.c, src/lib-sieve/plugins/variables/ext-
3307
 
+       variables-modifiers.c, src/lib-sieve/plugins/variables/ext-
3308
 
+       variables-operands.c, src/lib-sieve/plugins/variables/tst-string.c,
3309
 
+       src/lib-sieve/sieve-address-parts.c, src/lib-sieve/sieve-code-
3310
 
+       dumper.c, src/lib-sieve/sieve-code.c, src/lib-sieve/sieve-code.h,
3311
 
+       src/lib-sieve/sieve-comparators.c, src/lib-sieve/sieve-match-
3312
 
+       types.c, src/lib-sieve/tst-address.c, src/lib-sieve/tst-exists.c,
3313
 
+       src/lib-sieve/tst-header.c, src/lib-sieve/tst-size.c, src/testsuite
3314
 
+       /cmd-test-fail.c, src/testsuite/cmd-test-set.c, src/testsuite/cmd-
3315
 
+       test.c, src/testsuite/testsuite-objects.c, src/testsuite/tst-test-
3316
 
+       compile.c, src/testsuite/tst-test-error.c:
3317
 
+       Improved byte code dumping to be more readable.
3318
 
+       [758155f2aab1]
3319
 
+
3320
 
+       * TODO:
3321
 
+       Updated TODO file.
3322
 
+       [b9341f8c801e]
3323
 
+
3324
 
+2008-09-07  Stephan Bosch  <stephan@rename-it.nl>
3325
 
+
3326
 
+       * INSTALL, README, TODO:
3327
 
+       Updated documentation.
3328
 
+       [6628c1731333]
3329
 
+
3330
 
+       * TODO:
3331
 
+       Removed redundant security issue listed in TODO.
3332
 
+       [05599a5b010b]
3333
 
+
3334
 
+       * Makefile.am, TODO, src/lib-sieve/mcht-is.c, src/lib-sieve/sieve-
3335
 
+       address-parts.c, tests/address.svtest:
3336
 
+       Resolved handling of invalid addresses in headers for the most part.
3337
 
+       [0f3e2d8877e4]
3338
 
+
3339
 
+       * TODO, src/lib-sieve/plugins/include/ext-include-common.c, src/lib-
3340
 
+       sieve/plugins/variables/ext-variables-common.c, src/lib-
3341
 
+       sieve/plugins/variables/ext-variables-operands.c, src/lib-
3342
 
+       sieve/plugins/variables/sieve-ext-variables.h:
3343
 
+       Variables: made sure broken/malicious binary cannot allocate
3344
 
+       variable storage of arbitrary size.
3345
 
+       [1ce135869da6]
3346
 
+
3347
 
+       * src/lib-sieve/plugins/include/ext-include.c, src/lib-
3348
 
+       sieve/plugins/variables/ext-variables-common.c:
3349
 
+       Variables: added coding of variable scope.
3350
 
+       [511ac1c1864e]
3351
 
+
3352
 
+       * src/lib-sieve/ext-encoded-character.c, src/lib-sieve/ext-envelope.c,
3353
 
+       src/lib-sieve/ext-fileinto.c, src/lib-sieve/ext-reject.c, src/lib-
3354
 
+       sieve/plugins/body/ext-body.c, src/lib-sieve/plugins/comparator-i
3355
 
+       -ascii-numeric/ext-cmp-i-ascii-numeric.c, src/lib-sieve/plugins/copy
3356
 
+       /ext-copy.c, src/lib-sieve/plugins/imapflags/ext-imapflags.c, src
3357
 
+       /lib-sieve/plugins/include/ext-include.c, src/lib-
3358
 
+       sieve/plugins/regex/ext-regex.c, src/lib-sieve/plugins/relational
3359
 
+       /ext-relational.c, src/lib-sieve/plugins/subaddress/ext-
3360
 
+       subaddress.c, src/lib-sieve/plugins/vacation/ext-vacation.c, src
3361
 
+       /lib-sieve/plugins/variables/ext-variables-arguments.c, src/lib-
3362
 
+       sieve/plugins/variables/ext-variables-common.c, src/lib-
3363
 
+       sieve/plugins/variables/ext-variables-common.h, src/lib-
3364
 
+       sieve/plugins/variables/ext-variables.c, src/lib-sieve/sieve-
3365
 
+       address-parts.c, src/lib-sieve/sieve-code-dumper.c, src/lib-sieve
3366
 
+       /sieve-comparators.c, src/lib-sieve/sieve-extensions.c, src/lib-
3367
 
+       sieve/sieve-extensions.h, src/lib-sieve/sieve-interpreter.c, src
3368
 
+       /lib-sieve/sieve-match-types.c, src/testsuite/ext-testsuite.c:
3369
 
+       Added support for per-script extension intialization.
3370
 
+       [8ce3c35e05d7]
3371
 
+
3372
 
+2008-09-06  Stephan Bosch  <stephan@rename-it.nl>
3373
 
+
3374
 
+       * INSTALL, README:
3375
 
+       Reduced the severity of the warning indicating the experimental
3376
 
+       nature of this implementation.
3377
 
+       [ceea4bd93458]
3378
 
+
3379
 
+       * TODO:
3380
 
+       Updated TODO.
3381
 
+       [a200a842fd4c]
3382
 
+
3383
 
+2008-08-31  Stephan Bosch  <stephan@rename-it.nl>
3384
 
+
3385
 
+       * src/lib-sieve/sieve-code-dumper.c:
3386
 
+       Minor cosmetic change to code dumping.
3387
 
+       [75828a2293e0]
3388
 
+
3389
 
+       * src/lib-sieve/plugins/include/ext-include-binary.c, src/lib-
3390
 
+       sieve/plugins/include/ext-include-common.c, src/lib-sieve/sieve-
3391
 
+       ast.c, src/lib-sieve/sieve-binary-dumper.c, src/lib-sieve/sieve-
3392
 
+       code-dumper.c, src/lib-sieve/sieve-generator.c, src/lib-sieve/sieve-
3393
 
+       interpreter.c, src/lib-sieve/sieve.c, src/testsuite/testsuite-
3394
 
+       common.c, src/testsuite/testsuite.c:
3395
 
+       Added the concept of a script code header to list the extensions
3396
 
+       actually used by a script (was using all extensions listed in the
3397
 
+       binary).
3398
 
+       [7be9b0d97e5f]
3399
 
+
3400
 
+       * src/lib-sieve/cmd-require.c, src/lib-sieve/sieve-ast.c, src/lib-
3401
 
+       sieve/sieve-ast.h, src/lib-sieve/sieve-generator.c, src/lib-sieve
3402
 
+       /sieve-generator.h, src/lib-sieve/sieve-interpreter.c, src/lib-sieve
3403
 
+       /sieve-validator.c:
3404
 
+       Revised implementation of the require command.
3405
 
+       [40c588255ef4]
3406
 
+
3407
 
+       * Makefile.am, TODO, src/lib-sieve/plugins/vacation/cmd-vacation.c,
3408
 
+       tests/extensions/vacation/execute.svtest,
3409
 
+       tests/extensions/vacation/execute/no-handle.sieve:
3410
 
+       Vacation: properly implemented handling of variables vs. handle
3411
 
+       generation.
3412
 
+       [93fb21f7bc6b]
3413
 
+
3414
 
+       * tests/extensions/imapflags/execute.svtest,
3415
 
+       tests/extensions/imapflags/execute/flags-side-effect.sieve:
3416
 
+       Forgot to add niet testsuite files.
3417
 
+       [aae56b7f1a47]
3418
 
+
3419
 
+       * src/lib-sieve/sieve-code.c, src/lib-sieve/sieve-code.h:
3420
 
+       Added support for runtime detection of variable strings.
3421
 
+       [6e1f1dcabba9]
3422
 
+
3423
 
+       * TODO:
3424
 
+       Updated TODO.
3425
 
+       [7741fd1718b8]
3426
 
+
3427
 
+       * Makefile.am, TODO, src/lib-sieve/cmd-keep.c, src/lib-
3428
 
+       sieve/plugins/copy/ext-copy.c, src/lib-sieve/plugins/imapflags/tag-
3429
 
+       flags.c, src/lib-sieve/sieve-actions.h, src/lib-sieve/sieve-
3430
 
+       generator.c, src/lib-sieve/sieve-result.c:
3431
 
+       Imapflags: properly implemented handling of duplicate store actions
3432
 
+       with different :flags.
3433
 
+       [3ac7e031ebd0]
3434
 
+
3435
 
+2008-08-30  Stephan Bosch  <stephan@rename-it.nl>
3436
 
+
3437
 
+       * src/lib-sieve/cmd-redirect.c:
3438
 
+       Fixed assertion triggered at the end when redirect was executed
3439
 
+       before.
3440
 
+       [3ac9261ad66f]
3441
 
+
3442
 
+       * src/sieve-bin/mail-raw.c, src/sieve-bin/mail-raw.h, src/sieve-bin
3443
 
+       /sieve-exec.c, src/sieve-bin/sieve-test.c:
3444
 
+       Incorporated changes in deliver into the mail-raw implementation of
3445
 
+       the sieve tools.
3446
 
+       [938996ab0023]
3447
 
+
3448
 
+2008-08-26  Stephan Bosch  <stephan@rename-it.nl>
3449
 
+
3450
 
+       * TODO, src/lib-sieve/plugins/imapflags/ext-imapflags-common.c:
3451
 
+       Imapflags: Added FIXME.
3452
 
+       [fd1281ef5eef]
3453
 
+
3454
 
+       * TODO, src/lib-sieve/cmd-discard.c, src/lib-sieve/cmd-redirect.c, src
3455
 
+       /lib-sieve/ext-reject.c, src/lib-sieve/plugins/vacation/cmd-
3456
 
+       vacation.c, src/lib-sieve/sieve-actions.c, src/lib-sieve/sieve-
3457
 
+       result.c, src/lib-sieve/sieve-result.h, tests/execute/errors.svtest,
3458
 
+       tests/execute/errors/actions-limit.sieve, tests/execute/errors
3459
 
+       /redirect-limit.sieve:
3460
 
+       Implemented policy limit on the maximum number of redirect actions
3461
 
+       in a result.
3462
 
+       [c8524a9a370f]
3463
 
+
3464
 
+       * src/lib-sieve/Makefile.am, src/lib-sieve/sieve-limits.c, src/lib-
3465
 
+       sieve/sieve-limits.h, src/lib-sieve/sieve-result.c,
3466
 
+       tests/execute/errors.svtest, tests/execute/errors/actions-
3467
 
+       limit.sieve:
3468
 
+       Implemented limit on the number of actions active simultaneously.
3469
 
+       [a62a86f489d0]
3470
 
+
3471
 
+       * src/lib-sieve/plugins/variables/ext-variables-common.c,
3472
 
+       tests/extensions/include/errors/action-conflicts.sieve,
3473
 
+       tests/extensions/include/errors/included/action-fileinto.sieve,
3474
 
+       tests/extensions/include/errors/included/action-reject.sieve,
3475
 
+       tests/extensions/include/errors/runtime.sieve:
3476
 
+       Include: fixed a stupid bug triggered when variables are not used.
3477
 
+       [48079cfe53f7]
3478
 
+
3479
 
+       * tests/extensions/include/errors.svtest:
3480
 
+       Testsuite: activated runtime tests for the include extension.
3481
 
+       [73aa79ec006a]
3482
 
+
3483
 
+       * Makefile.am, tests/extensions/vacation/errors.svtest,
3484
 
+       tests/extensions/vacation/errors/conflict-reject.sieve:
3485
 
+       Testsuite: added runtime error tests for vacation extension.
3486
 
+       [d32c37e395ce]
3487
 
+
3488
 
+       * Makefile.am, tests/execute/errors.svtest, tests/execute/errors
3489
 
+       /action-conflicts.sieve, tests/execute/errors/conflict-reject-
3490
 
+       fileinto.sieve, tests/execute/errors/conflict-reject-keep.sieve,
3491
 
+       tests/execute/errors/conflict-reject-redirect.sieve:
3492
 
+       Testsuite: added simple runtime action conflict tests.
3493
 
+       [6bef60271972]
3494
 
+
3495
 
+       * doc/rfc/draft-ietf-sieve-refuse-reject-07.txt:
3496
 
+       Installed refuse-reject draft RFC in doc/rfc directory.
3497
 
+       [c608ef17a086]
3498
 
+
3499
 
+2008-08-25  Stephan Bosch  <stephan@rename-it.nl>
3500
 
+
3501
 
+       * sieve/errors/action-conflicts.sieve, sieve/errors/action-
3502
 
+       duplicates.sieve, src/lib-sieve/sieve-interpreter.c,
3503
 
+       src/testsuite/Makefile.am, src/testsuite/ext-testsuite.c,
3504
 
+       src/testsuite/testsuite-common.c, src/testsuite/testsuite-common.h,
3505
 
+       src/testsuite/testsuite.c, src/testsuite/tst-test-execute.c,
3506
 
+       tests/execute/errors/action-conflicts.sieve, tests/execute/errors
3507
 
+       /action-duplicates.sieve:
3508
 
+       Testsuite: added support for testing runtime errors.
3509
 
+       [e2a304290b53]
3510
 
+
3511
 
+       * TODO, src/lib-sieve/plugins/vacation/cmd-vacation.c, src/lib-sieve
3512
 
+       /sieve-ast.c, src/lib-sieve/sieve-ast.h:
3513
 
+       Vacation: discovered and partially fixed various RFC-related issues.
3514
 
+       [97e0e14d9557]
3515
 
+
3516
 
+       * doc/rfc/vacation.rfc5230.txt, src/lib-sieve/plugins/vacation/draft-
3517
 
+       ietf-sieve-vacation-07.txt, src/lib-sieve/plugins/vacation/ext-
3518
 
+       vacation.c:
3519
 
+       Installed new RFC for vacation extension in doc/rfc directory.
3520
 
+       [df13b70a2cb1]
3521
 
+
3522
 
+       * TODO:
3523
 
+       Updated TODO.
3524
 
+       [a256cbead058]
3525
 
+
3526
 
+       * TODO, src/testsuite/cmd-test-fail.c, src/testsuite/cmd-test-set.c,
3527
 
+       src/testsuite/cmd-test.c, src/testsuite/ext-testsuite.c,
3528
 
+       src/testsuite/mail-raw.c, src/testsuite/mail-raw.h,
3529
 
+       src/testsuite/namespaces.c, src/testsuite/namespaces.h,
3530
 
+       src/testsuite/testsuite-common.c, src/testsuite/testsuite-common.h,
3531
 
+       src/testsuite/testsuite-objects.c, src/testsuite/testsuite-
3532
 
+       objects.h, src/testsuite/testsuite.c, src/testsuite/tst-test-
3533
 
+       compile.c, src/testsuite/tst-test-error.c:
3534
 
+       Finished code cleanup for now.
3535
 
+       [a458a0b55c11]
3536
 
+
3537
 
+       * src/sieve-bin/bin-common.c, src/sieve-bin/bin-common.h, src/sieve-
3538
 
+       bin/mail-raw.c, src/sieve-bin/mail-raw.h, src/sieve-
3539
 
+       bin/namespaces.c, src/sieve-bin/namespaces.h, src/sieve-bin/sieve-
3540
 
+       exec.c, src/sieve-bin/sieve-test.c, src/sieve-bin/sievec.c, src
3541
 
+       /sieve-bin/sieved.c:
3542
 
+       Cleaned up Sieve tools.
3543
 
+       [ae09a094452c]
3544
 
+
3545
 
+       * src/plugins/lda-sieve/lda-sieve-plugin.c, src/plugins/lda-sieve/lda-
3546
 
+       sieve-plugin.h:
3547
 
+       Cleaned up LDA Sieve plugin.
3548
 
+       [ed1ca951fd92]
3549
 
+
3550
 
+       * src/lib-sieve/plugins/variables/cmd-set.c, src/lib-
3551
 
+       sieve/plugins/variables/ext-variables-arguments.c, src/lib-
3552
 
+       sieve/plugins/variables/ext-variables-arguments.h, src/lib-
3553
 
+       sieve/plugins/variables/ext-variables-common.c, src/lib-
3554
 
+       sieve/plugins/variables/ext-variables-common.h, src/lib-
3555
 
+       sieve/plugins/variables/ext-variables-limits.h, src/lib-
3556
 
+       sieve/plugins/variables/ext-variables-modifiers.c, src/lib-
3557
 
+       sieve/plugins/variables/ext-variables-modifiers.h, src/lib-
3558
 
+       sieve/plugins/variables/ext-variables-name.c, src/lib-
3559
 
+       sieve/plugins/variables/ext-variables-name.h, src/lib-
3560
 
+       sieve/plugins/variables/ext-variables-operands.c, src/lib-
3561
 
+       sieve/plugins/variables/ext-variables-operands.h, src/lib-
3562
 
+       sieve/plugins/variables/ext-variables.c, src/lib-
3563
 
+       sieve/plugins/variables/sieve-ext-variables.h, src/lib-
3564
 
+       sieve/plugins/variables/tst-string.c:
3565
 
+       Cleaned up variables extension.
3566
 
+       [5a4e4e269892]
3567
 
+
3568
 
+       * src/lib-sieve/plugins/vacation/cmd-vacation.c:
3569
 
+       Vacation: removed useless duplicate_mark call.
3570
 
+       [569aaef1dd00]
3571
 
+
3572
 
+       * src/lib-sieve/plugins/vacation/cmd-vacation.c, src/lib-
3573
 
+       sieve/plugins/vacation/ext-vacation-common.h, src/lib-
3574
 
+       sieve/plugins/vacation/ext-vacation.c:
3575
 
+       Cleaned up vacation extension.
3576
 
+       [8df7a1bc6564]
3577
 
+
3578
 
+2008-08-18  Stephan Bosch  <stephan@rename-it.nl>
3579
 
+
3580
 
+       * Makefile.am, sieve/examples/subaddress.rfc5233.sieve, tests/address-
3581
 
+       parts/subaddress.svtest, tests/compile/examples.svtest,
3582
 
+       tests/extensions/subaddress/basic.svtest,
3583
 
+       tests/extensions/subaddress/rfc.svtest:
3584
 
+       Testsuite: extended tests for the subaddress extension.
3585
 
+       [7f440b626914]
3586
 
+
3587
 
+2008-08-17  Stephan Bosch  <stephan@rename-it.nl>
3588
 
+
3589
 
+       * doc/rfc/subaddress.rfc5233.txt, src/lib-
3590
 
+       sieve/plugins/subaddress/rfc3598.txt:
3591
 
+       Installed new subaddress RFC in doc/rfc directory.
3592
 
+       [5cb09b134086]
3593
 
+
3594
 
+       * src/lib-sieve/plugins/subaddress/ext-subaddress.c:
3595
 
+       Cleaned up subaddress extension.
3596
 
+       [ec5e1f9fda78]
3597
 
+
3598
 
+       * Makefile.am, sieve/examples/relational.rfc5231.sieve, tests/compile
3599
 
+       /compile-examples.svtest, tests/compile/examples.svtest,
3600
 
+       tests/extensions/relational/basic.svtest,
3601
 
+       tests/extensions/relational/errors.svtest,
3602
 
+       tests/extensions/relational/errors/validation.sieve,
3603
 
+       tests/extensions/relational/rfc.svtest, tests/match-
3604
 
+       types/relational.svtest:
3605
 
+       Testsuite: restructured and extended tests for the relational
3606
 
+       extension.
3607
 
+       [17ee47e6d698]
3608
 
+
3609
 
+       * doc/rfc/relational.rfc5231.txt, src/lib-
3610
 
+       sieve/plugins/relational/rfc3431.txt:
3611
 
+       Installed new relational RFC in doc/rfc directory.
3612
 
+       [6a1838d879d9]
3613
 
+
3614
 
+       * src/lib-sieve/plugins/relational/ext-relational-common.c, src/lib-
3615
 
+       sieve/plugins/relational/ext-relational-common.h, src/lib-
3616
 
+       sieve/plugins/relational/ext-relational.c, src/lib-
3617
 
+       sieve/plugins/relational/mcht-count.c, src/lib-
3618
 
+       sieve/plugins/relational/mcht-value.c:
3619
 
+       Cleaned up relational extension.
3620
 
+       [8fa1cca640b9]
3621
 
+
3622
 
+       * src/lib-sieve/plugins/regex/ext-regex-common.c, src/lib-
3623
 
+       sieve/plugins/regex/ext-regex-common.h, src/lib-sieve/plugins/regex
3624
 
+       /ext-regex.c, src/lib-sieve/plugins/regex/mcht-regex.c:
3625
 
+       Cleaned up regex extension.
3626
 
+       [930e79a89723]
3627
 
+
3628
 
+       * src/lib-sieve/plugins/include/cmd-import.c, src/lib-
3629
 
+       sieve/plugins/include/cmd-include.c, src/lib-sieve/plugins/include
3630
 
+       /cmd-return.c, src/lib-sieve/plugins/include/ext-include-binary.c,
3631
 
+       src/lib-sieve/plugins/include/ext-include-binary.h, src/lib-
3632
 
+       sieve/plugins/include/ext-include-common.c, src/lib-
3633
 
+       sieve/plugins/include/ext-include-common.h, src/lib-
3634
 
+       sieve/plugins/include/ext-include-limits.h, src/lib-
3635
 
+       sieve/plugins/include/ext-include-variables.c, src/lib-
3636
 
+       sieve/plugins/include/ext-include-variables.h, src/lib-
3637
 
+       sieve/plugins/include/ext-include.c:
3638
 
+       Cleaned up include extension.
3639
 
+       [4f58be7cfde3]
3640
 
+
3641
 
+       * src/lib-sieve/plugins/imapflags/cmd-addflag.c, src/lib-
3642
 
+       sieve/plugins/imapflags/cmd-removeflag.c, src/lib-
3643
 
+       sieve/plugins/imapflags/cmd-setflag.c, src/lib-
3644
 
+       sieve/plugins/imapflags/ext-imapflags-common.c, src/lib-
3645
 
+       sieve/plugins/imapflags/ext-imapflags-common.h, src/lib-
3646
 
+       sieve/plugins/imapflags/ext-imapflags.c, src/lib-
3647
 
+       sieve/plugins/imapflags/tag-flags.c, src/lib-sieve/plugins/imapflags
3648
 
+       /tst-hasflag.c:
3649
 
+       Cleaned up imapflags extension.
3650
 
+       [1dc6e9c11f50]
3651
 
+
3652
 
+       * src/lib-sieve/plugins/copy/ext-copy.c:
3653
 
+       Cleaned up copy extension.
3654
 
+       [1ae3233e93c0]
3655
 
+
3656
 
+       * src/lib-sieve/plugins/comparator-i-ascii-numeric/ext-cmp-i-ascii-
3657
 
+       numeric.c:
3658
 
+       Cleaned up comparator-i;ascii-numeric.
3659
 
+       [3bc2c679843b]
3660
 
+
3661
 
+2008-08-16  Stephan Bosch  <stephan@rename-it.nl>
3662
 
+
3663
 
+       * tests/extensions/body/match-values.svtest:
3664
 
+       Forgot to add test file.
3665
 
+       [31efedcb72a6]
3666
 
+
3667
 
+       * Makefile.am:
3668
 
+       Testsuite: added test for the behavior of the body test with match
3669
 
+       values.
3670
 
+       [76c69d75e5bd]
3671
 
+
3672
 
+       * src/lib-sieve/plugins/body/ext-body-common.h, src/lib-
3673
 
+       sieve/plugins/body/ext-body.c, src/lib-sieve/plugins/body/tst-
3674
 
+       body.c, src/lib-sieve/sieve-match-types.c:
3675
 
+       Body: now disables match value processing during body test
3676
 
+       evaluation as required by RFC.
3677
 
+       [43ed6da2c07d]
3678
 
+
3679
 
+       * src/lib-sieve/mcht-contains.c, src/lib-sieve/mcht-is.c, src/lib-
3680
 
+       sieve/mcht-matches.c, src/lib-sieve/sieve-result.c, src/lib-sieve
3681
 
+       /sieve-result.h, src/lib-sieve/sieve-script-private.h, src/lib-sieve
3682
 
+       /sieve-script.c, src/lib-sieve/sieve-script.h, src/lib-sieve/sieve-
3683
 
+       types.h, src/lib-sieve/sieve-validator.c, src/lib-sieve/sieve-
3684
 
+       validator.h:
3685
 
+       Finished code cleanup of the sieve library itself.
3686
 
+       [7041828c5bf4]
3687
 
+
3688
 
+       * src/lib-sieve/sieve-common.h, src/lib-sieve/sieve-dump.h, src/lib-
3689
 
+       sieve/sieve-error-private.h, src/lib-sieve/sieve-error.c, src/lib-
3690
 
+       sieve/sieve-error.h, src/lib-sieve/sieve-extensions.c, src/lib-sieve
3691
 
+       /sieve-extensions.h, src/lib-sieve/sieve-generator.c, src/lib-sieve
3692
 
+       /sieve-generator.h, src/lib-sieve/sieve-interpreter.c, src/lib-sieve
3693
 
+       /sieve-interpreter.h, src/lib-sieve/sieve-limits.h, src/lib-sieve
3694
 
+       /sieve-message.c, src/lib-sieve/sieve-message.h, src/lib-sieve
3695
 
+       /sieve-objects.c, src/lib-sieve/sieve-objects.h:
3696
 
+       Broad code cleanup.
3697
 
+       [ce2750c32d73]
3698
 
+
3699
 
+       * src/lib-sieve/cmd-stop.c:
3700
 
+       Forgot to add new file for stop command.
3701
 
+       [85e220b27364]
3702
 
+
3703
 
+       * src/lib-sieve/Makefile.am, src/lib-sieve/cmd-discard.c, src/lib-
3704
 
+       sieve/cmd-if.c, src/lib-sieve/cmd-keep.c, src/lib-sieve/cmd-
3705
 
+       redirect.c, src/lib-sieve/cmd-require.c, src/lib-
3706
 
+       sieve/plugins/imapflags/ext-imapflags-common.c, src/lib-
3707
 
+       sieve/plugins/include/cmd-import.c, src/lib-sieve/plugins/variables
3708
 
+       /tst-string.c, src/lib-sieve/sieve-actions.h, src/lib-sieve/sieve-
3709
 
+       code-dumper.c, src/lib-sieve/sieve-commands-private.h, src/lib-sieve
3710
 
+       /sieve-commands.c, src/lib-sieve/sieve-commands.h, src/lib-sieve
3711
 
+       /sieve-generator.c, src/lib-sieve/sieve-interpreter.c, src/lib-sieve
3712
 
+       /sieve-validator.c, src/lib-sieve/tst-address.c, src/lib-sieve/tst-
3713
 
+       allof.c, src/lib-sieve/tst-anyof.c, src/lib-sieve/tst-exists.c, src
3714
 
+       /lib-sieve/tst-header.c, src/lib-sieve/tst-not.c, src/lib-sieve/tst-
3715
 
+       size.c, src/testsuite/cmd-test-fail.c, src/testsuite/cmd-test-set.c,
3716
 
+       src/testsuite/cmd-test.c, src/testsuite/tst-test-compile.c,
3717
 
+       src/testsuite/tst-test-error.c:
3718
 
+       Cleaned up commands implementation.
3719
 
+       [b91b56692665]
3720
 
+
3721
 
+       * src/lib-sieve/sieve-code.c, src/lib-sieve/sieve-code.h:
3722
 
+       Cleaned up sieve-code.
3723
 
+       [bbee4bf32b63]
3724
 
+
3725
 
+       * src/lib-sieve/sieve-binary-dumper.c, src/lib-sieve/sieve-binary-
3726
 
+       dumper.h:
3727
 
+       Cleaned up sieve-binary-dumper.
3728
 
+       [08a3dc06bce3]
3729
 
+
3730
 
+       * src/lib-sieve/sieve-binary.c, src/lib-sieve/sieve-binary.h:
3731
 
+       Cleaned up sieve-binary.
3732
 
+       [22672ecf40c3]
3733
 
+
3734
 
+       * src/lib-sieve/sieve-ast.c, src/lib-sieve/sieve-ast.h:
3735
 
+       Cleaned up sieve-ast.
3736
 
+       [00363cd89a2a]
3737
 
+
3738
 
+       * src/lib-sieve/sieve-address.c, src/lib-sieve/sieve-address.h:
3739
 
+       Cleaned up sieve-address.
3740
 
+       [cb7d1b1feb8d]
3741
 
+
3742
 
+       * src/lib-sieve/sieve-actions.c, src/lib-sieve/sieve-actions.h:
3743
 
+       Cleaned up actions implementation.
3744
 
+       [af5589339bd3]
3745
 
+
3746
 
+       * src/lib-sieve/sieve-address-parts.c, src/lib-sieve/sieve-address-
3747
 
+       parts.h, src/lib-sieve/sieve-comparators.c:
3748
 
+       Cleaned up address part and comparator implementation.
3749
 
+       [dfc2d1398889]
3750
 
+
3751
 
+       * sieve/errors/match-type-errors.sieve, src/lib-sieve/ext-envelope.c,
3752
 
+       src/lib-sieve/plugins/body/tst-body.c, src/lib-
3753
 
+       sieve/plugins/imapflags/tst-hasflag.c, src/lib-sieve/plugins/regex
3754
 
+       /mcht-regex.c, src/lib-sieve/plugins/variables/tst-string.c, src
3755
 
+       /lib-sieve/sieve-comparators.h, src/lib-sieve/sieve-match-types.c,
3756
 
+       src/lib-sieve/sieve-match-types.h, src/lib-sieve/tst-address.c, src
3757
 
+       /lib-sieve/tst-header.c, src/testsuite/tst-test-error.c,
3758
 
+       tests/compile/errors.svtest, tests/compile/errors/match-type.sieve:
3759
 
+       Cleaned up match type implementation.
3760
 
+       [945375c5c915]
3761
 
+
3762
 
+       * TODO, src/lib-sieve/plugins/regex/mcht-regex.c:
3763
 
+       Regex: improvements and bugfixes.
3764
 
+       [a6cf1195a291]
3765
 
+
3766
 
+       * Makefile.am, src/lib-sieve/plugins/regex/regex-errors.sieve,
3767
 
+       tests/extensions/regex/basic.svtest,
3768
 
+       tests/extensions/regex/errors.svtest,
3769
 
+       tests/extensions/regex/errors/compile.sieve, tests/match-
3770
 
+       types/regex.svtest:
3771
 
+       Testsuite: restructured regex tests.
3772
 
+       [8e7c02d55cf3]
3773
 
+
3774
 
+       * Makefile.am, doc/rfc/draft-murchison-sieve-regex-07.txt, src/lib-
3775
 
+       sieve/plugins/regex/draft-murchison-sieve-regex-07.txt, src/lib-
3776
 
+       sieve/plugins/regex/mcht-regex.c, src/lib-
3777
 
+       sieve/plugins/regex/regex.sieve, src/lib-sieve/sieve-match-types.c,
3778
 
+       tests/extensions/variables/regex.svtest, tests/match-
3779
 
+       types/regex.svtest:
3780
 
+       Regex: fixed a few minor bugs.
3781
 
+       [560db263607a]
3782
 
+
3783
 
+2008-08-14  Stephan Bosch  <stephan@rename-it.nl>
3784
 
+
3785
 
+       * src/sieve-bin/mail-raw.c, src/sieve-bin/mail-raw.h, src/sieve-
3786
 
+       bin/namespaces.c, src/sieve-bin/namespaces.h, src/sieve-bin/sieve-
3787
 
+       exec.c, src/sieve-bin/sieve-test.c, src/testsuite/mail-raw.c,
3788
 
+       src/testsuite/mail-raw.h, src/testsuite/namespaces.c,
3789
 
+       src/testsuite/namespaces.h, src/testsuite/testsuite-common.c,
3790
 
+       src/testsuite/testsuite-common.h, src/testsuite/testsuite.c:
3791
 
+       Compile fix for changes in Dovecot.
3792
 
+       [aa1a94658613]
3793
 
+
3794
 
+2008-08-13  Stephan Bosch  <stephan@rename-it.nl>
3795
 
+
3796
 
+       * TODO, src/lib-sieve/plugins/include/cmd-import.c, src/lib-
3797
 
+       sieve/plugins/include/ext-include-common.c, src/lib-
3798
 
+       sieve/plugins/include/ext-include-common.h, src/lib-
3799
 
+       sieve/plugins/variables/ext-variables-common.c,
3800
 
+       tests/extensions/include/errors/runtime.sieve:
3801
 
+       Include: implemented runtime checking of export/import.
3802
 
+       [cbd74d26eff4]
3803
 
+
3804
 
+       * src/lib-sieve/plugins/include/cmd-import.c, src/lib-
3805
 
+       sieve/plugins/include/cmd-include.c, src/lib-sieve/plugins/include
3806
 
+       /ext-include-binary.c, src/lib-sieve/plugins/include/ext-include-
3807
 
+       common.h, src/lib-sieve/plugins/include/ext-include-variables.c, src
3808
 
+       /lib-sieve/plugins/include/ext-include-variables.h, src/lib-
3809
 
+       sieve/plugins/include/ext-include.c, src/lib-sieve/sieve-ast.c, src
3810
 
+       /lib-sieve/sieve-ast.h, src/lib-sieve/sieve-validator.c,
3811
 
+       tests/extensions/include/variables.svtest:
3812
 
+       Include: transformed import and export to actual code operations for
3813
 
+       runtime checking.
3814
 
+       [d8002c76aabb]
3815
 
+
3816
 
+       * src/lib-sieve/plugins/variables/ext-variables-common.c, src/lib-
3817
 
+       sieve/plugins/variables/sieve-ext-variables.h:
3818
 
+       Variables: added functionality to obtain variable identifier from
3819
 
+       storage using linked scope.
3820
 
+       [504a89d17b2d]
3821
 
+
3822
 
+       * src/lib-sieve/plugins/imapflags/cmd-addflag.c, src/lib-
3823
 
+       sieve/plugins/imapflags/cmd-removeflag.c, src/lib-
3824
 
+       sieve/plugins/imapflags/cmd-setflag.c, src/lib-
3825
 
+       sieve/plugins/imapflags/ext-imapflags-common.c, src/lib-
3826
 
+       sieve/plugins/imapflags/ext-imapflags-common.h, src/lib-
3827
 
+       sieve/plugins/variables/cmd-set.c, src/lib-sieve/plugins/variables
3828
 
+       /ext-variables-common.c, src/lib-sieve/plugins/variables/ext-
3829
 
+       variables-operands.c, src/lib-sieve/plugins/variables/sieve-ext-
3830
 
+       variables.h:
3831
 
+       Variables: invalid variable indexes now trigger interpretation to
3832
 
+       fail with EXEC_BIN_CORRUPT.
3833
 
+       [7a03042a70ea]
3834
 
+
3835
 
+2008-08-12  Stephan Bosch  <stephan@rename-it.nl>
3836
 
+
3837
 
+       * src/lib-sieve/plugins/imapflags/ext-imapflags-common.c, src/lib-
3838
 
+       sieve/plugins/include/ext-include-binary.c, src/lib-
3839
 
+       sieve/plugins/include/ext-include-binary.h, src/lib-
3840
 
+       sieve/plugins/include/ext-include-common.c, src/lib-
3841
 
+       sieve/plugins/variables/ext-variables-common.c:
3842
 
+       Include: variable indexes are now verified to the global variable
3843
 
+       scope, meaning that a corrupt binary cannot allocate arbitrary
3844
 
+       global variables anymore.
3845
 
+       [d8b16b132509]
3846
 
+
3847
 
+       * src/lib-sieve/ext-encoded-character.c, src/lib-sieve/ext-envelope.c,
3848
 
+       src/lib-sieve/ext-fileinto.c, src/lib-sieve/ext-reject.c, src/lib-
3849
 
+       sieve/plugins/body/ext-body.c, src/lib-sieve/plugins/comparator-i
3850
 
+       -ascii-numeric/ext-cmp-i-ascii-numeric.c, src/lib-sieve/plugins/copy
3851
 
+       /ext-copy.c, src/lib-sieve/plugins/imapflags/ext-imapflags.c, src
3852
 
+       /lib-sieve/plugins/include/ext-include.c, src/lib-
3853
 
+       sieve/plugins/regex/ext-regex.c, src/lib-sieve/plugins/relational
3854
 
+       /ext-relational.c, src/lib-sieve/plugins/subaddress/ext-
3855
 
+       subaddress.c, src/lib-sieve/plugins/vacation/ext-vacation.c, src
3856
 
+       /lib-sieve/plugins/variables/ext-variables.c, src/lib-sieve/sieve-
3857
 
+       address-parts.c, src/lib-sieve/sieve-comparators.c, src/lib-sieve
3858
 
+       /sieve-extensions.c, src/lib-sieve/sieve-extensions.h, src/lib-sieve
3859
 
+       /sieve-match-types.c, src/testsuite/ext-testsuite.c:
3860
 
+       Removed obsoleted runtime_load() extension event.
3861
 
+       [6f0b6cbd33c6]
3862
 
+
3863
 
+       * src/lib-sieve/plugins/imapflags/ext-imapflags-common.c, src/lib-
3864
 
+       sieve/plugins/imapflags/ext-imapflags-common.h, src/lib-
3865
 
+       sieve/plugins/imapflags/ext-imapflags.c, src/lib-
3866
 
+       sieve/plugins/include/ext-include-common.c, src/lib-
3867
 
+       sieve/plugins/variables/ext-variables-common.c, src/lib-
3868
 
+       sieve/plugins/variables/ext-variables-operands.c, src/lib-
3869
 
+       sieve/plugins/variables/sieve-ext-variables.h, src/lib-sieve/sieve-
3870
 
+       interpreter.c, src/lib-sieve/sieve-interpreter.h, src/lib-sieve
3871
 
+       /sieve-match-types.c:
3872
 
+       Added run() event to the interpreter_extension object.
3873
 
+       [878c2ad37f27]
3874
 
+
3875
 
+       * TODO:
3876
 
+       Cleaned up TODO file.
3877
 
+       [8ca8af945cec]
3878
 
+
3879
 
+       * TODO, doc/rfc/RFC Controversy.txt, src/lib-sieve/plugins/imapflags
3880
 
+       /ext-imapflags-common.c, src/lib-sieve/plugins/include/ext-include-
3881
 
+       variables.c, src/lib-sieve/plugins/variables/Makefile.am, src/lib-
3882
 
+       sieve/plugins/variables/cmd-set.c, src/lib-sieve/plugins/variables
3883
 
+       /ext-variables-arguments.c, src/lib-sieve/plugins/variables/ext-
3884
 
+       variables-common.c, src/lib-sieve/plugins/variables/ext-variables-
3885
 
+       limits.h, src/lib-sieve/plugins/variables/ext-variables-name.c, src
3886
 
+       /lib-sieve/plugins/variables/ext-variables-operands.c, src/lib-
3887
 
+       sieve/plugins/variables/sieve-ext-variables.h,
3888
 
+       tests/extensions/variables/basic.svtest,
3889
 
+       tests/extensions/variables/errors.svtest,
3890
 
+       tests/extensions/variables/errors/limits.sieve:
3891
 
+       Variables: implemented limits on number of variables in a scope, the
3892
 
+       length of variable names, size of variable values and the number of
3893
 
+       accesible match values.
3894
 
+       [f23512858a52]
3895
 
+
3896
 
+       * TODO, src/lib-sieve/mcht-matches.c, src/lib-
3897
 
+       sieve/plugins/include/Makefile.am, src/lib-sieve/plugins/regex/mcht-
3898
 
+       regex.c, src/lib-sieve/sieve-limits.h, src/lib-sieve/sieve-match-
3899
 
+       types.c:
3900
 
+       Limited number of accepted match values
3901
 
+       [31520dab90b8]
3902
 
+
3903
 
+       * src/lib-sieve/plugins/include/ext-include-limits.h:
3904
 
+       Include: forgot to add new file to the repository.
3905
 
+       [32e7a10e0c4e]
3906
 
+
3907
 
+       * TODO:
3908
 
+       Merged concurrent changes.
3909
 
+       [9a691e80df72]
3910
 
+
3911
 
+       * TODO, src/lib-sieve/plugins/include/ext-include-binary.c, src/lib-
3912
 
+       sieve/plugins/include/ext-include-binary.h, src/lib-
3913
 
+       sieve/plugins/include/ext-include-common.c, src/lib-
3914
 
+       sieve/plugins/include/ext-include-common.h:
3915
 
+       Include: limited the number of included scripts.
3916
 
+       [f01020cfcebb]
3917
 
+
3918
 
+       * src/lib-sieve/sieve-script.c, src/lib-sieve/sieve-script.h, src/lib-
3919
 
+       sieve/sieve.c, src/lib-sieve/sieve.h, src/plugins/lda-sieve/lda-
3920
 
+       sieve-plugin.c, src/sieve-bin/bin-common.c:
3921
 
+       LDA-Plugin: prevented plugin from polluting the logfiles when the
3922
 
+       script does not exist.
3923
 
+       [5d70ae722bca]
3924
 
+
3925
 
+2008-08-11  Stephan Bosch  <stephan@rename-it.nl>
3926
 
+
3927
 
+       * src/lib-sieve/plugins/include/cmd-include.c,
3928
 
+       tests/extensions/include/errors.svtest,
3929
 
+       tests/extensions/include/errors/generic.sieve:
3930
 
+       Include: used wrong messaging function in previous commit.
3931
 
+       [177bf38926ca]
3932
 
+
3933
 
+       * src/lib-sieve/plugins/include/cmd-include.c:
3934
 
+       Include: prohibited use of '/' in scriptnames.
3935
 
+       [88105cf833da]
3936
 
+
3937
 
+2008-08-10  Stephan Bosch  <stephan@rename-it.nl>
3938
 
+
3939
 
+       * TODO, tests/extensions/body/basic.svtest:
3940
 
+       Body: discovered various issues (listed in disabled tests).
3941
 
+       [66543e00dfba]
3942
 
+
3943
 
+       * src/lib-sieve/sieve-message.c, src/lib-sieve/sieve-message.h,
3944
 
+       src/testsuite/cmd-test-set.c, src/testsuite/testsuite-common.c,
3945
 
+       src/testsuite/testsuite-common.h, src/testsuite/testsuite-objects.c,
3946
 
+       src/testsuite/testsuite-objects.h,
3947
 
+       tests/extensions/body/basic.svtest:
3948
 
+       Body: added test regarding empty bodies and fixed testsuite to flush
3949
 
+       the message context when the message is changed.
3950
 
+       [c6c5a7eb8e6e]
3951
 
+
3952
 
+       * src/lib-sieve/plugins/body/tst-body.c,
3953
 
+       tests/extensions/body/basic.svtest:
3954
 
+       Body: fixed default comparator and added testsuite test to prevent
3955
 
+       this in the future.
3956
 
+       [83bd74561800]
3957
 
+
3958
 
+       * Makefile.am, src/lib-sieve/plugins/body/ext-body-common.c, src/lib-
3959
 
+       sieve/plugins/body/tst-body.c, tests/extensions/body/basic.svtest:
3960
 
+       Body: fixed bug in the :raw transform, added much comment to the
3961
 
+       body extraction code and added a first simple test to the testsuite.
3962
 
+       [3153995e2bc7]
3963
 
+
3964
 
+       * src/lib-sieve/sieve-lexer.c, src/testsuite/mail-raw.c:
3965
 
+       Made the lexer conform to the new Sieve RFC.
3966
 
+       [0fae7796f624]
3967
 
+
3968
 
+       * doc/rfc/body.rfc5173.txt, src/lib-sieve/plugins/body/draft-ietf-
3969
 
+       sieve-body-07.txt, src/lib-sieve/plugins/body/ext-body.c:
3970
 
+       Installed RFC for the body extension in the doc/rfc directory.
3971
 
+       [42dc34bb2dc2]
3972
 
+
3973
 
+       * TODO, src/lib-sieve/cmd-redirect.c, src/lib-sieve/cmd-require.c, src
3974
 
+       /lib-sieve/ext-envelope.c, src/lib-sieve/ext-fileinto.c, src/lib-
3975
 
+       sieve/ext-reject.c, src/lib-sieve/plugins/imapflags/ext-imapflags-
3976
 
+       common.c, src/lib-sieve/plugins/imapflags/tag-flags.c, src/lib-
3977
 
+       sieve/plugins/include/cmd-include.c, src/lib-sieve/plugins/include
3978
 
+       /ext-include-common.c, src/lib-sieve/plugins/relational/ext-
3979
 
+       relational-common.c, src/lib-sieve/plugins/vacation/cmd-vacation.c,
3980
 
+       src/lib-sieve/plugins/variables/ext-variables-arguments.c, src/lib-
3981
 
+       sieve/sieve-actions.c, src/lib-sieve/sieve-binary.c, src/lib-sieve
3982
 
+       /sieve-comparators.c, src/lib-sieve/sieve-validator.c, src/lib-sieve
3983
 
+       /sieve-validator.h, src/lib-sieve/tst-address.c:
3984
 
+       Made sure error messages do not print large erroneous values.
3985
 
+       [ea459c2b87c0]
3986
 
+
3987
 
+       * TODO, src/lib-sieve/sieve-parser.c, tests/compile/errors.svtest,
3988
 
+       tests/compile/errors/parser.sieve:
3989
 
+       Limited the depth of the AST and added tests to verify that it is
3990
 
+       resolved gracefully.
3991
 
+       [aa4d3069f079]
3992
 
+
3993
 
+2008-08-09  Stephan Bosch  <stephan@rename-it.nl>
3994
 
+
3995
 
+       * src/lib-sieve/sieve-limits.h, src/lib-sieve/sieve-parser.c,
3996
 
+       tests/compile/errors.svtest, tests/compile/errors/parser.sieve:
3997
 
+       Limited number of command arguments.
3998
 
+       [9a2fc3c9675d]
3999
 
+
4000
 
+       * src/lib-sieve/sieve-lexer.c:
4001
 
+       Made lexer use the (i_*) ctype.h functions.
4002
 
+       [51d06f8b3339]
4003
 
+
4004
 
+       * src/lib-sieve/sieve-lexer.c, src/lib-sieve/sieve-limits.h,
4005
 
+       tests/compile/errors.svtest, tests/compile/errors/lexer.sieve:
4006
 
+       Limited the length of identifiers.
4007
 
+       [aaca552f0561]
4008
 
+
4009
 
+       * TODO, src/lib-sieve/Makefile.am, src/lib-sieve/cmd-redirect.c, src
4010
 
+       /lib-sieve/sieve-address.c, src/lib-sieve/sieve-ast.c, src/lib-sieve
4011
 
+       /sieve-ast.h, src/lib-sieve/sieve-code.c, src/lib-sieve/sieve-
4012
 
+       common.h, src/lib-sieve/sieve-lexer.c, src/lib-sieve/sieve-limits.h,
4013
 
+       src/lib-sieve/sieve-parser.c, tests/compile/errors.svtest,
4014
 
+       tests/compile/errors/lexer.sieve:
4015
 
+       Enforced limits on string length and handled the finite nature of
4016
 
+       integers for number parsing and the construction of the AST.
4017
 
+       [317c332b2623]
4018
 
+
4019
 
+2008-08-06  Stephan Bosch  <stephan@rename-it.nl>
4020
 
+
4021
 
+       * src/lib-sieve/plugins/include/ext-include-binary.c, src/lib-
4022
 
+       sieve/plugins/include/ext-include-variables.c:
4023
 
+       Include: fixed bug in global variables referencing the main script.
4024
 
+       [b1c1779b1d4b]
4025
 
+
4026
 
+2008-08-05  Stephan Bosch  <stephan@rename-it.nl>
4027
 
+
4028
 
+       * src/lib-sieve/plugins/include/cmd-include.c, src/lib-
4029
 
+       sieve/plugins/include/ext-include-binary.c, src/lib-
4030
 
+       sieve/plugins/include/ext-include-binary.h, src/lib-
4031
 
+       sieve/plugins/include/ext-include-common.c, src/lib-
4032
 
+       sieve/plugins/include/ext-include-common.h, src/lib-
4033
 
+       sieve/plugins/include/ext-include-variables.c, src/lib-
4034
 
+       sieve/plugins/include/ext-include-variables.h,
4035
 
+       tests/extensions/include/variables.svtest:
4036
 
+       Include: symbol table for global variables now also includes
4037
 
+       locations for the first import/export of each known variable.
4038
 
+       [ba3785f991b9]
4039
 
+
4040
 
+       * src/lib-sieve/plugins/include/cmd-include.c, src/lib-
4041
 
+       sieve/plugins/include/ext-include-binary.c, src/lib-
4042
 
+       sieve/plugins/include/ext-include-binary.h, src/lib-
4043
 
+       sieve/plugins/include/ext-include-common.c, src/lib-
4044
 
+       sieve/plugins/include/ext-include-common.h:
4045
 
+       Include: included scripts are now referenced by an include_id in
4046
 
+       stead of the binary block id.
4047
 
+       [b67c51062eba]
4048
 
+
4049
 
+       * src/lib-sieve/sieve-interpreter.c, src/lib-sieve/sieve-validator.c:
4050
 
+       Forgot to implement free() event for validator and interpreter
4051
 
+       extensions.
4052
 
+       [e1f834c53a3d]
4053
 
+
4054
 
+       * src/lib-sieve/plugins/include/cmd-import.c, src/lib-
4055
 
+       sieve/plugins/include/ext-include-binary.c, src/lib-
4056
 
+       sieve/plugins/include/ext-include-binary.h, src/lib-
4057
 
+       sieve/plugins/include/ext-include-common.c, src/lib-
4058
 
+       sieve/plugins/include/ext-include-common.h, src/lib-
4059
 
+       sieve/plugins/include/ext-include-variables.c, src/lib-
4060
 
+       sieve/plugins/include/ext-include-variables.h, src/lib-
4061
 
+       sieve/plugins/include/ext-include.c, src/lib-sieve/plugins/variables
4062
 
+       /ext-variables-common.c, src/lib-sieve/plugins/variables/sieve-ext-
4063
 
+       variables.h, src/lib-sieve/sieve-binary-dumper.c, src/lib-sieve
4064
 
+       /sieve-binary-dumper.h, src/lib-sieve/sieve-extensions.h, src/lib-
4065
 
+       sieve/sieve-generator.c, src/testsuite/ext-testsuite.c,
4066
 
+       tests/extensions/include/errors.svtest,
4067
 
+       tests/extensions/include/errors/import-runtime.sieve,
4068
 
+       tests/extensions/include/errors/variables.sieve:
4069
 
+       Include: added symbol table to the binary for global variables.
4070
 
+       [d9518ecfeb23]
4071
 
+
4072
 
+       * README, TODO:
4073
 
+       Updated documentation.
4074
 
+       [54897b07b2da]
4075
 
+
4076
 
+2008-08-03  Stephan Bosch  <stephan@rename-it.nl>
4077
 
+
4078
 
+       * TODO:
4079
 
+       Minor TODO file revisions.
4080
 
+       [472b4c6dde9e]
4081
 
+
4082
 
+       * Makefile.am, tests/match-types/regex.svtest:
4083
 
+       Testsuite: added match values test for the :regex match
4084
 
+       [35384a182b33]
4085
 
+
4086
 
+       * TODO, src/lib-sieve/mcht-matches.c, src/lib-sieve/plugins/include
4087
 
+       /ext-include-common.c, src/lib-sieve/plugins/regex/mcht-regex.c, src
4088
 
+       /lib-sieve/sieve-match-types.c, src/lib-sieve/sieve-match-types.h,
4089
 
+       tests/extensions/variables/match.svtest, tests/match-
4090
 
+       types/matches.svtest:
4091
 
+       Fixed replacing match values only when a test succeeds.
4092
 
+       [dd371558d0fb]
4093
 
+
4094
 
+       * src/lib-sieve/sieve-interpreter.c, src/lib-sieve/sieve-
4095
 
+       interpreter.h, src/lib-sieve/sieve-validator.c, src/lib-sieve/sieve-
4096
 
+       validator.h:
4097
 
+       Upgraded validator and interpreter extension support to provide
4098
 
+       destruction notifications.
4099
 
+       [0ec7042e1ce5]
4100
 
+
4101
 
+2008-08-02  Stephan Bosch  <stephan@rename-it.nl>
4102
 
+
4103
 
+       * TODO:
4104
 
+       Include: found one issue.
4105
 
+       [37f5ac342261]
4106
 
+
4107
 
+       * src/lib-sieve/plugins/include/ext-include-common.c, src/testsuite
4108
 
+       /testsuite-common.c, src/testsuite/testsuite.c,
4109
 
+       tests/extensions/include/errors.svtest,
4110
 
+       tests/extensions/include/errors/circular-1.sieve,
4111
 
+       tests/extensions/include/errors/circular-2.sieve,
4112
 
+       tests/extensions/include/errors/circular-3.sieve,
4113
 
+       tests/extensions/include/errors/included/circular-one.sieve,
4114
 
+       tests/extensions/include/errors/included/circular-three-2.sieve,
4115
 
+       tests/extensions/include/errors/included/circular-three-3.sieve,
4116
 
+       tests/extensions/include/errors/included/circular-three.sieve,
4117
 
+       tests/extensions/include/errors/included/circular-two-2.sieve,
4118
 
+       tests/extensions/include/errors/included/circular-two.sieve,
4119
 
+       tests/extensions/include/included/variables-included1.sieve,
4120
 
+       tests/extensions/include/included/variables-included2.sieve,
4121
 
+       tests/extensions/include/included/variables-included3.sieve,
4122
 
+       tests/extensions/include/variables-included1.sieve,
4123
 
+       tests/extensions/include/variables-included2.sieve,
4124
 
+       tests/extensions/include/variables-included3.sieve:
4125
 
+       Testsuite: added circular include tests.
4126
 
+       [bfa2fb869c31]
4127
 
+
4128
 
+       * doc/rfc/draft-daboo-sieve-include-05.txt, src/lib-
4129
 
+       sieve/plugins/include/Makefile.am, src/lib-sieve/plugins/include
4130
 
+       /draft-daboo-sieve-include-05.txt, src/lib-sieve/plugins/include
4131
 
+       /include-error.sieve, src/lib-sieve/plugins/include/include-
4132
 
+       variables.sieve, src/lib-sieve/plugins/include/include-
4133
 
+       variables1.sieve, src/lib-sieve/plugins/include/include-
4134
 
+       variables2.sieve, src/lib-sieve/plugins/include/include-
4135
 
+       variables3.sieve, src/lib-sieve/plugins/include/include.sieve, src
4136
 
+       /lib-sieve/plugins/include/included1.sieve, src/lib-
4137
 
+       sieve/plugins/include/included2.sieve, src/lib-
4138
 
+       sieve/plugins/include/included3.sieve,
4139
 
+       tests/extensions/include/errors.svtest,
4140
 
+       tests/extensions/include/errors/generic.sieve:
4141
 
+       Include: cleaned up source directory.
4142
 
+       [525f4e7bd2ce]
4143
 
+
4144
 
+       * Makefile.am, src/lib-sieve/plugins/include/include-variables-
4145
 
+       error.sieve, src/lib-sieve/plugins/include/include-variables-
4146
 
+       error2.sieve, tests/extensions/include/errors.svtest,
4147
 
+       tests/extensions/include/errors/variables-inactive.sieve,
4148
 
+       tests/extensions/include/errors/variables.sieve:
4149
 
+       Testsuite: added compile error tests for the include extension.
4150
 
+       [7efaba3fb362]
4151
 
+
4152
 
+       * src/lib-sieve/plugins/copy/rfc3894.txt:
4153
 
+       Copy: forgot to remove RFC from old location.
4154
 
+       [4cd77c6931ad]
4155
 
+
4156
 
+       * doc/rfc/copy.rfc3894.txt:
4157
 
+       Copy: moved RFC to doc/rfc directory.
4158
 
+       [04dd13d1e194]
4159
 
+
4160
 
+       * doc/rfc/imap4flags.rfc5232.txt, src/lib-sieve/plugins/imapflags
4161
 
+       /draft-ietf-sieve-imapflags-05.txt, src/lib-sieve/plugins/imapflags
4162
 
+       /ext-imapflags.c:
4163
 
+       Imapflags: updated specification to RFC 5232.
4164
 
+       [f1f8c50c2d7e]
4165
 
+
4166
 
+       * TODO:
4167
 
+       Imapflags: found one new issue.
4168
 
+       [9f896bff4250]
4169
 
+
4170
 
+       * Makefile.am, src/lib-sieve/plugins/imapflags/ext-imapflags-common.c,
4171
 
+       src/lib-sieve/plugins/imapflags/ext-imapflags-common.h, src/lib-
4172
 
+       sieve/plugins/imapflags/tst-hasflag.c, src/lib-
4173
 
+       sieve/plugins/variables/ext-variables-arguments.c, src/lib-sieve
4174
 
+       /sieve-generator.c, tests/extensions/imapflags/hasflag.svtest,
4175
 
+       tests/extensions/imapflags/rfc.svtest:
4176
 
+       Imapflags: accidentally omitted support for multiple variables in
4177
 
+       the hasflag test.
4178
 
+       [b6602e8dd433]
4179
 
+
4180
 
+       * TODO, tests/extensions/variables/errors.svtest,
4181
 
+       tests/extensions/variables/errors/set.sieve,
4182
 
+       tests/extensions/variables/string.svtest:
4183
 
+       Testsuite: added new tests for the variables extension.
4184
 
+       [ff3d19af6da3]
4185
 
+
4186
 
+       * src/lib-sieve/sieve-lexer.c, src/lib-sieve/sieve-validator.c,
4187
 
+       tests/compile/trivial.sieve,
4188
 
+       tests/extensions/variables/errors.svtest:
4189
 
+       Fixed various case-sensitivily-related issues.
4190
 
+       [8d140a08e7d8]
4191
 
+
4192
 
+       * Makefile.am, src/lib-sieve/plugins/variables/ext-variables-
4193
 
+       arguments.c, tests/extensions/variables/errors.svtest,
4194
 
+       tests/extensions/variables/errors/namespace.sieve,
4195
 
+       tests/extensions/variables/errors/set.sieve:
4196
 
+       Variables: fixed various error handling issues.
4197
 
+       [eb93d4e65fce]
4198
 
+
4199
 
+       * src/lib-sieve/sieve-address.c:
4200
 
+       Fixed a warning.
4201
 
+       [5e651fda205f]
4202
 
+
4203
 
+2008-08-01  Stephan Bosch  <stephan@rename-it.nl>
4204
 
+
4205
 
+       * Makefile.am, src/lib-sieve/Makefile.am, src/lib-
4206
 
+       sieve/plugins/variables/Makefile.am, src/lib-sieve/plugins/variables
4207
 
+       /ext-variables.c:
4208
 
+       Fixed 'make dist' to produce a working tarball.
4209
 
+       [39a595dbbde4]
4210
 
+
4211
 
+       * src/lib-sieve/mcht-matches.c, src/lib-sieve/plugins/comparator-i
4212
 
+       -ascii-numeric/ext-cmp-i-ascii-numeric.c, tests/match-
4213
 
+       types/contains.svtest, tests/match-types/is.svtest, tests/match-
4214
 
+       types/matches.svtest, tests/match-types/relational.svtest:
4215
 
+       Testsuite: added test regarding matching the empty string and fixed
4216
 
+       an issue in the i;ascii-numeric comparator.
4217
 
+       [4817eca9348a]
4218
 
+
4219
 
+       * Makefile.am, TODO, src/lib-sieve/mcht-contains.c, src/lib-sieve
4220
 
+       /mcht-is.c, src/lib-sieve/mcht-matches.c, src/lib-
4221
 
+       sieve/plugins/regex/mcht-regex.c, src/lib-sieve/plugins/relational
4222
 
+       /mcht-count.c, src/lib-sieve/plugins/relational/mcht-value.c, src
4223
 
+       /lib-sieve/plugins/variables/tst-string.c, src/lib-sieve/sieve-
4224
 
+       match-types.h, src/lib-sieve/sieve-match.c,
4225
 
+       tests/extensions/variables/string.svtest:
4226
 
+       Variables: fixed :count issue for the string test.
4227
 
+       [fc0444f14dd1]
4228
 
+
4229
 
+       * TODO, tests/extensions/variables/basic.svtest,
4230
 
+       tests/extensions/variables/modifiers.svtest,
4231
 
+       tests/extensions/variables/string.svtest:
4232
 
+       Testsuite: added more tests for the variables extension and found
4233
 
+       one issue.
4234
 
+       [cd218e005c1e]
4235
 
+
4236
 
+       * Makefile.am, src/lib-sieve/ext-envelope.c, src/lib-sieve/tst-
4237
 
+       address.c, src/lib-sieve/tst-header.c,
4238
 
+       tests/extensions/variables/basic.svtest,
4239
 
+       tests/extensions/variables/match.svtest,
4240
 
+       tests/extensions/variables/modifiers.svtest, tests/match-
4241
 
+       types/contains.svtest:
4242
 
+       Testsuite: added RFC compliance tests for the variables extension
4243
 
+       and fixed use of wrong default comparator.
4244
 
+       [2246d563ad2d]
4245
 
+
4246
 
+       * src/lib-sieve/ext-encoded-character.c, src/lib-
4247
 
+       sieve/plugins/variables/ext-variables-arguments.c, src/lib-sieve
4248
 
+       /sieve-validator.c, tests/extensions/variables/quoting.svtest:
4249
 
+       Fixed bug in the order of default argument processing. Variable
4250
 
+       strings were evaluated befor constant strings, which is wrong.
4251
 
+       [6fa43c9bac62]
4252
 
+
4253
 
+       * src/lib-sieve/ext-envelope.c, src/lib-sieve/sieve-address.c,
4254
 
+       tests/extensions/envelope.svtest:
4255
 
+       Envelope: added more test and fixed source route parsing.
4256
 
+       [568d3af73d04]
4257
 
+
4258
 
+       * src/lib-sieve/ext-envelope.c, src/lib-sieve/sieve-address.c,
4259
 
+       tests/extensions/envelope.svtest:
4260
 
+       Envelope: fixed one bug in the path parsing (printfs active).
4261
 
+       [fbae4e8724ad]
4262
 
+
4263
 
+2008-07-31  Stephan Bosch  <stephan@rename-it.nl>
4264
 
+
4265
 
+       * TODO, doc/rfc/RFC Controversy.txt, src/lib-sieve/ext-envelope.c, src
4266
 
+       /lib-sieve/plugins/include/ext-include-binary.c, src/lib-
4267
 
+       sieve/plugins/subaddress/ext-subaddress.c, src/lib-sieve/sieve-
4268
 
+       address-parts.c, src/lib-sieve/sieve-address-parts.h, src/lib-sieve
4269
 
+       /sieve-address.c, src/lib-sieve/sieve-address.h, src/lib-sieve
4270
 
+       /sieve-common.h, tests/extensions/envelope.svtest,
4271
 
+       tests/testsuite.svtest:
4272
 
+       Envelope: working towards proper RFC compliance of forward/return-
4273
 
+       path parsing.
4274
 
+       [0d6138082c33]
4275
 
+
4276
 
+2008-07-29  Stephan Bosch  <stephan@rename-it.nl>
4277
 
+
4278
 
+       * src/lib-sieve/plugins/variables/ext-variables-arguments.c,
4279
 
+       tests/extensions/variables/basic.svtest:
4280
 
+       Variables: fixed RFC compliance issue regarding failing validation
4281
 
+       on unknown namespaces.
4282
 
+       [336904483e84]
4283
 
+
4284
 
+       * src/lib-sieve/plugins/variables/ext-variables-arguments.c,
4285
 
+       tests/extensions/variables/basic.svtest:
4286
 
+       Variables: fixed bug in variables substitution (RFC example failed
4287
 
+       during testing).
4288
 
+       [ccbfb44d427c]
4289
 
+
4290
 
+       * src/lib-sieve/plugins/variables/ext-variables-common.c,
4291
 
+       tests/extensions/variables/basic.svtest:
4292
 
+       Variables: fixed very significant bug in the variable scope
4293
 
+       implementation.
4294
 
+       [225f7cfd99c0]
4295
 
+
4296
 
+       * src/lib-sieve/sieve-binary.h:
4297
 
+       Removed superfluous include.
4298
 
+       [29e9b491cadf]
4299
 
+
4300
 
+       * tests/extensions/variables/basic.svtest:
4301
 
+       Testsuite: cleaned up basic varibles test case.
4302
 
+       [b8ac459bccec]
4303
 
+
4304
 
+       * Makefile.am, configure.in, src/testsuite/Makefile.am,
4305
 
+       src/testsuite/tests/address-parts/subaddress.svtest,
4306
 
+       src/testsuite/tests/comparators/core.svtest,
4307
 
+       src/testsuite/tests/compile/compile-examples.svtest,
4308
 
+       src/testsuite/tests/compile/compile.svtest,
4309
 
+       src/testsuite/tests/compile/errors.svtest,
4310
 
+       src/testsuite/tests/compile/errors/address-part.sieve,
4311
 
+       src/testsuite/tests/compile/errors/address.sieve,
4312
 
+       src/testsuite/tests/compile/errors/encoded-character.sieve,
4313
 
+       src/testsuite/tests/compile/errors/envelope.sieve,
4314
 
+       src/testsuite/tests/compile/errors/header.sieve,
4315
 
+       src/testsuite/tests/compile/errors/if.sieve,
4316
 
+       src/testsuite/tests/compile/errors/keep.sieve,
4317
 
+       src/testsuite/tests/compile/errors/require.sieve,
4318
 
+       src/testsuite/tests/compile/errors/size.sieve,
4319
 
+       src/testsuite/tests/compile/errors/stop.sieve,
4320
 
+       src/testsuite/tests/compile/redirect.sieve,
4321
 
+       src/testsuite/tests/compile/trivial.sieve, src/testsuite/tests
4322
 
+       /control-structures.svtest, src/testsuite/tests/exists.svtest,
4323
 
+       src/testsuite/tests/extensions/encoded-character.svtest,
4324
 
+       src/testsuite/tests/extensions/envelope.svtest,
4325
 
+       src/testsuite/tests/extensions/imapflags/basic.svtest,
4326
 
+       src/testsuite/tests/extensions/imapflags/rfc.svtest,
4327
 
+       src/testsuite/tests/extensions/include/variables-included1.sieve,
4328
 
+       src/testsuite/tests/extensions/include/variables-included2.sieve,
4329
 
+       src/testsuite/tests/extensions/include/variables-included3.sieve,
4330
 
+       src/testsuite/tests/extensions/include/variables.svtest,
4331
 
+       src/testsuite/tests/extensions/variables/basic.svtest,
4332
 
+       src/testsuite/tests/extensions/variables/match.svtest,
4333
 
+       src/testsuite/tests/header.svtest, src/testsuite/tests/lexer.svtest,
4334
 
+       src/testsuite/tests/match-types/contains.svtest, src/testsuite/tests
4335
 
+       /match-types/is.svtest, src/testsuite/tests/match-
4336
 
+       types/matches.svtest, src/testsuite/tests/match-
4337
 
+       types/relational.svtest, src/testsuite/tests/testsuite.svtest, tests
4338
 
+       /address-parts/subaddress.svtest, tests/comparators/core.svtest,
4339
 
+       tests/compile/compile-examples.svtest, tests/compile/compile.svtest,
4340
 
+       tests/compile/errors.svtest, tests/compile/errors/address-
4341
 
+       part.sieve, tests/compile/errors/address.sieve, tests/compile/errors
4342
 
+       /encoded-character.sieve, tests/compile/errors/envelope.sieve,
4343
 
+       tests/compile/errors/header.sieve, tests/compile/errors/if.sieve,
4344
 
+       tests/compile/errors/keep.sieve, tests/compile/errors/require.sieve,
4345
 
+       tests/compile/errors/size.sieve, tests/compile/errors/stop.sieve,
4346
 
+       tests/compile/redirect.sieve, tests/compile/trivial.sieve, tests
4347
 
+       /control-structures.svtest, tests/exists.svtest, tests/extensions
4348
 
+       /encoded-character.svtest, tests/extensions/envelope.svtest,
4349
 
+       tests/extensions/imapflags/basic.svtest,
4350
 
+       tests/extensions/imapflags/rfc.svtest, tests/extensions/include
4351
 
+       /variables-included1.sieve, tests/extensions/include/variables-
4352
 
+       included2.sieve, tests/extensions/include/variables-included3.sieve,
4353
 
+       tests/extensions/include/variables.svtest,
4354
 
+       tests/extensions/variables/basic.svtest,
4355
 
+       tests/extensions/variables/match.svtest, tests/header.svtest,
4356
 
+       tests/lexer.svtest, tests/match-types/contains.svtest, tests/match-
4357
 
+       types/is.svtest, tests/match-types/matches.svtest, tests/match-
4358
 
+       types/relational.svtest, tests/testsuite.svtest:
4359
 
+       Testsuite: moved tests directory to the root of the package.
4360
 
+       [bbd0d8bab632]
4361
 
+
4362
 
+       * doc/rfc/variables.rfc5229.txt, src/lib-
4363
 
+       sieve/plugins/variables/rfc5229.txt:
4364
 
+       Installed variables rfc in the doc/rfc directory.
4365
 
+       [785a600fb225]
4366
 
+
4367
 
+       * TODO, src/lib-sieve/ext-encoded-character.c,
4368
 
+       src/testsuite/tests/compile/errors/encoded-character.sieve,
4369
 
+       src/testsuite/tests/extensions/encoded-character.svtest:
4370
 
+       Encoded-character: resolved error reporting issue, added some syntax
4371
 
+       error tests and fixed some parsing bugs in the process.
4372
 
+       [9dd5079adbbe]
4373
 
+
4374
 
+       * TODO, src/lib-sieve/ext-encoded-character.c,
4375
 
+       src/testsuite/tests/compile/errors.svtest,
4376
 
+       src/testsuite/tests/compile/errors/address-part.sieve,
4377
 
+       src/testsuite/tests/compile/errors/encoded-character.sieve,
4378
 
+       src/testsuite/tests/compile/errors/envelope.sieve,
4379
 
+       src/testsuite/tests/compile/errors/keep.sieve,
4380
 
+       src/testsuite/tests/compile/errors/size.sieve,
4381
 
+       src/testsuite/tests/compile/errors/stop.sieve, src/testsuite/tests
4382
 
+       /control-structures.svtest:
4383
 
+       Testsuite: added compile error testcases and discovered one new
4384
 
+       issue.
4385
 
+       [1bf8cc2f7f10]
4386
 
+
4387
 
+       * TODO:
4388
 
+       Reprioritized TODO file.
4389
 
+       [1342d7920181]
4390
 
+
4391
 
+       * TODO, src/lib-sieve/plugins/include/ext-include-common.c, src/lib-
4392
 
+       sieve/plugins/variables/ext-variables-common.c, src/lib-
4393
 
+       sieve/plugins/variables/sieve-ext-variables.h:
4394
 
+       Variables: resolved issues in the scope implementation.
4395
 
+       [a3bcc26814b1]
4396
 
+
4397
 
+       * src/lib-sieve/plugins/include/cmd-include.c, src/lib-
4398
 
+       sieve/plugins/include/ext-include-common.c, src/lib-
4399
 
+       sieve/plugins/include/ext-include-common.h, src/lib-
4400
 
+       sieve/plugins/include/ext-include-variables.c, src/lib-
4401
 
+       sieve/plugins/include/ext-include-variables.h, src/lib-sieve/sieve-
4402
 
+       ast.c, src/lib-sieve/sieve-ast.h:
4403
 
+       Added proper extension support to AST object.
4404
 
+       [031f0a483697]
4405
 
+
4406
 
+2008-07-28  Stephan Bosch  <stephan@rename-it.nl>
4407
 
+
4408
 
+       * src/lib-sieve/sieve-error.c, src/lib-sieve/sieve-error.h, src/lib-
4409
 
+       sieve/sieve-validator.c, src/testsuite/tests/compile/errors.svtest,
4410
 
+       src/testsuite/tests/compile/errors/address.sieve,
4411
 
+       src/testsuite/tests/compile/errors/header.sieve,
4412
 
+       src/testsuite/tests/compile/errors/if.sieve,
4413
 
+       src/testsuite/tests/compile/errors/require.sieve, src/testsuite
4414
 
+       /testsuite-common.c:
4415
 
+       Testsuite: added a few more compile error test cases.
4416
 
+       [658fa458abd4]
4417
 
+
4418
 
+       * src/lib-sieve/sieve-error.c, src/lib-sieve/sieve-error.h,
4419
 
+       src/testsuite/Makefile.am,
4420
 
+       src/testsuite/tests/compile/errors.svtest,
4421
 
+       src/testsuite/tests/compile/errors/header.sieve,
4422
 
+       src/testsuite/tests/errors.svtest, src/testsuite/tests/header-
4423
 
+       errors.sieve, src/testsuite/testsuite-common.c, src/testsuite
4424
 
+       /testsuite-common.h, src/testsuite/testsuite.c, src/testsuite/tst-
4425
 
+       test-compile.c, src/testsuite/tst-test-error.c:
4426
 
+       Testsuite: completed support for error validation and added one test
4427
 
+       case.
4428
 
+       [b7ae709ef86e]
4429
 
+
4430
 
+       * src/testsuite/Makefile.am, src/testsuite/cmd-test-fail.c,
4431
 
+       src/testsuite/cmd-test-set.c, src/testsuite/ext-testsuite.c,
4432
 
+       src/testsuite/tests/errors.svtest, src/testsuite/tests/header-
4433
 
+       errors.sieve, src/testsuite/testsuite-common.h, src/testsuite/tst-
4434
 
+       test-compile.c, src/testsuite/tst-test-error.c:
4435
 
+       Testsuite: started support for error validation.
4436
 
+       [bef773d65f77]
4437
 
+
4438
 
+       * TODO, src/testsuite/Makefile.am, src/testsuite/tests/match-
4439
 
+       types/contains.svtest, src/testsuite/tests/match-types/is.svtest:
4440
 
+       Testsuite: marginally improved match-type tests.
4441
 
+       [444696f0d147]
4442
 
+
4443
 
+       * src/testsuite/Makefile.am:
4444
 
+       Added variables testcase to the testsuite.
4445
 
+       [2030448d3cd4]
4446
 
+
4447
 
+       * src/lib-sieve/mcht-matches.c, src/lib-sieve/sieve-match-types.c, src
4448
 
+       /lib-sieve/sieve-match-types.h,
4449
 
+       src/testsuite/tests/extensions/variables/match.svtest,
4450
 
+       src/testsuite/tests/lexer.svtest, src/testsuite/tests/match-
4451
 
+       types/matches.svtest:
4452
 
+       Fixed bugs in the :matches match type.
4453
 
+       [6305d80a9f22]
4454
 
+
4455
 
+       * src/lib-sieve/ext-encoded-character.c, src/testsuite/Makefile.am,
4456
 
+       src/testsuite/tests/extensions/encoded-character.svtest:
4457
 
+       Encoded-character: fixed a few bugs to properly match the examples
4458
 
+       provided in the RFC.
4459
 
+       [a320882164ec]
4460
 
+
4461
 
+2008-07-27  Stephan Bosch  <stephan@rename-it.nl>
4462
 
+
4463
 
+       * TODO, src/lib-sieve/tst-header.c:
4464
 
+       Added stripping of right white space from header content.
4465
 
+       [9a21206c0260]
4466
 
+
4467
 
+       * TODO:
4468
 
+       Updated TODO
4469
 
+       [8ec5db20d93b]
4470
 
+
4471
 
+       * src/testsuite/tests/extensions/envelope.svtest:
4472
 
+       Envelope: forgot to add new test case.
4473
 
+       [ce3a837f69f0]
4474
 
+
4475
 
+       * TODO, src/lib-sieve/ext-envelope.c, src/testsuite/Makefile.am:
4476
 
+       Envelope: <> return path now always matches as the empty string,
4477
 
+       regardless of the specified address part.
4478
 
+       [270b07d72782]
4479
 
+
4480
 
+       * TODO:
4481
 
+       Minor TODO file change.
4482
 
+       [9ba44410e26e]
4483
 
+
4484
 
+       * src/lib-sieve/ext-envelope.c, src/lib-sieve/tst-address.c:
4485
 
+       Forgot to adjust comment.
4486
 
+       [3560a09d215a]
4487
 
+
4488
 
+       * doc/rfc/RFC Controversy.txt:
4489
 
+       Updated documentation.
4490
 
+       [20da4decbf18]
4491
 
+
4492
 
+       * TODO, doc/rfc/RFC Controversy.txt, sieve/errors/envelope-
4493
 
+       errors.sieve, sieve/examples/elvey.sieve, src/lib-sieve/ext-
4494
 
+       envelope.c, src/lib-sieve/sieve-ast.c, src/lib-sieve/sieve-ast.h,
4495
 
+       src/lib-sieve/tst-address.c:
4496
 
+       Envelope: added compile-time envelope-part verification.
4497
 
+       [9a5d8cd44c16]
4498
 
+
4499
 
+       * doc/rfc/RFC Controversy.txt:
4500
 
+       Added RFC controversy file to log all matters that require
4501
 
+       clarification from RFC editors.
4502
 
+       [eaa9516bda0a]
4503
 
+
4504
 
+       * TODO:
4505
 
+       Restricted allowable headers for the address test.
4506
 
+       [b7212151acde]
4507
 
+
4508
 
+       * TODO, sieve/errors/address-errors.sieve, src/lib-sieve/tst-
4509
 
+       address.c, src/testsuite/tests/extensions/imapflags/rfc.svtest:
4510
 
+       Imapflags: forgot to add testcase file.
4511
 
+       [afe2b84e7719]
4512
 
+
4513
 
+       * src/lib-sieve/sieve-match.c:
4514
 
+       Disallowed extraction of key elements from key strings for match
4515
 
+       types for with that would not make sense.
4516
 
+       [ba9fe4253d74]
4517
 
+
4518
 
+       * TODO, src/lib-sieve/plugins/imapflags/ext-imapflags-common.c, src
4519
 
+       /lib-sieve/plugins/imapflags/tag-flags.c, src/lib-
4520
 
+       sieve/plugins/relational/mcht-count.c, src/testsuite/Makefile.am,
4521
 
+       src/testsuite/tests/extensions/imapflags/basic.svtest:
4522
 
+       Imapflags: resolved problem of hasflags encountering duplicate flags
4523
 
+       in flag lists contained in a variable.
4524
 
+       [df6023e12048]
4525
 
+
4526
 
+       * TODO, src/lib-sieve/ext-envelope.c, src/lib-sieve/mcht-contains.c,
4527
 
+       src/lib-sieve/mcht-is.c, src/lib-sieve/mcht-matches.c, src/lib-
4528
 
+       sieve/plugins/body/tst-body.c, src/lib-sieve/plugins/imapflags/tst-
4529
 
+       hasflag.c, src/lib-sieve/plugins/regex/mcht-regex.c, src/lib-
4530
 
+       sieve/plugins/relational/mcht-count.c, src/lib-
4531
 
+       sieve/plugins/relational/mcht-value.c, src/lib-
4532
 
+       sieve/plugins/variables/tst-string.c, src/lib-sieve/sieve-match-
4533
 
+       types.h, src/lib-sieve/sieve-match.c, src/lib-sieve/sieve-match.h,
4534
 
+       src/lib-sieve/tst-address.c, src/lib-sieve/tst-header.c,
4535
 
+       src/testsuite/Makefile.am,
4536
 
+       src/testsuite/tests/extensions/imapflags/basic.svtest:
4537
 
+       Imapflags: resolved string representation issue in hasflag.
4538
 
+       [9261c0d19ce3]
4539
 
+
4540
 
+       * TODO, src/lib-sieve/plugins/body/tst-body.c, src/lib-
4541
 
+       sieve/plugins/imapflags/tst-hasflag.c, src/lib-
4542
 
+       sieve/plugins/variables/tst-string.c, src/lib-sieve/sieve-match.c,
4543
 
+       src/lib-sieve/sieve-match.h, src/lib-sieve/tst-header.c,
4544
 
+       src/testsuite/tests/extensions/imapflags/basic.svtest:
4545
 
+       Resolved code duplication among commands that use comparators and
4546
 
+       match-types and found problems in the imapflags extension in the
4547
 
+       process.
4548
 
+       [662b8d662c89]
4549
 
+
4550
 
+2008-07-26  Stephan Bosch  <stephan@rename-it.nl>
4551
 
+
4552
 
+       * src/plugins/lda-sieve/lda-sieve-plugin.c:
4553
 
+       LDA-Sieve plugin: forgot to save the new binary when encountered a
4554
 
+       corrupt one.
4555
 
+       [d42d299f470b]
4556
 
+
4557
 
+       * TODO, src/lib-sieve/cmd-keep.c, src/lib-sieve/cmd-redirect.c, src
4558
 
+       /lib-sieve/ext-fileinto.c, src/lib-sieve/ext-reject.c, src/lib-sieve
4559
 
+       /sieve-actions.c, src/lib-sieve/sieve-binary.c, src/lib-sieve/sieve-
4560
 
+       binary.h, src/lib-sieve/sieve-code-dumper.c, src/lib-sieve/sieve-
4561
 
+       interpreter.c, src/lib-sieve/sieve-interpreter.h:
4562
 
+       Improved the handling corrupt binaries further for the action
4563
 
+       commands.
4564
 
+       [fd1d663f3b2c]
4565
 
+
4566
 
+2008-07-25  Stephan Bosch  <stephan@rename-it.nl>
4567
 
+
4568
 
+       * TODO, src/lib-sieve/Makefile.am, src/lib-sieve/ext-envelope.c, src
4569
 
+       /lib-sieve/mcht-contains.c, src/lib-sieve/mcht-is.c, src/lib-sieve
4570
 
+       /mcht-matches.c, src/lib-sieve/plugins/body/tst-body.c, src/lib-
4571
 
+       sieve/plugins/imapflags/ext-imapflags-common.c, src/lib-
4572
 
+       sieve/plugins/imapflags/ext-imapflags-common.h, src/lib-
4573
 
+       sieve/plugins/imapflags/tst-hasflag.c, src/lib-sieve/plugins/regex
4574
 
+       /mcht-regex.c, src/lib-sieve/plugins/relational/ext-relational-
4575
 
+       common.h, src/lib-sieve/plugins/relational/mcht-count.c, src/lib-
4576
 
+       sieve/plugins/relational/mcht-value.c, src/lib-
4577
 
+       sieve/plugins/variables/tst-string.c, src/lib-sieve/sieve-address-
4578
 
+       parts.c, src/lib-sieve/sieve-address-parts.h, src/lib-sieve/sieve-
4579
 
+       common.h, src/lib-sieve/sieve-match-types.c, src/lib-sieve/sieve-
4580
 
+       match-types.h, src/lib-sieve/sieve-match.c, src/lib-sieve/sieve-
4581
 
+       match.h, src/lib-sieve/tst-address.c, src/lib-sieve/tst-header.c,
4582
 
+       src/sieve-bin/sieve-test.c, src/testsuite/Makefile.am,
4583
 
+       src/testsuite/tests/control-structures.svtest, src/testsuite/tests
4584
 
+       /match-types/relational.svtest, src/testsuite/testsuite-common.c,
4585
 
+       src/testsuite/testsuite-common.h, src/testsuite/testsuite.c:
4586
 
+       Significantly improved handling of old/corrupt binaries and revised
4587
 
+       matching implementation in the process.
4588
 
+       [07f6bc2fe04b]
4589
 
+
4590
 
+       * src/lib-sieve/plugins/comparator-i-ascii-numeric/ext-cmp-i-ascii-
4591
 
+       numeric.c:
4592
 
+       Fixed extremely stupid bug in the i;ascii-numeric comparator.
4593
 
+       [f7df94b061ec]
4594
 
+
4595
 
+       * src/lib-sieve/sieve-binary.c, src/lib-sieve/sieve-interpreter.c,
4596
 
+       src/plugins/lda-sieve/lda-sieve-plugin.c, src/sieve-bin/sieve-
4597
 
+       exec.c, src/sieve-bin/sieve-test.c:
4598
 
+       Implemented graceful handling of corrupt binaries by the sieve lda
4599
 
+       plugin.
4600
 
+       [c300bab057a2]
4601
 
+
4602
 
+       * configure.in:
4603
 
+       Properly configured package name.
4604
 
+       [dfe8a1ecad3c]
4605
 
+
4606
 
+       * TODO, src/lib-sieve/cmd-discard.c, src/lib-sieve/cmd-keep.c, src
4607
 
+       /lib-sieve/cmd-redirect.c, src/lib-sieve/ext-envelope.c, src/lib-
4608
 
+       sieve/ext-fileinto.c, src/lib-sieve/ext-reject.c, src/lib-
4609
 
+       sieve/plugins/body/tst-body.c, src/lib-sieve/plugins/imapflags/cmd-
4610
 
+       addflag.c, src/lib-sieve/plugins/imapflags/cmd-removeflag.c, src
4611
 
+       /lib-sieve/plugins/imapflags/cmd-setflag.c, src/lib-
4612
 
+       sieve/plugins/imapflags/tst-hasflag.c, src/lib-sieve/plugins/include
4613
 
+       /cmd-include.c, src/lib-sieve/plugins/include/cmd-return.c, src/lib-
4614
 
+       sieve/plugins/vacation/cmd-vacation.c, src/lib-
4615
 
+       sieve/plugins/variables/cmd-set.c, src/lib-sieve/plugins/variables
4616
 
+       /tst-string.c, src/lib-sieve/sieve-code.c, src/lib-sieve/sieve-
4617
 
+       code.h, src/lib-sieve/sieve-commands.c, src/lib-sieve/sieve-
4618
 
+       interpreter.c, src/lib-sieve/sieve-interpreter.h, src/lib-sieve
4619
 
+       /sieve-result.c, src/lib-sieve/sieve-result.h, src/lib-sieve/sieve-
4620
 
+       types.h, src/lib-sieve/tst-address.c, src/lib-sieve/tst-exists.c,
4621
 
+       src/lib-sieve/tst-header.c, src/lib-sieve/tst-size.c, src/sieve-bin
4622
 
+       /sieve-exec.c, src/testsuite/cmd-test-fail.c, src/testsuite/cmd-
4623
 
+       test-set.c, src/testsuite/cmd-test.c, src/testsuite/tst-test-
4624
 
+       compile.c:
4625
 
+       Working towards improving the handling of currupt binaries: defined
4626
 
+       multiple exit codes for execution functions and defined trace macro
4627
 
+       for reporting binary corruptions.
4628
 
+       [10c30a4bd44a]
4629
 
+
4630
 
+       * TODO, src/testsuite/tests/extensions/include/variables-
4631
 
+       included1.sieve, src/testsuite/tests/extensions/include/variables-
4632
 
+       included2.sieve, src/testsuite/tests/extensions/include/variables-
4633
 
+       included3.sieve,
4634
 
+       src/testsuite/tests/extensions/include/variables.svtest:
4635
 
+       Testsuite: forgot to add test cases for include extension.
4636
 
+       [e3542907a783]
4637
 
+
4638
 
+       * TODO, src/lib-sieve/plugins/include/cmd-include.c, src/lib-
4639
 
+       sieve/plugins/include/ext-include-binary.c, src/lib-
4640
 
+       sieve/plugins/include/ext-include-common.c, src/lib-
4641
 
+       sieve/plugins/include/ext-include-common.h, src/lib-
4642
 
+       sieve/plugins/variables/ext-variables-operands.c, src/lib-sieve
4643
 
+       /sieve-script.c, src/lib-sieve/sieve-script.h,
4644
 
+       src/testsuite/Makefile.am, src/testsuite/testsuite.c:
4645
 
+       Fixed code emission for extension-defined variables and removed
4646
 
+       hardcoded paths from include extension.
4647
 
+       [c3dfcab426ca]
4648
 
+
4649
 
+       * TODO:
4650
 
+       Added future TODO item.
4651
 
+       [defad0db1bb4]
4652
 
+
4653
 
+       * TODO, src/lib-sieve/sieve-interpreter.h:
4654
 
+       Updated TODO and removed spurious FIXME.
4655
 
+       [477722eeaf09]
4656
 
+
4657
 
+       * README, src/testsuite/ext-testsuite.c:
4658
 
+       Updated documentation.
4659
 
+       [89e50989541a]
4660
 
+
4661
 
+       * .hgignore, src/lib-sieve/sieve-script.c, src/lib-sieve/sieve-
4662
 
+       script.h, src/testsuite/Makefile.am, src/testsuite/cmd-test-fail.c,
4663
 
+       src/testsuite/cmd-test-set.c, src/testsuite/cmd-test.c,
4664
 
+       src/testsuite/ext-testsuite.c, src/testsuite/tests/compile/compile-
4665
 
+       examples.svtest, src/testsuite/tests/compile/compile.svtest,
4666
 
+       src/testsuite/tests/compile/redirect.sieve,
4667
 
+       src/testsuite/tests/compile/trivial.sieve, src/testsuite/testsuite-
4668
 
+       common.h, src/testsuite/tst-test-compile.c:
4669
 
+       Testsuite: added test_compile command to test compilation of
4670
 
+       scripts.
4671
 
+       [e6846fc1dc11]
4672
 
+
4673
 
+2008-07-24  Stephan Bosch  <stephan@rename-it.nl>
4674
 
+
4675
 
+       * TODO, sieve/errors/out-address-errors.sieve, src/lib-sieve/sieve-
4676
 
+       address.c, src/lib-sieve/sieve-binary.c:
4677
 
+       Revised Sieve address validation functionality.
4678
 
+       [10abb0055a23]
4679
 
+
4680
 
+       * README, TODO, configure.in, src/lib-sieve/sieve-binary.c:
4681
 
+       Started using new str_new_const() function.
4682
 
+       [3fc4deedc23b]
4683
 
+
4684
 
+       * TODO, src/lib-sieve/cmd-redirect.c, src/lib-sieve/plugins/imapflags
4685
 
+       /cmd-addflag.c, src/lib-sieve/plugins/imapflags/cmd-removeflag.c,
4686
 
+       src/lib-sieve/plugins/imapflags/cmd-setflag.c, src/lib-
4687
 
+       sieve/plugins/imapflags/ext-imapflags-common.c, src/lib-
4688
 
+       sieve/plugins/imapflags/ext-imapflags-common.h, src/lib-
4689
 
+       sieve/plugins/imapflags/ext-imapflags.c, src/lib-
4690
 
+       sieve/plugins/imapflags/imapflags-errors.sieve, src/lib-
4691
 
+       sieve/plugins/imapflags/imapflags.sieve, src/lib-
4692
 
+       sieve/plugins/imapflags/tag-flags.c, src/lib-sieve/plugins/imapflags
4693
 
+       /tst-hasflag.c, src/lib-sieve/sieve-commands.h, src/lib-sieve/sieve-
4694
 
+       result.c, src/lib-sieve/sieve-result.h:
4695
 
+       Imapflags: improved handling of invalid flags.
4696
 
+       [4d45ccdd880b]
4697
 
+
4698
 
+       * TODO, src/lib-sieve/plugins/include/ext-include-binary.c, src/lib-
4699
 
+       sieve/plugins/include/ext-include-common.c, src/lib-sieve/sieve-
4700
 
+       ast.c, src/lib-sieve/sieve-binary.c, src/lib-sieve/sieve-
4701
 
+       interpreter.c, src/lib-sieve/sieve-result.c, src/lib-sieve/sieve-
4702
 
+       validator.c:
4703
 
+       Significantly improved pool allocation by checking --enable-debug
4704
 
+       warnings from dovecot.
4705
 
+       [4a5f60764e5f]
4706
 
+
4707
 
+       * src/lib-sieve/sieve-generator.c, src/lib-sieve/sieve-validator.c:
4708
 
+       Removed all legacy use of array_create().
4709
 
+       [f4bb043dc649]
4710
 
+
4711
 
+       * src/lib-sieve/sieve-lexer.c:
4712
 
+       Lexer: fixed repetitive string alloation problem.
4713
 
+       [14dd750dfeb8]
4714
 
+
4715
 
+2008-07-23  Stephan Bosch  <stephan@rename-it.nl>
4716
 
+
4717
 
+       * src/lib-sieve/sieve-binary.c:
4718
 
+       Fixed bug introduced by previous change.
4719
 
+       [e4db63d3e106]
4720
 
+
4721
 
+       * src/lib-sieve/Makefile.am, src/lib-sieve/plugins/variables/cmd-
4722
 
+       set.c, src/lib-sieve/sieve-actions.c, src/lib-sieve/sieve-address-
4723
 
+       parts.c, src/lib-sieve/sieve-binary.c, src/lib-sieve/sieve-binary.h,
4724
 
+       src/lib-sieve/sieve-code-dumper.c, src/lib-sieve/sieve-code.c, src
4725
 
+       /lib-sieve/sieve-common.h, src/lib-sieve/sieve-comparators.c, src
4726
 
+       /lib-sieve/sieve-extensions-private.h, src/lib-sieve/sieve-
4727
 
+       extensions.c, src/lib-sieve/sieve-match-types.c, src/testsuite
4728
 
+       /testsuite-common.c, src/testsuite/testsuite-objects.c:
4729
 
+       Reworked operand and operation binary coding functions.
4730
 
+       [a8f9c4a6c502]
4731
 
+
4732
 
+       * src/lib-sieve/cmd-discard.c, src/lib-sieve/cmd-if.c, src/lib-sieve
4733
 
+       /cmd-keep.c, src/lib-sieve/cmd-redirect.c, src/lib-sieve/cmd-
4734
 
+       require.c, src/lib-sieve/ext-envelope.c, src/lib-sieve/ext-
4735
 
+       fileinto.c, src/lib-sieve/ext-reject.c, src/lib-sieve/plugins/body
4736
 
+       /ext-body-common.c, src/lib-sieve/plugins/body/tst-body.c, src/lib-
4737
 
+       sieve/plugins/comparator-i-ascii-numeric/ext-cmp-i-ascii-numeric.c,
4738
 
+       src/lib-sieve/plugins/copy/ext-copy.c, src/lib-
4739
 
+       sieve/plugins/imapflags/cmd-addflag.c, src/lib-
4740
 
+       sieve/plugins/imapflags/cmd-removeflag.c, src/lib-
4741
 
+       sieve/plugins/imapflags/cmd-setflag.c, src/lib-
4742
 
+       sieve/plugins/imapflags/ext-imapflags-common.c, src/lib-
4743
 
+       sieve/plugins/imapflags/tag-flags.c, src/lib-sieve/plugins/imapflags
4744
 
+       /tst-hasflag.c, src/lib-sieve/plugins/include/cmd-include.c, src
4745
 
+       /lib-sieve/plugins/include/cmd-return.c, src/lib-
4746
 
+       sieve/plugins/include/ext-include-binary.c, src/lib-
4747
 
+       sieve/plugins/include/ext-include-common.c, src/lib-
4748
 
+       sieve/plugins/include/ext-include-variables.c, src/lib-
4749
 
+       sieve/plugins/include/ext-include.c, src/lib-sieve/plugins/regex
4750
 
+       /ext-regex.c, src/lib-sieve/plugins/relational/ext-relational.c, src
4751
 
+       /lib-sieve/plugins/subaddress/ext-subaddress.c, src/lib-
4752
 
+       sieve/plugins/vacation/cmd-vacation.c, src/lib-
4753
 
+       sieve/plugins/variables/cmd-set.c, src/lib-sieve/plugins/variables
4754
 
+       /ext-variables-common.c, src/lib-sieve/plugins/variables/ext-
4755
 
+       variables-common.h, src/lib-sieve/plugins/variables/ext-variables-
4756
 
+       modifiers.c, src/lib-sieve/plugins/variables/ext-variables-
4757
 
+       modifiers.h, src/lib-sieve/plugins/variables/ext-variables-
4758
 
+       operands.c, src/lib-sieve/plugins/variables/sieve-ext-variables.h,
4759
 
+       src/lib-sieve/plugins/variables/tst-string.c, src/lib-sieve/sieve-
4760
 
+       actions.h, src/lib-sieve/sieve-address-parts.c, src/lib-sieve/sieve-
4761
 
+       address-parts.h, src/lib-sieve/sieve-ast.c, src/lib-sieve/sieve-
4762
 
+       ast.h, src/lib-sieve/sieve-binary-dumper.c, src/lib-sieve/sieve-
4763
 
+       binary.c, src/lib-sieve/sieve-binary.h, src/lib-sieve/sieve-code.c,
4764
 
+       src/lib-sieve/sieve-code.h, src/lib-sieve/sieve-commands.c, src/lib-
4765
 
+       sieve/sieve-comparators.c, src/lib-sieve/sieve-comparators.h, src
4766
 
+       /lib-sieve/sieve-extensions-private.h, src/lib-sieve/sieve-
4767
 
+       extensions.c, src/lib-sieve/sieve-extensions.h, src/lib-sieve/sieve-
4768
 
+       generator.c, src/lib-sieve/sieve-generator.h, src/lib-sieve/sieve-
4769
 
+       interpreter.c, src/lib-sieve/sieve-interpreter.h, src/lib-sieve
4770
 
+       /sieve-match-types.c, src/lib-sieve/sieve-match-types.h, src/lib-
4771
 
+       sieve/sieve-message.c, src/lib-sieve/sieve-message.h, src/lib-sieve
4772
 
+       /sieve-objects.c, src/lib-sieve/sieve-objects.h, src/lib-sieve
4773
 
+       /sieve-result.c, src/lib-sieve/sieve-result.h, src/lib-sieve/sieve-
4774
 
+       validator.c, src/lib-sieve/sieve-validator.h, src/lib-sieve/tst-
4775
 
+       address.c, src/lib-sieve/tst-allof.c, src/lib-sieve/tst-anyof.c, src
4776
 
+       /lib-sieve/tst-exists.c, src/lib-sieve/tst-header.c, src/lib-sieve
4777
 
+       /tst-size.c, src/testsuite/cmd-test-fail.c, src/testsuite/cmd-test-
4778
 
+       set.c, src/testsuite/cmd-test.c, src/testsuite/testsuite-common.c,
4779
 
+       src/testsuite/testsuite-objects.c, src/testsuite/testsuite-
4780
 
+       objects.h:
4781
 
+       Fully substituted the use of extension ids with the use of the
4782
 
+       extension object itself.
4783
 
+       [0da758d61cad]
4784
 
+
4785
 
+       * src/lib-sieve/ext-encoded-character.c, src/lib-sieve/ext-envelope.c,
4786
 
+       src/lib-sieve/ext-fileinto.c, src/lib-sieve/ext-reject.c, src/lib-
4787
 
+       sieve/plugins/body/ext-body.c, src/lib-sieve/plugins/comparator-i
4788
 
+       -ascii-numeric/ext-cmp-i-ascii-numeric.c, src/lib-sieve/plugins/copy
4789
 
+       /ext-copy.c, src/lib-sieve/plugins/imapflags/ext-imapflags.c, src
4790
 
+       /lib-sieve/plugins/include/ext-include.c, src/lib-
4791
 
+       sieve/plugins/regex/ext-regex.c, src/lib-sieve/plugins/relational
4792
 
+       /ext-relational.c, src/lib-sieve/plugins/subaddress/ext-
4793
 
+       subaddress.c, src/lib-sieve/plugins/vacation/ext-vacation.c, src
4794
 
+       /lib-sieve/plugins/variables/ext-variables.c, src/lib-sieve/sieve-
4795
 
+       actions.c, src/lib-sieve/sieve-address-parts.c, src/lib-sieve/sieve-
4796
 
+       comparators.c, src/lib-sieve/sieve-extensions.c, src/lib-sieve
4797
 
+       /sieve-extensions.h, src/lib-sieve/sieve-match-types.c, src/lib-
4798
 
+       sieve/sieve-validator.c, src/testsuite/ext-testsuite.c:
4799
 
+       Made initially assigned extension id available directly from the
4800
 
+       const extension object itself.
4801
 
+       [3e237d753a2a]
4802
 
+
4803
 
+       * TODO, src/lib-sieve/sieve-error.c, src/lib-sieve/sieve-error.h:
4804
 
+       Reworked previous change into three elegant macros.
4805
 
+       [416c6954b998]
4806
 
+
4807
 
+2008-07-22  Stephan Bosch  <stephan@rename-it.nl>
4808
 
+
4809
 
+       * TODO, src/lib-sieve/plugins/include/ext-include-binary.c, src/lib-
4810
 
+       sieve/sieve-binary.c, src/lib-sieve/sieve-error.c, src/lib-sieve
4811
 
+       /sieve-error.h, src/lib-sieve/sieve-extensions.c, src/lib-sieve
4812
 
+       /sieve-script.c, src/plugins/lda-sieve/lda-sieve-plugin.c:
4813
 
+       Made utility functions for neatly handing system errors, warnings
4814
 
+       and notices.
4815
 
+       [8a116201d954]
4816
 
+
4817
 
+       * src/lib-sieve/tst-allof.c, src/lib-sieve/tst-anyof.c,
4818
 
+       src/testsuite/tests/control-structures.svtest:
4819
 
+       Testsuite: added tests for use of allof/anyof with a single test and
4820
 
+       optimized code generation.
4821
 
+       [971a8a94e8ab]
4822
 
+
4823
 
+       * TODO, src/testsuite/tests/header.svtest, src/testsuite/tests/match-
4824
 
+       types/contains.svtest:
4825
 
+       Testsuite: added test case for the header test and found one issue.
4826
 
+       [447d40a17ea0]
4827
 
+
4828
 
+       * src/lib-sieve/sieve-lexer.c, src/testsuite/Makefile.am,
4829
 
+       src/testsuite/tests/lexer.svtest:
4830
 
+       Testsuite: added lexer string scan comparison test and fixed lexer
4831
 
+       bug in the process.
4832
 
+       [1bab36c85b54]
4833
 
+
4834
 
+2008-07-21  Stephan Bosch  <stephan@rename-it.nl>
4835
 
+
4836
 
+       * TODO, src/testsuite/tests/control-structures.svtest:
4837
 
+       Testsuite: added some control structure tests involving nesting.
4838
 
+       [46a2df6cafe4]
4839
 
+
4840
 
+       * TODO, src/lib-sieve/tst-exists.c, src/testsuite/Makefile.am,
4841
 
+       src/testsuite/tests/exists.svtest, src/testsuite/testsuite-
4842
 
+       objects.c:
4843
 
+       Testsuite: added tests for 'exists' test and fixed a semantic error
4844
 
+       in the 'exists' test.
4845
 
+       [ce5660cb5dbf]
4846
 
+
4847
 
+       * TODO, src/lib-sieve/ext-envelope.c, src/lib-sieve/sieve-address-
4848
 
+       parts.c, src/testsuite/tests/testsuite.svtest, src/testsuite
4849
 
+       /testsuite-objects.c:
4850
 
+       Testsuite: tested handling of teststuite envelope environment and
4851
 
+       fixed bugs in the envelope test in the process.
4852
 
+       [ff0f9c67a106]
4853
 
+
4854
 
+       * src/testsuite/Makefile.am, src/testsuite/tests/address-
4855
 
+       parts/subaddress.svtest, src/testsuite/testsuite-common.c:
4856
 
+       Testsuite: added test case for subadress extension.
4857
 
+       [21061d5f3422]
4858
 
+
4859
 
+       * Makefile.am, TODO, configure.in, src/Makefile.am,
4860
 
+       src/testsuite/Makefile.am, src/testsuite/tests/testsuite.svtest,
4861
 
+       src/testsuite/testsuite-common.c, src/testsuite/testsuite-common.h,
4862
 
+       src/testsuite/testsuite.c:
4863
 
+       Coupled testsuite to 'make test'.
4864
 
+       [36ab72963cd1]
4865
 
+
4866
 
+       * sieve/tests/encoded-character.sieve, src/lib-sieve/cmd-if.c, src
4867
 
+       /lib-sieve/cmd-redirect.c, src/lib-sieve/ext-encoded-character.c,
4868
 
+       src/lib-sieve/ext-envelope.c, src/lib-sieve/ext-fileinto.c, src/lib-
4869
 
+       sieve/ext-reject.c, src/lib-sieve/sieve-interpreter.c, src/lib-sieve
4870
 
+       /tst-address.c, src/lib-sieve/tst-allof.c, src/lib-sieve/tst-
4871
 
+       anyof.c, src/lib-sieve/tst-exists.c, src/lib-sieve/tst-header.c, src
4872
 
+       /lib-sieve/tst-not.c, src/lib-sieve/tst-size.c:
4873
 
+       Cleaned up test and core extension implementations.
4874
 
+       [5df6769ad854]
4875
 
+
4876
 
+       * src/lib-sieve/cmd-discard.c, src/lib-sieve/cmd-if.c, src/lib-sieve
4877
 
+       /cmd-keep.c, src/lib-sieve/cmd-redirect.c, src/lib-sieve/cmd-
4878
 
+       require.c:
4879
 
+       Cleaned up command implementations.
4880
 
+       [837769563332]
4881
 
+
4882
 
+       * src/lib-sieve/sieve-script-private.h, src/lib-sieve/sieve-script.c:
4883
 
+       Fixed handling of script files that are in fact symbolic links.
4884
 
+       [fd9003533d28]
4885
 
+
4886
 
+       * src/lib-sieve/sieve-binary.c:
4887
 
+       Fixed bug in binary created without a corresponding script object.
4888
 
+       [9560bfd8e2e5]
4889
 
+
4890
 
+       * TODO, src/lib-sieve/sieve-binary.c, src/lib-sieve/sieve-error.c, src
4891
 
+       /lib-sieve/sieve-error.h, src/lib-sieve/sieve-script.c:
4892
 
+       Reversed stat() and open() on two occasions to make retrieved stat
4893
 
+       information guaranteed to be valid for the opened file and added
4894
 
+       error handling for various close() system calls.
4895
 
+       [b04c29c4ac90]
4896
 
+
4897
 
+       * TODO:
4898
 
+       Updated TODO list.
4899
 
+       [bab521877ded]
4900
 
+
4901
 
+       * src/lib-sieve/plugins/regex/ext-regex.c, src/lib-sieve/plugins/regex
4902
 
+       /mcht-regex.c, src/lib-sieve/plugins/variables/cmd-set.c, src/lib-
4903
 
+       sieve/plugins/variables/ext-variables-common.c, src/lib-
4904
 
+       sieve/plugins/variables/ext-variables-modifiers.c, src/lib-
4905
 
+       sieve/plugins/variables/ext-variables-name.c, src/lib-
4906
 
+       sieve/plugins/variables/ext-variables-name.h, src/lib-
4907
 
+       sieve/plugins/variables/ext-variables.c, src/lib-sieve/sieve-
4908
 
+       actions.c:
4909
 
+       Removed various unnecessary includes of <ctype.h> and replaced yey
4910
 
+       another toupper() with its i_* equivalent.
4911
 
+       [2e1963c29390]
4912
 
+
4913
 
+       * src/lib-sieve/plugins/comparator-i-ascii-numeric/ext-cmp-i-ascii-
4914
 
+       numeric.c, src/lib-sieve/plugins/variables/ext-variables-name.c:
4915
 
+       Removed direct use of isdigit, isalpha and isalnum and replaced
4916
 
+       these with their dovecot i_* equivalents to prevent problems on some
4917
 
+       systems.
4918
 
+       [732c5001ccb5]
4919
 
+
4920
 
+       * TODO:
4921
 
+       Updated TODO.
4922
 
+       [47c0a9d219b6]
4923
 
+
4924
 
+       * src/lib-sieve/plugins/variables/Makefile.am, src/lib-
4925
 
+       sieve/plugins/variables/cmd-set.c, src/lib-sieve/plugins/variables
4926
 
+       /ext-variables-common.c, src/lib-sieve/plugins/variables/ext-
4927
 
+       variables-common.h, src/lib-sieve/plugins/variables/ext-variables-
4928
 
+       modifiers.c, src/lib-sieve/plugins/variables/ext-variables-
4929
 
+       modifiers.h, src/lib-sieve/plugins/variables/ext-variables.c, src
4930
 
+       /lib-sieve/plugins/variables/sieve-ext-variables.h, src/lib-
4931
 
+       sieve/plugins/variables/variables-match.sieve,
4932
 
+       src/testsuite/tests/extensions/variables/basic.svtest:
4933
 
+       Variables: made set modifiers descendants of the sieve object too.
4934
 
+       [6c31299662d8]
4935
 
+
4936
 
+2008-07-20  Stephan Bosch  <stephan@rename-it.nl>
4937
 
+
4938
 
+       * src/lib-sieve/sieve-code.c, src/lib-sieve/sieve-objects.c,
4939
 
+       src/testsuite/testsuite-common.c, src/testsuite/testsuite-common.h,
4940
 
+       src/testsuite/testsuite-objects.c, src/testsuite/testsuite-
4941
 
+       objects.h:
4942
 
+       Testsuite: made testsuite objects a descendant from sieve objects.
4943
 
+       [12a346d25711]
4944
 
+
4945
 
+       * TODO, src/lib-sieve/plugins/regex/ext-regex.c, src/lib-sieve/sieve-
4946
 
+       actions.c, src/lib-sieve/sieve-address-parts.c, src/lib-sieve/sieve-
4947
 
+       comparators.c, src/lib-sieve/sieve-match-types.c, src/lib-sieve
4948
 
+       /sieve-validator.c, src/lib-sieve/sieve-validator.h:
4949
 
+       Removed remaining code duplication among comparators, match types
4950
 
+       and address parts.
4951
 
+       [1654a241fa56]
4952
 
+
4953
 
+       * TODO:
4954
 
+       Updated TODO list.
4955
 
+       [8292d75ce253]
4956
 
+
4957
 
+       * src/lib-sieve/plugins/copy/ext-copy.c, src/lib-
4958
 
+       sieve/plugins/imapflags/ext-imapflags-common.h, src/lib-
4959
 
+       sieve/plugins/imapflags/ext-imapflags.c, src/lib-
4960
 
+       sieve/plugins/imapflags/tag-flags.c, src/lib-sieve/sieve-actions.c,
4961
 
+       src/lib-sieve/sieve-actions.h, src/lib-sieve/sieve-address-parts.h,
4962
 
+       src/lib-sieve/sieve-code.c, src/lib-sieve/sieve-code.h, src/lib-
4963
 
+       sieve/sieve-comparators.h, src/lib-sieve/sieve-match-types.h, src
4964
 
+       /lib-sieve/sieve-objects.c, src/lib-sieve/sieve-objects.h:
4965
 
+       Made side effects sieve objects too.
4966
 
+       [81b6c6a65f86]
4967
 
+
4968
 
+       * src/lib-sieve/Makefile.am, src/lib-sieve/cmp-i-ascii-casemap.c, src
4969
 
+       /lib-sieve/cmp-i-octet.c, src/lib-sieve/mcht-contains.c, src/lib-
4970
 
+       sieve/mcht-is.c, src/lib-sieve/mcht-matches.c, src/lib-
4971
 
+       sieve/plugins/comparator-i-ascii-numeric/ext-cmp-i-ascii-numeric.c,
4972
 
+       src/lib-sieve/plugins/regex/ext-regex-common.c, src/lib-
4973
 
+       sieve/plugins/regex/mcht-regex.c, src/lib-sieve/plugins/relational
4974
 
+       /ext-relational-common.c, src/lib-sieve/plugins/relational/mcht-
4975
 
+       count.c, src/lib-sieve/plugins/relational/mcht-value.c, src/lib-
4976
 
+       sieve/plugins/subaddress/ext-subaddress.c, src/lib-sieve/sieve-
4977
 
+       address-parts.c, src/lib-sieve/sieve-address-parts.h, src/lib-sieve
4978
 
+       /sieve-common.h, src/lib-sieve/sieve-comparators.c, src/lib-sieve
4979
 
+       /sieve-comparators.h, src/lib-sieve/sieve-match-types.c, src/lib-
4980
 
+       sieve/sieve-match-types.h, src/lib-sieve/sieve-objects.c, src/lib-
4981
 
+       sieve/sieve-objects.h:
4982
 
+       Introduced the concept of a sieve object to merge the coding of
4983
 
+       comparators, match types, address parts and other objects that might
4984
 
+       need to be represented in byte code (removes lots of code
4985
 
+       duplication).
4986
 
+       [344eaae8693c]
4987
 
+
4988
 
+2008-07-19  Stephan Bosch  <stephan@rename-it.nl>
4989
 
+
4990
 
+       * TODO, src/lib-sieve/cmp-i-octet.c, src/lib-sieve/mcht-contains.c,
4991
 
+       src/lib-sieve/mcht-is.c, src/lib-sieve/mcht-matches.c, src/lib-
4992
 
+       sieve/plugins/regex/Makefile.am, src/lib-sieve/plugins/regex/ext-
4993
 
+       regex-common.c, src/lib-sieve/plugins/regex/ext-regex-common.h, src
4994
 
+       /lib-sieve/plugins/regex/ext-regex.c, src/lib-sieve/plugins/regex
4995
 
+       /mcht-regex.c, src/lib-sieve/plugins/relational/ext-relational-
4996
 
+       common.c, src/lib-sieve/plugins/relational/ext-relational-common.h,
4997
 
+       src/lib-sieve/plugins/relational/ext-relational.c, src/lib-
4998
 
+       sieve/plugins/relational/mcht-count.c, src/lib-
4999
 
+       sieve/plugins/relational/mcht-value.c, src/lib-sieve/sieve-
5000
 
+       comparators.c, src/lib-sieve/sieve-comparators.h, src/lib-sieve
5001
 
+       /sieve-match-types.c, src/lib-sieve/sieve-match-types.h:
5002
 
+       Revised extension support for match-types.
5003
 
+       [a6bf1b1c8a2b]
5004
 
+
5005
 
+       * src/lib-sieve/Makefile.am, src/lib-sieve/cmp-i-ascii-casemap.c, src
5006
 
+       /lib-sieve/cmp-i-octet.c, src/lib-sieve/sieve-comparators.c, src
5007
 
+       /lib-sieve/sieve-comparators.h:
5008
 
+       Cleaned up comparator implementation.
5009
 
+       [8976941d215c]
5010
 
+
5011
 
+       * TODO, src/lib-sieve/plugins/comparator-i-ascii-numeric/ext-cmp-i
5012
 
+       -ascii-numeric.c, src/lib-sieve/sieve-comparators.c, src/lib-sieve
5013
 
+       /sieve-comparators.h, src/testsuite/tests/comparators/core.svtest:
5014
 
+       Revised extension support for comparators.
5015
 
+       [29676b9e16c2]
5016
 
+
5017
 
+2008-07-18  Stephan Bosch  <stephan@rename-it.nl>
5018
 
+
5019
 
+       * src/lib-sieve/sieve-comparators.c:
5020
 
+       Fixed stupid bug in the match-type context validation.
5021
 
+       [e67e5024a970]
5022
 
+
5023
 
+       * src/lib-sieve/Makefile.am, src/lib-sieve/sieve-ast.c, src/lib-sieve
5024
 
+       /sieve-ast.h, src/lib-sieve/sieve-common.h, src/lib-sieve/sieve-
5025
 
+       error.c, src/lib-sieve/sieve-error.h, src/lib-sieve/sieve-lexer.c,
5026
 
+       src/lib-sieve/sieve-parser.c, src/lib-sieve/sieve-result.c, src/lib-
5027
 
+       sieve/sieve-script-private.h, src/lib-sieve/sieve-script.c, src/lib-
5028
 
+       sieve/sieve-types.h, src/lib-sieve/sieve.h:
5029
 
+       Made error reporting cleaner by avoiding the scriptname of the main
5030
 
+       script and indicating that the printed numbers are in fact source
5031
 
+       code lines.
5032
 
+       [2c5ae7a67d28]
5033
 
+
5034
 
+       * src/lib-sieve/sieve-validator.h:
5035
 
+       Fixed warnings caused by remaining spurious inline definitions in
5036
 
+       sieve-validator.h
5037
 
+       [bfc24ba04381]
5038
 
+
5039
 
+2008-07-17  Stephan Bosch  <stephan@rename-it.nl>
5040
 
+
5041
 
+       * src/lib-sieve/sieve-lexer.c, src/lib-sieve/sieve-lexer.h, src/lib-
5042
 
+       sieve/sieve-parser.c, src/lib-sieve/sieve-parser.h, src/lib-
5043
 
+       sieve/sieve.c, src/lib-sieve/sieve.h, src/plugins/lda-sieve/lda-
5044
 
+       sieve-plugin.c:
5045
 
+       Code cleanup: parser, lexer, lda-plugin and main interface.
5046
 
+       [d5ca488d55b7]
5047
 
+
5048
 
+       * TODO:
5049
 
+       Updated TODO.
5050
 
+       [c44e8d20b130]
5051
 
+
5052
 
+2008-07-16  Stephan Bosch  <stephan@rename-it.nl>
5053
 
+
5054
 
+       * INSTALL:
5055
 
+       Update INSTALL file.
5056
 
+       [c0acf033f79d]
5057
 
+
5058
 
+       * README, TODO:
5059
 
+       Updated documentation.
5060
 
+       [3f2415b96676]
5061
 
+
5062
 
+       * TODO, src/lib-sieve/cmd-discard.c, src/lib-sieve/cmd-keep.c, src
5063
 
+       /lib-sieve/cmd-redirect.c, src/lib-sieve/ext-fileinto.c, src/lib-
5064
 
+       sieve/ext-reject.c, src/lib-sieve/plugins/vacation/cmd-vacation.c,
5065
 
+       src/lib-sieve/sieve-actions.c, src/lib-sieve/sieve-actions.h, src
5066
 
+       /lib-sieve/sieve-binary.c, src/lib-sieve/sieve-interpreter.c, src
5067
 
+       /lib-sieve/sieve-interpreter.h, src/lib-sieve/sieve-result.c, src
5068
 
+       /lib-sieve/sieve-result.h:
5069
 
+       Made runtime errors for action conflicts more user-friendly by
5070
 
+       adding sourcecode line numbers.
5071
 
+       [5dfc5676bd6f]
5072
 
+
5073
 
+       * src/lib-sieve/cmd-discard.c, src/lib-sieve/cmd-if.c, src/lib-sieve
5074
 
+       /cmd-keep.c, src/lib-sieve/cmd-redirect.c, src/lib-sieve/cmd-
5075
 
+       require.c, src/lib-sieve/ext-envelope.c, src/lib-sieve/ext-
5076
 
+       fileinto.c, src/lib-sieve/ext-reject.c, src/lib-sieve/plugins/body
5077
 
+       /tst-body.c, src/lib-sieve/plugins/copy/ext-copy.c, src/lib-
5078
 
+       sieve/plugins/imapflags/cmd-addflag.c, src/lib-
5079
 
+       sieve/plugins/imapflags/cmd-removeflag.c, src/lib-
5080
 
+       sieve/plugins/imapflags/cmd-setflag.c, src/lib-
5081
 
+       sieve/plugins/imapflags/tag-flags.c, src/lib-sieve/plugins/imapflags
5082
 
+       /tst-hasflag.c, src/lib-sieve/plugins/include/cmd-include.c, src
5083
 
+       /lib-sieve/plugins/include/cmd-return.c, src/lib-
5084
 
+       sieve/plugins/include/ext-include-common.c, src/lib-
5085
 
+       sieve/plugins/include/ext-include-common.h, src/lib-
5086
 
+       sieve/plugins/vacation/cmd-vacation.c, src/lib-
5087
 
+       sieve/plugins/variables/cmd-set.c, src/lib-sieve/plugins/variables
5088
 
+       /ext-variables-arguments.c, src/lib-sieve/plugins/variables/tst-
5089
 
+       string.c, src/lib-sieve/sieve-actions.c, src/lib-sieve/sieve-
5090
 
+       actions.h, src/lib-sieve/sieve-address-parts.c, src/lib-sieve/sieve-
5091
 
+       code.c, src/lib-sieve/sieve-code.h, src/lib-sieve/sieve-commands.c,
5092
 
+       src/lib-sieve/sieve-commands.h, src/lib-sieve/sieve-common.h, src
5093
 
+       /lib-sieve/sieve-comparators.c, src/lib-sieve/sieve-generator.c, src
5094
 
+       /lib-sieve/sieve-generator.h, src/lib-sieve/sieve-match-types.c, src
5095
 
+       /lib-sieve/sieve-result.c, src/lib-sieve/sieve-result.h, src/lib-
5096
 
+       sieve/tst-address.c, src/lib-sieve/tst-allof.c, src/lib-sieve/tst-
5097
 
+       anyof.c, src/lib-sieve/tst-exists.c, src/lib-sieve/tst-header.c, src
5098
 
+       /lib-sieve/tst-not.c, src/lib-sieve/tst-size.c, src/testsuite/cmd-
5099
 
+       test-fail.c, src/testsuite/cmd-test-set.c, src/testsuite/cmd-test.c,
5100
 
+       src/testsuite/testsuite-objects.c:
5101
 
+       Cleaned up generator code and added emission of source line
5102
 
+       positions for all actions.
5103
 
+       [d60e232af73e]
5104
 
+
5105
 
+2008-07-14  Stephan Bosch  <stephan@rename-it.nl>
5106
 
+
5107
 
+       * TODO, sieve/tests/stop.sieve, src/lib-sieve/ext-reject.c, src/lib-
5108
 
+       sieve/plugins/vacation/cmd-vacation.c, src/lib-sieve/sieve-parser.c:
5109
 
+       Resolved various small issues.
5110
 
+       [dd844326cd20]
5111
 
+
5112
 
+       * TODO, src/lib-sieve/plugins/include/ext-include-common.c, src/lib-
5113
 
+       sieve/sieve-interpreter.c, src/lib-sieve/sieve-interpreter.h, src
5114
 
+       /lib-sieve/sieve.c, src/lib-sieve/sieve.h, src/plugins/lda-sieve
5115
 
+       /lda-sieve-plugin.c, src/sieve-bin/sieve-exec.c, src/sieve-bin
5116
 
+       /sieve-test.c, src/testsuite/testsuite.c:
5117
 
+       Removed last significant printf()s from library code.
5118
 
+       [663bb4cf98d8]
5119
 
+
5120
 
+       * sieve/tests/actions.sieve, src/lib-sieve/cmd-redirect.c, src/lib-
5121
 
+       sieve/ext-encoded-character.c, src/lib-sieve/plugins/copy/ext-
5122
 
+       copy.c, src/lib-sieve/plugins/vacation/cmd-vacation.c, src/lib-sieve
5123
 
+       /sieve-address.c, src/lib-sieve/sieve-address.h, src/lib-sieve
5124
 
+       /sieve-ast.c, src/lib-sieve/sieve-ast.h, src/lib-sieve/sieve-
5125
 
+       result.c:
5126
 
+       Added address normalization to prevent redirect action duplicates.
5127
 
+       [41e894bd5adb]
5128
 
+
5129
 
+       * src/lib-sieve/sieve-actions.c:
5130
 
+       Made "INBOX" folder name case-insensitive.
5131
 
+       [ad20dac29faf]
5132
 
+
5133
 
+       * TODO, src/lib-sieve/cmd-discard.c, src/lib-sieve/cmd-redirect.c, src
5134
 
+       /lib-sieve/ext-reject.c, src/lib-sieve/plugins/copy/ext-copy.c, src
5135
 
+       /lib-sieve/plugins/imapflags/imapflags-implicit.sieve, src/lib-
5136
 
+       sieve/plugins/imapflags/tag-flags.c, src/lib-sieve/plugins/vacation
5137
 
+       /cmd-vacation.c, src/lib-sieve/sieve-actions.c, src/lib-sieve/sieve-
5138
 
+       actions.h, src/lib-sieve/sieve-ast.h, src/lib-sieve/sieve-common.h,
5139
 
+       src/lib-sieve/sieve-result.c, src/lib-sieve/sieve-result.h, src/lib-
5140
 
+       sieve/sieve-validator.c, src/lib-sieve/sieve.c, src/lib-
5141
 
+       sieve/sieve.h, src/sieve-bin/sieve-test.c,
5142
 
+       src/testsuite/testsuite.c:
5143
 
+       Built result print functions thus removing various printf()s.
5144
 
+       [ab0569f04717]
5145
 
+
5146
 
+       * TODO, src/lib-sieve/plugins/include/ext-include-binary.c, src/lib-
5147
 
+       sieve/plugins/include/ext-include-variables.c, src/lib-
5148
 
+       sieve/plugins/variables/ext-variables-arguments.c, src/lib-sieve
5149
 
+       /sieve-interpreter.c, src/lib-sieve/sieve-lexer.c, src/lib-sieve
5150
 
+       /sieve-result.c, src/sieve-bin/sieve-exec.c:
5151
 
+       Removed various printf()s.
5152
 
+       [8b83101ed51a]
5153
 
+
5154
 
+       * README, TODO, src/lib-sieve/plugins/imapflags/ext-imapflags.c, src
5155
 
+       /lib-sieve/plugins/imapflags/imapflags.sieve, src/lib-
5156
 
+       sieve/plugins/imapflags/tag-flags.c, src/lib-sieve/sieve-result.c:
5157
 
+       Implemented support for side-effects to implicit keep and finished
5158
 
+       the imapflags extension.
5159
 
+       [c0b959cfdf01]
5160
 
+
5161
 
+       * src/lib-sieve/ext-encoded-character.c, src/lib-sieve/ext-envelope.c,
5162
 
+       src/lib-sieve/ext-fileinto.c, src/lib-sieve/ext-reject.c, src/lib-
5163
 
+       sieve/plugins/body/ext-body.c, src/lib-sieve/plugins/comparator-i
5164
 
+       -ascii-numeric/ext-cmp-i-ascii-numeric.c, src/lib-sieve/plugins/copy
5165
 
+       /ext-copy.c, src/lib-sieve/plugins/imapflags/ext-imapflags.c, src
5166
 
+       /lib-sieve/plugins/include/ext-include-common.c, src/lib-
5167
 
+       sieve/plugins/include/ext-include-common.h, src/lib-
5168
 
+       sieve/plugins/include/ext-include.c, src/lib-sieve/plugins/regex
5169
 
+       /ext-regex.c, src/lib-sieve/plugins/relational/ext-relational.c, src
5170
 
+       /lib-sieve/plugins/subaddress/ext-subaddress.c, src/lib-
5171
 
+       sieve/plugins/vacation/ext-vacation.c, src/lib-
5172
 
+       sieve/plugins/variables/ext-variables.c, src/lib-sieve/sieve-
5173
 
+       actions.c, src/lib-sieve/sieve-address-parts.c, src/lib-sieve/sieve-
5174
 
+       comparators.c, src/lib-sieve/sieve-extensions.c, src/lib-sieve
5175
 
+       /sieve-extensions.h, src/lib-sieve/sieve-interpreter.c, src/lib-
5176
 
+       sieve/sieve-match-types.c, src/testsuite/ext-testsuite.c:
5177
 
+       Previous change in extension interface for implicit side effect
5178
 
+       support broke include extension.
5179
 
+       [4cb32478d80d]
5180
 
+
5181
 
+       * src/lib-sieve/Makefile.am, src/lib-sieve/cmd-discard.c, src/lib-
5182
 
+       sieve/cmd-redirect.c, src/lib-sieve/ext-reject.c, src/lib-
5183
 
+       sieve/plugins/body/ext-body-common.c, src/lib-sieve/plugins/copy
5184
 
+       /ext-copy.c, src/lib-sieve/plugins/imapflags/ext-imapflags-common.c,
5185
 
+       src/lib-sieve/plugins/imapflags/ext-imapflags-common.h, src/lib-
5186
 
+       sieve/plugins/imapflags/ext-imapflags.c, src/lib-
5187
 
+       sieve/plugins/imapflags/tag-flags.c, src/lib-sieve/plugins/include
5188
 
+       /ext-include-common.c, src/lib-sieve/plugins/include/ext-include-
5189
 
+       common.h, src/lib-sieve/plugins/include/ext-include.c, src/lib-
5190
 
+       sieve/plugins/include/include.sieve, src/lib-sieve/plugins/vacation
5191
 
+       /cmd-vacation.c, src/lib-sieve/plugins/variables/ext-variables.c,
5192
 
+       src/lib-sieve/sieve-actions.c, src/lib-sieve/sieve-actions.h, src
5193
 
+       /lib-sieve/sieve-common.h, src/lib-sieve/sieve-extensions.c, src
5194
 
+       /lib-sieve/sieve-extensions.h, src/lib-sieve/sieve-interpreter.c,
5195
 
+       src/lib-sieve/sieve-interpreter.h, src/lib-sieve/sieve-message.c,
5196
 
+       src/lib-sieve/sieve-message.h, src/lib-sieve/sieve-result.c, src
5197
 
+       /lib-sieve/sieve-result.h:
5198
 
+       Added support for implicit side effects and adjusted imapflags
5199
 
+       extension accordingly.
5200
 
+       [f55d47d1daee]
5201
 
+
5202
 
+2008-07-13  Stephan Bosch  <stephan@rename-it.nl>
5203
 
+
5204
 
+       * TODO, src/lib-sieve/plugins/imapflags/tag-flags.c, src/lib-sieve
5205
 
+       /sieve-actions.c, src/lib-sieve/sieve-actions.h:
5206
 
+       Imapflags: flags are stored for explicit actions.
5207
 
+       [9fa69efd67d1]
5208
 
+
5209
 
+2008-07-12  Stephan Bosch  <stephan@rename-it.nl>
5210
 
+
5211
 
+       * src/lib-sieve/plugins/imapflags/cmd-addflag.c, src/lib-
5212
 
+       sieve/plugins/imapflags/cmd-removeflag.c, src/lib-
5213
 
+       sieve/plugins/imapflags/cmd-setflag.c, src/lib-
5214
 
+       sieve/plugins/imapflags/tag-flags.c:
5215
 
+       Imapflags: cleaned up some debug messages and fixed triggered
5216
 
+       assertion.
5217
 
+       [ebdd1e5333ca]
5218
 
+
5219
 
+       * src/lib-sieve/ext-envelope.c, src/lib-sieve/ext-fileinto.c, src/lib-
5220
 
+       sieve/ext-reject.c:
5221
 
+       Forgot a few trace macros.
5222
 
+       [4f32214d959c]
5223
 
+
5224
 
+       * TODO:
5225
 
+       Updated TODO list.
5226
 
+       [9d16b8207a91]
5227
 
+
5228
 
+       * src/lib-sieve/sieve-actions.c:
5229
 
+       Fixed typos in some error messages.
5230
 
+       [584e2516320d]
5231
 
+
5232
 
+       * sieve/errors/out-address-errors.sieve, src/lib-sieve/Makefile.am,
5233
 
+       src/lib-sieve/cmd-redirect.c, src/lib-sieve/plugins/vacation/cmd-
5234
 
+       vacation.c, src/lib-sieve/sieve-address.c, src/lib-sieve/sieve-
5235
 
+       address.h, src/lib-sieve/sieve-validator-address.c, src/lib-sieve
5236
 
+       /sieve-validator.h:
5237
 
+       Improved address validation significantly.
5238
 
+       [3d2a4f000814]
5239
 
+
5240
 
+       * src/testsuite/tests/control-structures.svtest, src/testsuite/tests
5241
 
+       /match-types/contains.svtest:
5242
 
+       Added two simple test cases.
5243
 
+       [8354f6045c96]
5244
 
+
5245
 
+       * src/lib-sieve/sieve-commands.c:
5246
 
+       Forgot trace macro for the stop command.
5247
 
+       [2affc8a239aa]
5248
 
+
5249
 
+       * TODO:
5250
 
+       Removed llist TODO item, turns out to be less mergeable than
5251
 
+       initially thought.
5252
 
+       [e324d382f62b]
5253
 
+
5254
 
+2008-06-29  Stephan Bosch  <stephan@rename-it.nl>
5255
 
+
5256
 
+       * src/testsuite/tests/match-types/matches.svtest:
5257
 
+       Testsuite: extended :matches tests.
5258
 
+       [3cc1f848aa72]
5259
 
+
5260
 
+       * src/lib-sieve/cmd-discard.c, src/lib-sieve/cmd-keep.c, src/lib-sieve
5261
 
+       /cmd-redirect.c, src/lib-sieve/plugins/body/tst-body.c, src/lib-
5262
 
+       sieve/plugins/imapflags/cmd-addflag.c, src/lib-
5263
 
+       sieve/plugins/imapflags/cmd-removeflag.c, src/lib-
5264
 
+       sieve/plugins/imapflags/cmd-setflag.c, src/lib-
5265
 
+       sieve/plugins/imapflags/tst-hasflag.c, src/lib-sieve/plugins/include
5266
 
+       /cmd-include.c, src/lib-sieve/plugins/include/cmd-return.c, src/lib-
5267
 
+       sieve/plugins/vacation/cmd-vacation.c, src/lib-
5268
 
+       sieve/plugins/variables/cmd-set.c, src/lib-sieve/plugins/variables
5269
 
+       /tst-string.c, src/lib-sieve/sieve-code.c, src/lib-sieve/sieve-
5270
 
+       interpreter.c, src/lib-sieve/sieve-interpreter.h, src/lib-sieve/tst-
5271
 
+       address.c, src/lib-sieve/tst-exists.c, src/lib-sieve/tst-header.c,
5272
 
+       src/lib-sieve/tst-size.c, src/testsuite/cmd-test-fail.c,
5273
 
+       src/testsuite/cmd-test-set.c, src/testsuite/cmd-test.c,
5274
 
+       src/testsuite/ext-testsuite.c, src/testsuite/tests/match-
5275
 
+       types/matches.svtest, src/testsuite/testsuite-common.c,
5276
 
+       src/testsuite/testsuite-common.h, src/testsuite/testsuite.c:
5277
 
+       Introduced trace macro for runtime tracing and improved testsuite
5278
 
+       implementation.
5279
 
+       [d4206ad35724]
5280
 
+
5281
 
+       * src/lib-sieve/mcht-matches.c, src/testsuite/mail-raw.c,
5282
 
+       src/testsuite/tests/match-types/matches.svtest:
5283
 
+       Testsuite: fixed CRLF bug in reading a script-specified mail
5284
 
+       message.
5285
 
+       [65bedbabab62]
5286
 
+
5287
 
+       * sieve/tests/matches.sieve, src/lib-sieve/mcht-matches.c, src/lib-
5288
 
+       sieve/tst-header.c, src/testsuite/tests/match-types/matches.svtest:
5289
 
+       Fixed bugs in :matches implementation.
5290
 
+       [ded9f063bb3b]
5291
 
+
5292
 
+2008-06-28  Stephan Bosch  <stephan@rename-it.nl>
5293
 
+
5294
 
+       * src/lib-sieve/sieve-generator.c, src/testsuite/tests/match-
5295
 
+       types/matches.svtest, src/testsuite/tests/testsuite.sieve,
5296
 
+       src/testsuite/tests/testsuite.svtest:
5297
 
+       Added testcase to the testsuite.
5298
 
+       [901e88d94ef2]
5299
 
+
5300
 
+       * README, src/lib-sieve/ext-encoded-character.c, src/lib-sieve/ext-
5301
 
+       envelope.c, src/lib-sieve/ext-fileinto.c, src/lib-sieve/ext-
5302
 
+       reject.c, src/lib-sieve/plugins/imapflags/ext-imapflags.c, src/lib-
5303
 
+       sieve/plugins/include/ext-include.c, src/lib-sieve/plugins/variables
5304
 
+       /ext-variables.c:
5305
 
+       Updated documentation.
5306
 
+       [fe8d65b77b9d]
5307
 
+
5308
 
+       * TODO:
5309
 
+       Updated TODO.
5310
 
+       [e591cfdaaab9]
5311
 
+
5312
 
+       * TODO, src/lib-sieve/sieve-error-private.h, src/lib-sieve/sieve-
5313
 
+       error.c, src/lib-sieve/sieve-error.h, src/lib-sieve/sieve-parser.c,
5314
 
+       src/lib-sieve/sieve-validator.c, src/plugins/lda-sieve/lda-sieve-
5315
 
+       plugin.c, src/sieve-bin/bin-common.c, src/sieve-bin/sieve-exec.c,
5316
 
+       src/sieve-bin/sieve-test.c, src/testsuite/testsuite.c:
5317
 
+       Added support for limits on the maximum number of errors collected
5318
 
+       during compilation.
5319
 
+       [16066e307609]
5320
 
+
5321
 
+       * README, TODO:
5322
 
+       Updated documentation.
5323
 
+       [4282b0a65c30]
5324
 
+
5325
 
+       * sieve/errors/out-address-errors.sieve, src/lib-sieve/Makefile.am,
5326
 
+       src/lib-sieve/cmd-redirect.c, src/lib-sieve/plugins/vacation/cmd-
5327
 
+       vacation.c, src/lib-sieve/sieve-address.c, src/lib-sieve/sieve-
5328
 
+       commands.h, src/lib-sieve/sieve-validator-address.c, src/lib-sieve
5329
 
+       /sieve-validator.h:
5330
 
+       Added compile-time address validation.
5331
 
+       [d977d476923d]
5332
 
+
5333
 
+       * doc/rfc/imail.rfc2822.txt:
5334
 
+       Added IMAIL rfc.
5335
 
+       [252d826d42e3]
5336
 
+
5337
 
+       * doc/rfc/draft-ietf-sieve-3028bis-13.txt, doc/rfc/rfc3028.txt,
5338
 
+       doc/rfc/rfc3629.txt, doc/rfc/sieve.rfc5228.txt,
5339
 
+       doc/rfc/utf-8.rfc3629.txt:
5340
 
+       Updated doc/rfc directory.
5341
 
+       [c045f8d8aaf8]
5342
 
+
5343
 
+       * README, TODO:
5344
 
+       Updated documentation.
5345
 
+       [85aee022d63b]
5346
 
+
5347
 
+       * src/lib-sieve/ext-fileinto.c, src/lib-sieve/plugins/imapflags/tag-
5348
 
+       flags.c, src/lib-sieve/sieve-actions.c, src/lib-sieve/sieve-
5349
 
+       binary.c, src/lib-sieve/sieve-binary.h, src/lib-sieve/sieve-code-
5350
 
+       dumper.c, src/lib-sieve/sieve-commands.c, src/lib-sieve/sieve-
5351
 
+       commands.h, src/lib-sieve/sieve-extensions-private.h:
5352
 
+       Imapflags: finished for implicit flag attachment to fileinto and
5353
 
+       keep commands.
5354
 
+       [b9d8f9649bde]
5355
 
+
5356
 
+2008-06-17  Stephan Bosch  <stephan@rename-it.nl>
5357
 
+
5358
 
+       * TODO, src/lib-sieve/ext-encoded-character.c, src/lib-
5359
 
+       sieve/plugins/body/tst-body.c, src/lib-sieve/plugins/copy/ext-
5360
 
+       copy.c, src/lib-sieve/plugins/imapflags/ext-imapflags-common.c, src
5361
 
+       /lib-sieve/plugins/imapflags/ext-imapflags-common.h, src/lib-
5362
 
+       sieve/plugins/imapflags/ext-imapflags.c, src/lib-
5363
 
+       sieve/plugins/imapflags/tag-flags.c, src/lib-sieve/plugins/include
5364
 
+       /cmd-include.c, src/lib-sieve/plugins/vacation/cmd-vacation.c, src
5365
 
+       /lib-sieve/plugins/variables/cmd-set.c, src/lib-
5366
 
+       sieve/plugins/variables/ext-variables-arguments.c, src/lib-sieve
5367
 
+       /sieve-address-parts.c, src/lib-sieve/sieve-ast.c, src/lib-sieve
5368
 
+       /sieve-ast.h, src/lib-sieve/sieve-commands.c, src/lib-sieve/sieve-
5369
 
+       commands.h, src/lib-sieve/sieve-comparators.c, src/lib-sieve/sieve-
5370
 
+       match-types.c, src/lib-sieve/sieve-validator.c, src/lib-sieve/sieve-
5371
 
+       validator.h, src/lib-sieve/tst-size.c, src/testsuite/testsuite-
5372
 
+       objects.c:
5373
 
+       Added the concept of persistent tags and implemented imapflags
5374
 
+       extension for bare keep and fileinto commands (intermittent commit,
5375
 
+       not working properly yet).
5376
 
+       [b941171d7557]
5377
 
+
5378
 
+2008-06-04  Stephan Bosch  <stephan@rename-it.nl>
5379
 
+
5380
 
+       * src/lib-sieve/plugins/imapflags/cmd-addflag.c, src/lib-
5381
 
+       sieve/plugins/imapflags/cmd-removeflag.c, src/lib-
5382
 
+       sieve/plugins/imapflags/cmd-setflag.c, src/lib-
5383
 
+       sieve/plugins/imapflags/ext-imapflags-common.c, src/lib-
5384
 
+       sieve/plugins/imapflags/ext-imapflags-common.h, src/lib-
5385
 
+       sieve/plugins/imapflags/imapflags-variables.sieve, src/lib-
5386
 
+       sieve/plugins/imapflags/tst-hasflag.c, src/lib-
5387
 
+       sieve/plugins/variables/ext-variables-common.c, src/lib-
5388
 
+       sieve/plugins/variables/sieve-ext-variables.h:
5389
 
+       Imapflags: added execution support for variables.
5390
 
+       [3115627a9c60]
5391
 
+
5392
 
+       * src/lib-sieve/plugins/imapflags/Makefile.am, src/lib-
5393
 
+       sieve/plugins/imapflags/cmd-addflag.c, src/lib-
5394
 
+       sieve/plugins/imapflags/cmd-removeflag.c, src/lib-
5395
 
+       sieve/plugins/imapflags/cmd-setflag.c, src/lib-
5396
 
+       sieve/plugins/imapflags/ext-imapflags-common.c, src/lib-
5397
 
+       sieve/plugins/imapflags/ext-imapflags-common.h, src/lib-
5398
 
+       sieve/plugins/imapflags/imapflags-variables.sieve, src/lib-
5399
 
+       sieve/plugins/imapflags/tst-hasflag.c, src/lib-
5400
 
+       sieve/plugins/variables/cmd-set.c, src/lib-sieve/plugins/variables
5401
 
+       /ext-variables-arguments.c, src/lib-sieve/plugins/variables/ext-
5402
 
+       variables-arguments.h, src/lib-sieve/plugins/variables/ext-
5403
 
+       variables-operands.c, src/lib-sieve/plugins/variables/ext-variables-
5404
 
+       operands.h, src/lib-sieve/plugins/variables/sieve-ext-variables.h,
5405
 
+       src/lib-sieve/sieve-code.c, src/lib-sieve/sieve-code.h:
5406
 
+       Imapflags: added validation and code support for variables.
5407
 
+       [eebce2c24704]
5408
 
+
5409
 
+2008-06-03  Stephan Bosch  <stephan@rename-it.nl>
5410
 
+
5411
 
+       * TODO, src/lib-sieve/plugins/vacation/vacation.sieve, src/lib-sieve
5412
 
+       /sieve-validator.c:
5413
 
+       Fixed bug in duplicate argument detection.
5414
 
+       [9a8045ad9897]
5415
 
+
5416
 
+       * src/lib-sieve/plugins/vacation/Makefile.am, src/lib-
5417
 
+       sieve/plugins/vacation/cmd-vacation.c, src/lib-
5418
 
+       sieve/plugins/vacation/ext-vacation-common.h, src/lib-
5419
 
+       sieve/plugins/vacation/ext-vacation.c:
5420
 
+       Vacation: exported command implementation to separate file.
5421
 
+       [c0d69bd47692]
5422
 
+
5423
 
+       * src/lib-sieve/sieve-binary.c, src/sieve-bin/sieved.c:
5424
 
+       Fixed bug in sieved.
5425
 
+       [0cf9a6ab85d6]
5426
 
+
5427
 
+       * INSTALL, README, configure.in, src/sieve-bin/Makefile.am:
5428
 
+       Minor compile and documentation changes.
5429
 
+       [5d55a9fb061d]
5430
 
+
5431
 
+       * src/plugins/lda-sieve/lda-sieve-plugin.c:
5432
 
+       Made lda sieve plugin save and load binaries.
5433
 
+       [98a4a28d48d3]
5434
 
+
5435
 
+       * src/lib-sieve/sieve-ast.c, src/lib-sieve/sieve-ast.h, src/lib-sieve
5436
 
+       /sieve-binary.c, src/lib-sieve/sieve-binary.h, src/lib-sieve/sieve-
5437
 
+       code.c, src/lib-sieve/sieve-code.h, src/lib-sieve/sieve-commands.c,
5438
 
+       src/lib-sieve/sieve-commands.h, src/lib-sieve/sieve-comparators.c,
5439
 
+       src/lib-sieve/sieve-comparators.h, src/lib-sieve/sieve-generator.c,
5440
 
+       src/lib-sieve/sieve-generator.h, src/lib-sieve/sieve-interpreter.c,
5441
 
+       src/lib-sieve/sieve-interpreter.h, src/lib-sieve/sieve-lexer.c, src
5442
 
+       /lib-sieve/sieve-lexer.h, src/lib-sieve/sieve-result.c, src/lib-
5443
 
+       sieve/sieve-result.h, src/lib-sieve/sieve-script.c, src/lib-sieve
5444
 
+       /sieve-script.h, src/lib-sieve/sieve-validator.c, src/lib-sieve
5445
 
+       /sieve-validator.h, src/lib-sieve/sieve.c, src/lib-sieve/sieve.h,
5446
 
+       src/sieve-bin/sievec.c, src/testsuite/cmd-test.c, src/testsuite
5447
 
+       /testsuite-common.c:
5448
 
+       Resolved all outstanding warnings.
5449
 
+       [61acd01fe9df]
5450
 
+
5451
 
+       * DESIGN, INSTALL, Makefile.am, README, TODO, src/lib-
5452
 
+       sieve/Makefile.am, src/lib-sieve/plugins/body/Makefile.am, src/lib-
5453
 
+       sieve/plugins/comparator-i-ascii-numeric/Makefile.am, src/lib-
5454
 
+       sieve/plugins/copy/Makefile.am, src/lib-
5455
 
+       sieve/plugins/imapflags/Makefile.am, src/lib-sieve/plugins/imapflags
5456
 
+       /ext-imapflags-common.c, src/lib-sieve/plugins/include/Makefile.am,
5457
 
+       src/lib-sieve/plugins/regex/Makefile.am, src/lib-
5458
 
+       sieve/plugins/relational/Makefile.am, src/lib-
5459
 
+       sieve/plugins/subaddress/Makefile.am, src/lib-
5460
 
+       sieve/plugins/vacation/Makefile.am, src/lib-
5461
 
+       sieve/plugins/variables/Makefile.am:
5462
 
+       Updated documentation and fixed 'make dist'.
5463
 
+       [65c7b117ff36]
5464
 
+
5465
 
+2008-05-29  Stephan Bosch  <stephan@rename-it.nl>
5466
 
+
5467
 
+       * src/lib-sieve/sieve-generator.c, src/lib-sieve/sieve-generator.h,
5468
 
+       src/testsuite/Makefile.am, src/testsuite/cmd-test-fail.c,
5469
 
+       src/testsuite/cmd-test.c, src/testsuite/ext-testsuite.c,
5470
 
+       src/testsuite/tests/testsuite.sieve, src/testsuite/testsuite-
5471
 
+       common.c, src/testsuite/testsuite-common.h:
5472
 
+       Testsuite: added test_fail command.
5473
 
+       [063d37ff4c79]
5474
 
+
5475
 
+       * src/lib-sieve/cmd-if.c, src/lib-sieve/sieve-generator.c, src/lib-
5476
 
+       sieve/sieve-generator.h, src/lib-sieve/tst-allof.c, src/lib-sieve
5477
 
+       /tst-anyof.c, src/testsuite/Makefile.am, src/testsuite/cmd-test-
5478
 
+       set.c, src/testsuite/cmd-test.c, src/testsuite/ext-testsuite.c,
5479
 
+       src/testsuite/tests/testsuite.sieve, src/testsuite/testsuite-
5480
 
+       common.h, src/testsuite/testsuite-objects.c:
5481
 
+       Testsuite: added 'test' command to group sieve statements into a
5482
 
+       test.
5483
 
+       [3cc05036846c]
5484
 
+
5485
 
+2008-05-27  Stephan Bosch  <stephan@rename-it.nl>
5486
 
+
5487
 
+       * src/testsuite/cmd-test-set.c, src/testsuite/ext-testsuite.c,
5488
 
+       src/testsuite/tests/testsuite.sieve, src/testsuite/testsuite-
5489
 
+       common.c, src/testsuite/testsuite-common.h, src/testsuite/testsuite-
5490
 
+       objects.c, src/testsuite/testsuite-objects.h:
5491
 
+       Testsuite: added support for test object members.
5492
 
+       [62f783ff9f22]
5493
 
+
5494
 
+2008-05-25  Stephan Bosch  <stephan@rename-it.nl>
5495
 
+
5496
 
+       * src/testsuite/Makefile.am, src/testsuite/cmd-test-set.c,
5497
 
+       src/testsuite/testsuite-common.c, src/testsuite/testsuite-common.h,
5498
 
+       src/testsuite/testsuite-objects.c, src/testsuite/testsuite-
5499
 
+       objects.h:
5500
 
+       Testsuite: exported testsuit object interface to separate files.
5501
 
+       [e26637dce509]
5502
 
+
5503
 
+       * src/lib-sieve/sieve-code.h, src/lib-sieve/sieve-extensions-
5504
 
+       private.h, src/testsuite/Makefile.am, src/testsuite/cmd-test-
5505
 
+       message.c, src/testsuite/cmd-test-set.c, src/testsuite/ext-
5506
 
+       testsuite.c, src/testsuite/tests/testsuite.sieve, src/testsuite
5507
 
+       /testsuite-common.c, src/testsuite/testsuite-common.h:
5508
 
+       Testsuite: implemented testsuite object interface.
5509
 
+       [3e39d288a27f]
5510
 
+
5511
 
+2008-05-21  Stephan Bosch  <stephan@rename-it.nl>
5512
 
+
5513
 
+       * README, src/lib-sieve/plugins/vacation/vacation-errors.sieve:
5514
 
+       vacation: added TODO regarding duplicate tagged arguments to the
5515
 
+       vacation command.
5516
 
+       [62ced79fac8a]
5517
 
+
5518
 
+       * .hgignore, src/testsuite/testsuite:
5519
 
+       testsuite: removed spurious binary from repository.
5520
 
+       [058401bf5f8a]
5521
 
+
5522
 
+       * configure.in, src/testsuite/Makefile.am, src/testsuite/cmd-test-
5523
 
+       message.c, src/testsuite/mail-raw.c,
5524
 
+       src/testsuite/tests/testsuite.sieve, src/testsuite/testsuite,
5525
 
+       src/testsuite/testsuite-common.c, src/testsuite/testsuite-common.h,
5526
 
+       src/testsuite/testsuite.c:
5527
 
+       Testsuite: setting message content works.
5528
 
+       [93b3a300c389]
5529
 
+
5530
 
+       * src/lib-sieve/sieve-binary-dumper.c, src/lib-sieve/sieve-code-
5531
 
+       dumper.c, src/lib-sieve/sieve-extensions-private.h, src/lib-sieve
5532
 
+       /sieve-extensions.c, src/testsuite/cmd-test-message.c, src/testsuite
5533
 
+       /ext-testsuite.c, src/testsuite/testsuite,
5534
 
+       src/testsuite/testsuite.c:
5535
 
+       Fixed execution of initial testsuite implementation.
5536
 
+       [c1455741740d]
5537
 
+
5538
 
+2008-05-20  Stephan Bosch  <stephan@rename-it.nl>
5539
 
+
5540
 
+       * src/lib-sieve/ext-encoded-character.c, src/lib-sieve/ext-envelope.c,
5541
 
+       src/lib-sieve/ext-fileinto.c, src/lib-sieve/ext-reject.c, src/lib-
5542
 
+       sieve/plugins/body/ext-body.c, src/lib-sieve/plugins/comparator-i
5543
 
+       -ascii-numeric/ext-cmp-i-ascii-numeric.c, src/lib-sieve/plugins/copy
5544
 
+       /ext-copy.c, src/lib-sieve/plugins/imapflags/ext-imapflags.c, src
5545
 
+       /lib-sieve/plugins/include/ext-include-binary.c, src/lib-
5546
 
+       sieve/plugins/include/ext-include-binary.h, src/lib-
5547
 
+       sieve/plugins/include/ext-include.c, src/lib-sieve/plugins/regex
5548
 
+       /ext-regex.c, src/lib-sieve/plugins/relational/ext-relational.c, src
5549
 
+       /lib-sieve/plugins/subaddress/ext-subaddress.c, src/lib-
5550
 
+       sieve/plugins/vacation/ext-vacation.c, src/lib-
5551
 
+       sieve/plugins/variables/ext-variables.c, src/lib-sieve/sieve-
5552
 
+       actions.c, src/lib-sieve/sieve-address-parts.c, src/lib-sieve/sieve-
5553
 
+       binary-dumper.c, src/lib-sieve/sieve-binary-dumper.h, src/lib-sieve
5554
 
+       /sieve-binary.c, src/lib-sieve/sieve-binary.h, src/lib-sieve/sieve-
5555
 
+       code-dumper.c, src/lib-sieve/sieve-comparators.c, src/lib-sieve
5556
 
+       /sieve-extensions.h, src/lib-sieve/sieve-match-types.c,
5557
 
+       src/testsuite/testsuite:
5558
 
+       Properly implemented dumping a binary including a list of required
5559
 
+       extensions and support for extension-specific output.
5560
 
+       [49041cf55a5c]
5561
 
+
5562
 
+2008-05-18  Stephan Bosch  <stephan@rename-it.nl>
5563
 
+
5564
 
+       * .hgignore, src/Makefile.am, src/lib-sieve/Makefile.am, src/lib-sieve
5565
 
+       /ext-reject.c, src/lib-sieve/plugins/body/ext-body.c, src/lib-
5566
 
+       sieve/plugins/body/tst-body.c, src/lib-sieve/plugins/imapflags/ext-
5567
 
+       imapflags-common.c, src/lib-sieve/plugins/imapflags/imapflags.sieve,
5568
 
+       src/lib-sieve/plugins/imapflags/tag-flags.c, src/lib-
5569
 
+       sieve/plugins/imapflags/tst-hasflag.c, src/lib-sieve/plugins/include
5570
 
+       /cmd-include.c, src/lib-sieve/plugins/vacation/ext-vacation.c, src
5571
 
+       /lib-sieve/plugins/variables/cmd-set.c, src/lib-
5572
 
+       sieve/plugins/variables/ext-variables-arguments.c, src/lib-
5573
 
+       sieve/plugins/variables/ext-variables-common.c, src/lib-
5574
 
+       sieve/plugins/variables/ext-variables-operands.c, src/lib-
5575
 
+       sieve/plugins/variables/tst-string.c, src/lib-sieve/sieve-actions.c,
5576
 
+       src/lib-sieve/sieve-address-parts.c, src/lib-sieve/sieve-binary-
5577
 
+       dumper.c, src/lib-sieve/sieve-binary-dumper.h, src/lib-sieve/sieve-
5578
 
+       binary.c, src/lib-sieve/sieve-binary.h, src/lib-sieve/sieve-code-
5579
 
+       dumper.c, src/lib-sieve/sieve-code-dumper.h, src/lib-sieve/sieve-
5580
 
+       code.c, src/lib-sieve/sieve-code.h, src/lib-sieve/sieve-common.h,
5581
 
+       src/lib-sieve/sieve-comparators.c, src/lib-sieve/sieve-dump.h, src
5582
 
+       /lib-sieve/sieve-extensions-private.h, src/lib-sieve/sieve-match-
5583
 
+       types.c, src/lib-sieve/sieve-result.c, src/lib-sieve/sieve.c, src
5584
 
+       /lib-sieve/tst-header.c, src/testsuite/Makefile.am, src/testsuite
5585
 
+       /cmd-test-message.c, src/testsuite/ext-testsuite.c, src/testsuite
5586
 
+       /mail-raw.c, src/testsuite/mail-raw.h, src/testsuite/namespaces.c,
5587
 
+       src/testsuite/namespaces.h, src/testsuite/tests/testsuite.sieve,
5588
 
+       src/testsuite/testsuite, src/testsuite/testsuite-common.h,
5589
 
+       src/testsuite/testsuite.c:
5590
 
+       RECOVERED FROM INCONSISTENCY: developed testsuite and binary dumping
5591
 
+       and fixed various small issues.
5592
 
+       [5173404351c7]
5593
 
+
5594
 
+2008-04-06  Stephan Bosch  <stephan@rename-it.nl>
5595
 
+
5596
 
+       * README:
5597
 
+       Updated documentation.
5598
 
+       [e80c85bfd227]
5599
 
+
5600
 
+       * src/lib-sieve/plugins/include/Makefile.am, src/lib-
5601
 
+       sieve/plugins/include/cmd-export.c, src/lib-sieve/plugins/include
5602
 
+       /cmd-import.c, src/lib-sieve/plugins/include/ext-include-common.c,
5603
 
+       src/lib-sieve/plugins/include/ext-include-variables.c, src/lib-
5604
 
+       sieve/plugins/include/ext-include-variables.h, src/lib-
5605
 
+       sieve/plugins/include/include-variables.sieve, src/lib-
5606
 
+       sieve/plugins/include/include-variables1.sieve, src/lib-
5607
 
+       sieve/plugins/include/include-variables2.sieve, src/lib-
5608
 
+       sieve/plugins/include/include-variables3.sieve, src/lib-
5609
 
+       sieve/plugins/variables/cmd-set.c, src/lib-sieve/plugins/variables
5610
 
+       /ext-variables-common.c, src/lib-sieve/plugins/variables/ext-
5611
 
+       variables-common.h, src/lib-sieve/plugins/variables/ext-variables-
5612
 
+       operands.c, src/lib-sieve/plugins/variables/ext-variables.c, src
5613
 
+       /lib-sieve/plugins/variables/sieve-ext-variables.h:
5614
 
+       Include: merged import and export commands into a single
5615
 
+       implementation and implemented global variable storage.
5616
 
+       [2071bd319715]
5617
 
+
5618
 
+       * README, src/lib-sieve/plugins/variables/Makefile.am, src/lib-
5619
 
+       sieve/plugins/variables/ext-variables-common.c, src/lib-
5620
 
+       sieve/plugins/variables/ext-variables-operands.c, src/lib-
5621
 
+       sieve/plugins/variables/ext-variables-operands.h, src/lib-
5622
 
+       sieve/plugins/variables/ext-variables.c:
5623
 
+       Variables: exported new operand definitions to separate file.
5624
 
+       [1515291be1fe]
5625
 
+
5626
 
+2008-04-05  Stephan Bosch  <stephan@rename-it.nl>
5627
 
+
5628
 
+       * src/lib-sieve/plugins/variables/Makefile.am, src/lib-
5629
 
+       sieve/plugins/variables/ext-variables-arguments.c, src/lib-
5630
 
+       sieve/plugins/variables/ext-variables-arguments.h, src/lib-
5631
 
+       sieve/plugins/variables/ext-variables-common.c, src/lib-
5632
 
+       sieve/plugins/variables/ext-variables-common.h, src/lib-
5633
 
+       sieve/plugins/variables/ext-variables.c:
5634
 
+       Variables: exported new argument definitions to separate file.
5635
 
+       [889cea0db5b6]
5636
 
+
5637
 
+       * src/lib-sieve/plugins/include/cmd-export.c, src/lib-
5638
 
+       sieve/plugins/include/cmd-import.c, src/lib-sieve/plugins/include
5639
 
+       /ext-include-common.c, src/lib-sieve/plugins/include/ext-include-
5640
 
+       variables.c, src/lib-sieve/plugins/include/ext-include-variables.h:
5641
 
+       Include: implemented global variable scope.
5642
 
+       [5cce69ab4eb4]
5643
 
+
5644
 
+2008-04-03  Stephan Bosch  <stephan@rename-it.nl>
5645
 
+
5646
 
+       * README, src/sieve-bin/sieve-test.c:
5647
 
+       Added -c option to sieve-test to force compile.
5648
 
+       [5c2eeabbafbe]
5649
 
+
5650
 
+2008-03-24  Stephan Bosch  <stephan@rename-it.nl>
5651
 
+
5652
 
+       * README, src/lib-sieve/plugins/include/ext-include.c, src/lib-
5653
 
+       sieve/plugins/variables/ext-variables.c:
5654
 
+       Updated documentation.
5655
 
+       [157a94a31c54]
5656
 
+
5657
 
+       * src/lib-sieve/plugins/include/Makefile.am, src/lib-
5658
 
+       sieve/plugins/include/cmd-export.c, src/lib-sieve/plugins/include
5659
 
+       /cmd-import.c, src/lib-sieve/plugins/include/ext-include-binary.h,
5660
 
+       src/lib-sieve/plugins/include/ext-include-common.c, src/lib-
5661
 
+       sieve/plugins/include/ext-include-common.h, src/lib-
5662
 
+       sieve/plugins/include/ext-include-variables.c, src/lib-
5663
 
+       sieve/plugins/include/ext-include-variables.h, src/lib-
5664
 
+       sieve/plugins/include/include-variables1.sieve, src/lib-
5665
 
+       sieve/plugins/include/include-variables2.sieve:
5666
 
+       Include: moved variables support to separate file.
5667
 
+       [9a997c6e97d0]
5668
 
+
5669
 
+       * src/lib-sieve/plugins/include/Makefile.am, src/lib-
5670
 
+       sieve/plugins/include/cmd-export.c, src/lib-sieve/plugins/include
5671
 
+       /ext-include-binary.c, src/lib-sieve/plugins/include/ext-include-
5672
 
+       binary.h, src/lib-sieve/plugins/include/ext-include-common.c, src
5673
 
+       /lib-sieve/plugins/include/ext-include-common.h, src/lib-
5674
 
+       sieve/plugins/include/ext-include.c:
5675
 
+       Include: moved implementation of binary extension to separate file.
5676
 
+       [29877e0201ea]
5677
 
+
5678
 
+       * src/lib-sieve/plugins/include/cmd-export.c, src/lib-
5679
 
+       sieve/plugins/include/cmd-import.c, src/lib-sieve/plugins/include
5680
 
+       /ext-include-common.c, src/lib-sieve/plugins/include/ext-include-
5681
 
+       common.h, src/lib-sieve/plugins/include/ext-include.c, src/lib-
5682
 
+       sieve/plugins/include/include-variables-error2.sieve, src/lib-
5683
 
+       sieve/plugins/variables/ext-variables-common.c, src/lib-
5684
 
+       sieve/plugins/variables/ext-variables-common.h, src/lib-
5685
 
+       sieve/plugins/variables/sieve-ext-variables.h, src/lib-sieve/sieve-
5686
 
+       ast.c, src/lib-sieve/sieve-ast.h:
5687
 
+       Include: added AST context and now export context detectects export
5688
 
+       of imported variables.
5689
 
+       [7e2750e9e64b]
5690
 
+
5691
 
+       * src/lib-sieve/plugins/include/cmd-include.c, src/lib-
5692
 
+       sieve/plugins/include/ext-include-common.c, src/lib-
5693
 
+       sieve/plugins/include/ext-include-common.h, src/lib-
5694
 
+       sieve/plugins/include/include-error.sieve, src/lib-sieve/sieve-
5695
 
+       ast.c, src/lib-sieve/sieve-ast.h:
5696
 
+       Include: moved script existance validation back to validation stage.
5697
 
+       [f179c5640bed]
5698
 
+
5699
 
+       * src/lib-sieve/plugins/include/Makefile.am, src/lib-
5700
 
+       sieve/plugins/include/cmd-export.c, src/lib-sieve/plugins/include
5701
 
+       /cmd-import.c, src/lib-sieve/plugins/include/include-variables-
5702
 
+       error.sieve, src/lib-sieve/plugins/variables/cmd-set.c, src/lib-
5703
 
+       sieve/plugins/variables/ext-variables-common.c, src/lib-
5704
 
+       sieve/plugins/variables/sieve-ext-variables.h:
5705
 
+       Include: made import and export commands check whether the variables
5706
 
+       extension is active.
5707
 
+       [b1e85659979f]
5708
 
+
5709
 
+2008-03-23  Stephan Bosch  <stephan@rename-it.nl>
5710
 
+
5711
 
+       * src/lib-sieve/plugins/include/Makefile.am, src/lib-
5712
 
+       sieve/plugins/include/cmd-export.c, src/lib-sieve/plugins/include
5713
 
+       /cmd-import.c, src/lib-sieve/plugins/include/cmd-include.c, src/lib-
5714
 
+       sieve/plugins/include/ext-include-common.c, src/lib-
5715
 
+       sieve/plugins/include/ext-include-common.h, src/lib-
5716
 
+       sieve/plugins/include/ext-include.c, src/lib-sieve/plugins/include
5717
 
+       /include-variables.sieve, src/lib-sieve/plugins/include/include-
5718
 
+       variables1.sieve, src/lib-sieve/plugins/include/include-
5719
 
+       variables2.sieve, src/lib-sieve/sieve-generator.c, src/lib-sieve
5720
 
+       /sieve-script.c:
5721
 
+       Include: added skeleton import and export commands.
5722
 
+       [c3f48302b86a]
5723
 
+
5724
 
+       * README:
5725
 
+       Updated TODO.
5726
 
+       [404001bc4009]
5727
 
+
5728
 
+       * src/lib-sieve/plugins/regex/mcht-regex.c, src/lib-
5729
 
+       sieve/plugins/variables/Makefile.am, src/lib-sieve/plugins/variables
5730
 
+       /variables-regex.sieve, src/lib-sieve/sieve-match-types.c, src/lib-
5731
 
+       sieve/sieve-match-types.h:
5732
 
+       Regex: added match values support.
5733
 
+       [5dfb64a0f93b]
5734
 
+
5735
 
+       * src/lib-sieve/plugins/relational/Makefile.am, src/lib-
5736
 
+       sieve/plugins/relational/ext-relational-common.c, src/lib-
5737
 
+       sieve/plugins/relational/ext-relational-common.h, src/lib-
5738
 
+       sieve/plugins/relational/ext-relational.c, src/lib-
5739
 
+       sieve/plugins/relational/mcht-count.c, src/lib-
5740
 
+       sieve/plugins/relational/mcht-value.c:
5741
 
+       Relational: split match-type implementation into separate file.
5742
 
+       [c3887aa30660]
5743
 
+
5744
 
+       * src/lib-sieve/plugins/regex/Makefile.am, src/lib-sieve/plugins/regex
5745
 
+       /ext-regex-common.h, src/lib-sieve/plugins/regex/ext-regex.c, src
5746
 
+       /lib-sieve/plugins/regex/mcht-regex.c:
5747
 
+       Regex: split match type implementation into separate file.
5748
 
+       [6de0ef9ce851]
5749
 
+
5750
 
+       * src/lib-sieve/Makefile.am, src/lib-sieve/mcht-contains.c, src/lib-
5751
 
+       sieve/mcht-is.c, src/lib-sieve/mcht-matches.c, src/lib-
5752
 
+       sieve/plugins/body/ext-body-common.c, src/lib-sieve/sieve-match-
5753
 
+       types.c, src/lib-sieve/sieve-match-types.h:
5754
 
+       Exported match type implementations to separate files.
5755
 
+       [9c87314c8c6e]
5756
 
+
5757
 
+2008-03-22  Stephan Bosch  <stephan@rename-it.nl>
5758
 
+
5759
 
+       * src/lib-sieve/plugins/variables/variables-match.sieve, src/lib-sieve
5760
 
+       /sieve-match-types.c:
5761
 
+       Finished :matches function for now, but it can still be improved and
5762
 
+       it needs more testing.
5763
 
+       [dce3ebd372de]
5764
 
+
5765
 
+2008-03-09  Stephan Bosch  <stephan@rename-it.nl>
5766
 
+
5767
 
+       * src/lib-sieve/plugins/variables/variables-match.sieve, src/lib-sieve
5768
 
+       /sieve-match-types.c, src/lib-sieve/sieve-match-types.h:
5769
 
+       Revised :matches function, but did finish.
5770
 
+       [361d7952dcc3]
5771
 
+
5772
 
+2008-03-08  Stephan Bosch  <stephan@rename-it.nl>
5773
 
+
5774
 
+       * src/lib-sieve/plugins/variables/variables-match.sieve, src/lib-sieve
5775
 
+       /sieve-match-types.c:
5776
 
+       Variables: fixed bug in match value indexing.
5777
 
+       [eb6b7af13024]
5778
 
+
5779
 
+       * src/lib-sieve/ext-envelope.c, src/lib-sieve/plugins/body/tst-body.c,
5780
 
+       src/lib-sieve/plugins/imapflags/tst-hasflag.c, src/lib-
5781
 
+       sieve/plugins/variables/ext-variables-common.c, src/lib-
5782
 
+       sieve/plugins/variables/ext-variables-common.h, src/lib-
5783
 
+       sieve/plugins/variables/ext-variables.c, src/lib-
5784
 
+       sieve/plugins/variables/tst-string.c, src/lib-
5785
 
+       sieve/plugins/variables/variables-match.sieve, src/lib-sieve/sieve-
5786
 
+       match-types.c, src/lib-sieve/sieve-match-types.h, src/lib-sieve/tst-
5787
 
+       address.c, src/lib-sieve/tst-header.c:
5788
 
+       Variables: First work towards match value support.
5789
 
+       [39ae5f637374]
5790
 
+
5791
 
+2008-02-28  Stephan Bosch  <stephan@rename-it.nl>
5792
 
+
5793
 
+       * README, src/lib-sieve/plugins/variables/ext-variables.c:
5794
 
+       Updated documentation.
5795
 
+       [b01fae741c62]
5796
 
+
5797
 
+       * src/lib-sieve/plugins/variables/cmd-set.c, src/lib-
5798
 
+       sieve/plugins/variables/ext-variables-common.c, src/lib-
5799
 
+       sieve/plugins/variables/ext-variables-common.h, src/lib-
5800
 
+       sieve/plugins/variables/variables-errors.sieve:
5801
 
+       Variables: added variable name parsing to the set command and added
5802
 
+       error handling.
5803
 
+       [636f16de84ad]
5804
 
+
5805
 
+       * src/lib-sieve/plugins/variables/Makefile.am, src/lib-
5806
 
+       sieve/plugins/variables/ext-variables-common.c, src/lib-
5807
 
+       sieve/plugins/variables/ext-variables-name.c, src/lib-
5808
 
+       sieve/plugins/variables/ext-variables-name.h, src/lib-
5809
 
+       sieve/plugins/variables/variables-nspace.sieve:
5810
 
+       Variables: exported namespace+variable parsing to separate file.
5811
 
+       [1eb6468cbb57]
5812
 
+
5813
 
+       * src/lib-sieve/plugins/variables/ext-variables-common.c:
5814
 
+       Variables: exported namespace+variable parsing to separate function.
5815
 
+       [324762d634a0]
5816
 
+
5817
 
+       * README:
5818
 
+       Updated documentation.
5819
 
+       [2d7d8b3882d6]
5820
 
+
5821
 
+2008-02-27  Stephan Bosch  <stephan@rename-it.nl>
5822
 
+
5823
 
+       * src/lib-sieve/ext-envelope.c, src/lib-sieve/plugins/variables/ext-
5824
 
+       variables-common.c:
5825
 
+       Variables: added parsing support for namespaces.
5826
 
+       [be3b8bac2c3b]
5827
 
+
5828
 
+       * src/lib-sieve/plugins/variables/tst-string.c:
5829
 
+       Variables: fixed string test.
5830
 
+       [6b07d2c2aecf]
5831
 
+
5832
 
+2008-02-26  Stephan Bosch  <stephan@rename-it.nl>
5833
 
+
5834
 
+       * src/plugins/lda-sieve/lda-sieve-plugin.c:
5835
 
+       Expand ~ to home in sieve path.
5836
 
+       [5a26dbbd6b04]
5837
 
+
5838
 
+2008-02-25  Stephan Bosch  <stephan@rename-it.nl>
5839
 
+
5840
 
+       * src/lib-sieve/sieve-binary.c:
5841
 
+       Fixed indent in sieve-banary.c
5842
 
+       [b3ad65e8017e]
5843
 
+
5844
 
+       * src/lib-sieve/sieve-script.c:
5845
 
+       Simplified needlessly complex assignment.
5846
 
+       [71baeea1b4c2]
5847
 
+
5848
 
+       * README:
5849
 
+       Added TODO item.
5850
 
+       [5e891151c11d]
5851
 
+
5852
 
+       * src/lib-sieve/plugins/regex/ext-regex.c, src/lib-sieve/sieve-
5853
 
+       comparators.c:
5854
 
+       Avoid direct to_lower() invocations; replaced by i_tolower().
5855
 
+       [4a4da0b36b73]
5856
 
+
5857
 
+       * README:
5858
 
+       Updated documentation.
5859
 
+       [23fddcb3bff4]
5860
 
+
5861
 
+       * src/lib-sieve/plugins/regex/ext-regex.c, src/lib-sieve/sieve-code.c,
5862
 
+       src/lib-sieve/sieve-match-types.c:
5863
 
+       Changed various p_new(pool_datastack_create(),) invocations to
5864
 
+       t_new()
5865
 
+       [4a350bcb98fb]
5866
 
+
5867
 
+       * src/lib-sieve/ext-envelope.c, src/lib-
5868
 
+       sieve/plugins/variables/variables.sieve:
5869
 
+       Envelope: changed p_array_init(,pool_datastack_create(),) into
5870
 
+       t_array_init(,)
5871
 
+       [d2659865968c]
5872
 
+
5873
 
+       * README:
5874
 
+       Updated documentation.
5875
 
+       [8854635f2819]
5876
 
+
5877
 
+2008-02-23  Stephan Bosch  <stephan@rename-it.nl>
5878
 
+
5879
 
+       * src/lib-sieve/plugins/variables/ext-variables-common.c, src/lib-
5880
 
+       sieve/plugins/variables/variables.sieve, src/lib-sieve/sieve-code.c:
5881
 
+       Variables: fixed bug in string-list containing variables.
5882
 
+       [bda964bee9f5]
5883
 
+
5884
 
+       * src/lib-sieve/plugins/regex/ext-regex.c, src/lib-
5885
 
+       sieve/plugins/variables/tst-string.c, src/lib-
5886
 
+       sieve/plugins/variables/variables.sieve, src/lib-sieve/sieve-
5887
 
+       commands.c:
5888
 
+       Fixed bugs in string substitution support and the regex extension.
5889
 
+       [2c93a6f1f120]
5890
 
+
5891
 
+       * src/lib-sieve/plugins/variables/draft-ietf-sieve-variables-08.txt,
5892
 
+       src/lib-sieve/plugins/variables/ext-variables.c, src/lib-
5893
 
+       sieve/plugins/variables/rfc5229.txt:
5894
 
+       Variables: updated included specification to new RFC 5229.
5895
 
+       [970977365e61]
5896
 
+
5897
 
+       * README:
5898
 
+       Updated documentation.
5899
 
+       [8223da28978b]
5900
 
+
5901
 
+       * src/lib-sieve/plugins/variables/ext-variables-common.c, src/lib-
5902
 
+       sieve/plugins/variables/variables.sieve:
5903
 
+       Variables: made variable identifiers case insensitive.
5904
 
+       [22ba1d548f77]
5905
 
+
5906
 
+2008-02-22  Stephan Bosch  <stephan@rename-it.nl>
5907
 
+
5908
 
+       * src/lib-sieve/plugins/variables/cmd-set.c, src/lib-
5909
 
+       sieve/plugins/variables/variables-errors.sieve:
5910
 
+       Variables: added check for equal precedence and added comment.
5911
 
+       [78ac4b9fd4b7]
5912
 
+
5913
 
+       * src/lib-sieve/plugins/variables/cmd-set.c, src/lib-
5914
 
+       sieve/plugins/variables/ext-variables-common.c, src/lib-
5915
 
+       sieve/plugins/variables/variables.sieve:
5916
 
+       Variables: activated 'quotewildcard' set modifier and fixed a bug.
5917
 
+       [f5cc923c0cf8]
5918
 
+
5919
 
+       * src/lib-sieve/plugins/variables/cmd-set.c, src/lib-
5920
 
+       sieve/plugins/variables/ext-variables-common.c, src/lib-
5921
 
+       sieve/plugins/variables/variables.sieve:
5922
 
+       Variables: activated 'length' set modifier.
5923
 
+       [571ff4050c4e]
5924
 
+
5925
 
+       * src/lib-sieve/plugins/variables/cmd-set.c, src/lib-
5926
 
+       sieve/plugins/variables/ext-variables-common.h, src/lib-
5927
 
+       sieve/plugins/variables/variables.sieve:
5928
 
+       Variables: activated support for set command modifiers.
5929
 
+       [9c3840cc68f6]
5930
 
+
5931
 
+       * src/lib-sieve/plugins/body/ext-body-common.c:
5932
 
+       Adjusted body extension to compile with dovecot past 1.1.beta16
5933
 
+       (message parser changes)
5934
 
+       [854549e5e6d9]
5935
 
+
5936
 
+2008-02-14  Stephan Bosch  <stephan@rename-it.nl>
5937
 
+
5938
 
+       * AUTHORS:
5939
 
+       Added notice about the omission CMU code to the AUTHORS file.
5940
 
+       [e10b34c008dd]
5941
 
+
5942
 
+       * .hgignore, configure.in:
5943
 
+       Assigned proper package version and name.
5944
 
+       [19fa7bfb0623]
5945
 
+
5946
 
+       * .hgignore, COPYING:
5947
 
+       Removed duplicate licence.
5948
 
+       [be7aad6c814d]
5949
 
+
5950
 
+       * Makefile.am:
5951
 
+       Added maintainermode functions to Makefile.am
5952
 
+       [fdf2ea8d11d3]
5953
 
+
5954
 
+2008-02-13  Stephan Bosch  <stephan@rename-it.nl>
5955
 
+
5956
 
+       * src/lib-sieve/ext-encoded-character.c, src/lib-sieve/plugins/body
5957
 
+       /ext-body-common.c, src/lib-sieve/sieve-address-parts.c, src/lib-
5958
 
+       sieve/sieve-ast.c, src/lib-sieve/sieve-binary.c, src/lib-sieve
5959
 
+       /sieve-commands.c, src/lib-sieve/sieve-error.c, src/lib-sieve/sieve-
5960
 
+       error.h, src/lib-sieve/sieve-generator.c, src/lib-sieve/sieve-
5961
 
+       interpreter.c, src/lib-sieve/sieve-lexer.c, src/lib-sieve/sieve-
5962
 
+       parser.c, src/lib-sieve/sieve-validator.c, src/lib-sieve/sieve.c,
5963
 
+       src/plugins/lda-sieve/lda-sieve-plugin.c:
5964
 
+       Incorporated changes in dovecot-1.1
5965
 
+       [c8c67641d0dc]
5966
 
+
5967
 
+2008-02-11  Stephan Bosch  <stephan@rename-it.nl>
5968
 
+
5969
 
+       * src/lib-sieve/plugins/variables/cmd-set.c, src/lib-
5970
 
+       sieve/plugins/variables/variables.sieve:
5971
 
+       Variables: set modifiers are now sorted.
5972
 
+       [5ceb8e6709ef]
5973
 
+
5974
 
+2008-02-10  Stephan Bosch  <stephan@rename-it.nl>
5975
 
+
5976
 
+       * src/lib-sieve/plugins/variables/cmd-set.c, src/lib-
5977
 
+       sieve/plugins/variables/ext-variables-common.c, src/lib-
5978
 
+       sieve/plugins/variables/ext-variables-common.h, src/lib-
5979
 
+       sieve/plugins/variables/ext-variables.c, src/lib-
5980
 
+       sieve/plugins/variables/sieve-ext-variables.h:
5981
 
+       Added code support for set modifiers.
5982
 
+       [edba29e3d158]
5983
 
+
5984
 
+2008-01-06  Stephan Bosch  <stephan@rename-it.nl>
5985
 
+
5986
 
+       * src/lib-sieve/cmd-redirect.c, src/lib-sieve/ext-envelope.c, src/lib-
5987
 
+       sieve/ext-fileinto.c, src/lib-sieve/ext-reject.c, src/lib-
5988
 
+       sieve/plugins/body/tst-body.c, src/lib-sieve/plugins/imapflags/ext-
5989
 
+       imapflags-common.c, src/lib-sieve/plugins/imapflags/tst-hasflag.c,
5990
 
+       src/lib-sieve/plugins/vacation/ext-vacation.c, src/lib-
5991
 
+       sieve/plugins/variables/cmd-set.c, src/lib-sieve/plugins/variables
5992
 
+       /ext-variables-common.c, src/lib-sieve/plugins/variables/tst-
5993
 
+       string.c, src/lib-sieve/plugins/variables/variables.sieve, src/lib-
5994
 
+       sieve/sieve-validator.c, src/lib-sieve/tst-address.c, src/lib-sieve
5995
 
+       /tst-exists.c, src/lib-sieve/tst-header.c, src/lib-sieve/tst-size.c:
5996
 
+       Fixed bugs in validation error handling and fixed bugs in dynamic
5997
 
+       argument support.
5998
 
+       [207f7dea843e]
5999
 
+
6000
 
+2008-01-05  Stephan Bosch  <stephan@rename-it.nl>
6001
 
+
6002
 
+       * src/lib-sieve/plugins/variables/cmd-set.c, src/lib-
6003
 
+       sieve/plugins/variables/ext-variables-common.c, src/lib-
6004
 
+       sieve/plugins/variables/ext-variables-common.h, src/lib-
6005
 
+       sieve/plugins/variables/ext-variables.c, src/lib-
6006
 
+       sieve/plugins/variables/variables.sieve, src/lib-sieve/sieve-ast.c,
6007
 
+       src/lib-sieve/sieve-ast.h, src/lib-sieve/sieve-validator.c:
6008
 
+       First successful variable substitutions.
6009
 
+       [beaacb4d8406]
6010
 
+
6011
 
+       * Merged concurrent changes.
6012
 
+       [8e8f0012b6c1]
6013
 
+
6014
 
+       * src/lib-sieve/cmd-redirect.c, src/lib-sieve/ext-envelope.c, src/lib-
6015
 
+       sieve/ext-fileinto.c, src/lib-sieve/ext-reject.c, src/lib-
6016
 
+       sieve/plugins/body/tst-body.c, src/lib-sieve/plugins/imapflags/cmd-
6017
 
+       addflag.c, src/lib-sieve/plugins/imapflags/cmd-removeflag.c, src
6018
 
+       /lib-sieve/plugins/imapflags/cmd-setflag.c, src/lib-
6019
 
+       sieve/plugins/imapflags/tag-flags.c, src/lib-sieve/plugins/imapflags
6020
 
+       /tst-hasflag.c, src/lib-sieve/plugins/vacation/ext-vacation.c, src
6021
 
+       /lib-sieve/plugins/variables/cmd-set.c, src/lib-
6022
 
+       sieve/plugins/variables/ext-variables-common.c, src/lib-
6023
 
+       sieve/plugins/variables/ext-variables-common.h, src/lib-
6024
 
+       sieve/plugins/variables/ext-variables.c, src/lib-
6025
 
+       sieve/plugins/variables/sieve-ext-variables.h, src/lib-
6026
 
+       sieve/plugins/variables/tst-string.c, src/lib-sieve/sieve-actions.c,
6027
 
+       src/lib-sieve/sieve-actions.h, src/lib-sieve/sieve-address-parts.c,
6028
 
+       src/lib-sieve/sieve-address-parts.h, src/lib-sieve/sieve-code.c, src
6029
 
+       /lib-sieve/sieve-code.h, src/lib-sieve/sieve-comparators.c, src/lib-
6030
 
+       sieve/sieve-comparators.h, src/lib-sieve/sieve-interpreter.c, src
6031
 
+       /lib-sieve/sieve-match-types.c, src/lib-sieve/sieve-match-types.h,
6032
 
+       src/lib-sieve/tst-address.c, src/lib-sieve/tst-exists.c, src/lib-
6033
 
+       sieve/tst-header.c, src/lib-sieve/tst-size.c:
6034
 
+       Changed operand read API to get access to the runtime environment
6035
 
+       inside the read functions.
6036
 
+       [be351797c032]
6037
 
+
6038
 
+2008-01-04  Stephan Bosch  <stephan@rename-it.nl>
6039
 
+
6040
 
+       * sieve/errors/interesting.sieve, src/lib-sieve/sieve-parser.c:
6041
 
+       Minor fix in the error reporting of the sieve parser.
6042
 
+       [d403335a9351]
6043
 
+
6044
 
+       * src/lib-sieve/sieve-extensions.c, src/lib-sieve/sieve-extensions.h,
6045
 
+       src/lib-sieve/sieve.c:
6046
 
+       Implemented dynamic sieve_get_capabilities() for proper MANAGESIEVE
6047
 
+       support.
6048
 
+       [5ecaa79ab879]
6049
 
+
6050
 
+       * src/lib-sieve/sieve.c, src/lib-sieve/sieve.h:
6051
 
+       Published compiler API using script objects instead of paths.
6052
 
+       [16d8c8b63bcc]
6053
 
+
6054
 
+       * src/lib-sieve/sieve-validator.c:
6055
 
+       Fixed segfault occuring when command did not exist.
6056
 
+       [31182d66d254]
6057
 
+
6058
 
+       * src/lib-sieve/sieve-error.c, src/lib-sieve/sieve-script.c:
6059
 
+       Small changes: removed T_FRAME and improved an error message.
6060
 
+       [dac13553f2fa]
6061
 
+
6062
 
+2008-01-03  Stephan Bosch  <stephan@rename-it.nl>
6063
 
+
6064
 
+       * src/lib-sieve/Makefile.am, src/lib-sieve/plugins/include/ext-
6065
 
+       include-common.c, src/lib-sieve/sieve-binary.c, src/lib-sieve/sieve-
6066
 
+       error-private.h, src/lib-sieve/sieve-error.c, src/lib-sieve/sieve-
6067
 
+       error.h, src/lib-sieve/sieve-generator.c, src/lib-sieve/sieve-
6068
 
+       interpreter.c, src/lib-sieve/sieve-lexer.c, src/lib-sieve/sieve-
6069
 
+       parser.c, src/lib-sieve/sieve-result.c, src/lib-sieve/sieve-script-
6070
 
+       private.h, src/lib-sieve/sieve-script.c, src/lib-sieve/sieve-
6071
 
+       script.h, src/lib-sieve/sieve-validator.c, src/lib-sieve/sieve.c,
6072
 
+       src/lib-sieve/sieve.h, src/plugins/lda-sieve/lda-sieve-plugin.c, src
6073
 
+       /sieve-bin/bin-common.c, src/sieve-bin/sieve-exec.c, src/sieve-bin
6074
 
+       /sieve-test.c:
6075
 
+       Implemented required features for use with MANAGESIEVE service.
6076
 
+       [41d479d33f26]
6077
 
+
6078
 
+       * src/lib-sieve/sieve-error.c, src/lib-sieve/sieve-error.h:
6079
 
+       Added strbuf error handler.
6080
 
+       [57118bf13efc]
6081
 
+
6082
 
+2007-12-30  Stephan Bosch  <stephan@rename-it.nl>
6083
 
+
6084
 
+       * src/lib-sieve/plugins/variables/cmd-set.c, src/lib-
6085
 
+       sieve/plugins/variables/ext-variables-common.c, src/lib-
6086
 
+       sieve/plugins/variables/ext-variables-common.h, src/lib-
6087
 
+       sieve/plugins/variables/ext-variables.c, src/lib-sieve/sieve-
6088
 
+       actions.c, src/lib-sieve/sieve-address-parts.c, src/lib-sieve/sieve-
6089
 
+       code.c, src/lib-sieve/sieve-code.h, src/lib-sieve/sieve-
6090
 
+       comparators.c, src/lib-sieve/sieve-match-types.c:
6091
 
+       Added variable operand to the variables extension.
6092
 
+       [cd89ce24b255]
6093
 
+
6094
 
+       * src/lib-sieve/sieve-actions.c, src/lib-sieve/sieve-address-parts.c,
6095
 
+       src/lib-sieve/sieve-code.c, src/lib-sieve/sieve-code.h, src/lib-
6096
 
+       sieve/sieve-comparators.c, src/lib-sieve/sieve-extensions.h, src
6097
 
+       /lib-sieve/sieve-match-types.c:
6098
 
+       Added support for adding new types operands to the engine.
6099
 
+       [6f5eadd0e4c8]
6100
 
+
6101
 
+       * src/lib-sieve/plugins/variables/cmd-set.c, src/lib-
6102
 
+       sieve/plugins/variables/ext-variables-common.c, src/lib-
6103
 
+       sieve/plugins/variables/ext-variables-common.h, src/lib-
6104
 
+       sieve/plugins/variables/sieve-ext-variables.h:
6105
 
+       Defined variable argument for the variables extension.
6106
 
+       [b0552c08b279]
6107
 
+
6108
 
+2007-12-29  Stephan Bosch  <stephan@rename-it.nl>
6109
 
+
6110
 
+       * src/lib-sieve/sieve-commands.c, src/lib-sieve/sieve-generator.c, src
6111
 
+       /lib-sieve/sieve-generator.h, src/lib-sieve/sieve-validator.c, src
6112
 
+       /lib-sieve/sieve-validator.h:
6113
 
+       Changed validation and generation of string list argument to fully
6114
 
+       support the new string list encoding.
6115
 
+       [f65dd8431ae8]
6116
 
+
6117
 
+       * src/lib-sieve/sieve-actions.c, src/lib-sieve/sieve-binary.c, src
6118
 
+       /lib-sieve/sieve-code.c:
6119
 
+       Changed encoding of stringlist. Now it contains string operands in
6120
 
+       stead of bare strings.
6121
 
+       [7bac41b7e6c1]
6122
 
+
6123
 
+       * src/lib-sieve/sieve-extensions-private.h:
6124
 
+       Removed obsolete code.
6125
 
+       [9aeb0333b0d7]
6126
 
+
6127
 
+       * sieve/tests/address-part.sieve, src/lib-sieve/ext-encoded-
6128
 
+       character.c, src/lib-sieve/ext-envelope.c, src/lib-sieve/ext-
6129
 
+       fileinto.c, src/lib-sieve/ext-reject.c, src/lib-sieve/plugins/body
6130
 
+       /ext-body.c, src/lib-sieve/plugins/comparator-i-ascii-numeric/ext-
6131
 
+       cmp-i-ascii-numeric.c, src/lib-sieve/plugins/copy/ext-copy.c, src
6132
 
+       /lib-sieve/plugins/imapflags/tag-flags.c, src/lib-
6133
 
+       sieve/plugins/include/ext-include.c, src/lib-sieve/plugins/regex
6134
 
+       /ext-regex.c, src/lib-sieve/plugins/relational/ext-relational.c, src
6135
 
+       /lib-sieve/plugins/subaddress/ext-subaddress.c, src/lib-
6136
 
+       sieve/plugins/vacation/ext-vacation.c, src/lib-
6137
 
+       sieve/plugins/variables/ext-variables.c, src/lib-sieve/sieve-
6138
 
+       actions.c, src/lib-sieve/sieve-actions.h, src/lib-sieve/sieve-
6139
 
+       address-parts.c, src/lib-sieve/sieve-binary.c, src/lib-sieve/sieve-
6140
 
+       code.c, src/lib-sieve/sieve-comparators.c, src/lib-sieve/sieve-
6141
 
+       comparators.h, src/lib-sieve/sieve-extensions-private.h, src/lib-
6142
 
+       sieve/sieve-extensions.h, src/lib-sieve/sieve-generator.c, src/lib-
6143
 
+       sieve/sieve-match-types.c, src/lib-sieve/sieve-validator.c:
6144
 
+       Removed much code duplication between extensions that provide
6145
 
+       support for further extension.
6146
 
+       [3009bde82cd7]
6147
 
+
6148
 
+2007-12-27  Stephan Bosch  <stephan@rename-it.nl>
6149
 
+
6150
 
+       * src/lib-sieve/plugins/comparator-i-ascii-numeric/ext-cmp-i-ascii-
6151
 
+       numeric.c, src/lib-sieve/plugins/regex/ext-regex.c, src/lib-
6152
 
+       sieve/plugins/relational/ext-relational.c, src/lib-
6153
 
+       sieve/plugins/subaddress/ext-subaddress.c, src/lib-sieve/sieve-
6154
 
+       address-parts.c, src/lib-sieve/sieve-address-parts.h, src/lib-sieve
6155
 
+       /sieve-code.c, src/lib-sieve/sieve-comparators.c, src/lib-sieve
6156
 
+       /sieve-comparators.h, src/lib-sieve/sieve-extensions-private.h, src
6157
 
+       /lib-sieve/sieve-match-types.c, src/lib-sieve/sieve-match-types.h:
6158
 
+       Further migrated implementation of extensions to new extension
6159
 
+       architecture.
6160
 
+       [4ac0b9e8635c]
6161
 
+
6162
 
+       * src/lib-sieve/cmd-discard.c, src/lib-sieve/cmd-if.c, src/lib-sieve
6163
 
+       /cmd-keep.c, src/lib-sieve/cmd-redirect.c, src/lib-sieve/ext-
6164
 
+       encoded-character.c, src/lib-sieve/ext-envelope.c, src/lib-sieve
6165
 
+       /ext-fileinto.c, src/lib-sieve/ext-reject.c, src/lib-
6166
 
+       sieve/plugins/body/ext-body.c, src/lib-sieve/plugins/body/tst-
6167
 
+       body.c, src/lib-sieve/plugins/comparator-i-ascii-numeric/ext-cmp-i
6168
 
+       -ascii-numeric.c, src/lib-sieve/plugins/copy/copy.sieve, src/lib-
6169
 
+       sieve/plugins/copy/ext-copy.c, src/lib-sieve/plugins/imapflags/cmd-
6170
 
+       addflag.c, src/lib-sieve/plugins/imapflags/cmd-removeflag.c, src
6171
 
+       /lib-sieve/plugins/imapflags/cmd-setflag.c, src/lib-
6172
 
+       sieve/plugins/imapflags/ext-imapflags-common.c, src/lib-
6173
 
+       sieve/plugins/imapflags/ext-imapflags-common.h, src/lib-
6174
 
+       sieve/plugins/imapflags/ext-imapflags.c, src/lib-
6175
 
+       sieve/plugins/imapflags/tag-flags.c, src/lib-sieve/plugins/imapflags
6176
 
+       /tst-hasflag.c, src/lib-sieve/plugins/include/cmd-include.c, src
6177
 
+       /lib-sieve/plugins/include/cmd-return.c, src/lib-
6178
 
+       sieve/plugins/include/ext-include-common.h, src/lib-
6179
 
+       sieve/plugins/include/ext-include.c, src/lib-sieve/plugins/regex
6180
 
+       /ext-regex.c, src/lib-sieve/plugins/relational/ext-relational.c, src
6181
 
+       /lib-sieve/plugins/subaddress/ext-subaddress.c, src/lib-
6182
 
+       sieve/plugins/vacation/ext-vacation.c, src/lib-
6183
 
+       sieve/plugins/variables/cmd-set.c, src/lib-sieve/plugins/variables
6184
 
+       /ext-variables-common.h, src/lib-sieve/plugins/variables/ext-
6185
 
+       variables.c, src/lib-sieve/plugins/variables/tst-string.c, src/lib-
6186
 
+       sieve/sieve-actions.c, src/lib-sieve/sieve-actions.h, src/lib-sieve
6187
 
+       /sieve-address-parts.c, src/lib-sieve/sieve-binary.c, src/lib-sieve
6188
 
+       /sieve-binary.h, src/lib-sieve/sieve-code-dumper.c, src/lib-sieve
6189
 
+       /sieve-code-dumper.h, src/lib-sieve/sieve-code.c, src/lib-sieve
6190
 
+       /sieve-code.h, src/lib-sieve/sieve-commands.c, src/lib-sieve/sieve-
6191
 
+       common.h, src/lib-sieve/sieve-comparators.c, src/lib-sieve/sieve-
6192
 
+       extensions-private.h, src/lib-sieve/sieve-extensions.c, src/lib-
6193
 
+       sieve/sieve-extensions.h, src/lib-sieve/sieve-generator.c, src/lib-
6194
 
+       sieve/sieve-generator.h, src/lib-sieve/sieve-interpreter.c, src/lib-
6195
 
+       sieve/sieve-match-types.c, src/lib-sieve/sieve-validator.c, src/lib-
6196
 
+       sieve/sieve.c, src/lib-sieve/tst-address.c, src/lib-sieve/tst-
6197
 
+       allof.c, src/lib-sieve/tst-anyof.c, src/lib-sieve/tst-exists.c, src
6198
 
+       /lib-sieve/tst-header.c, src/lib-sieve/tst-size.c:
6199
 
+       Major changes in the extensions support.
6200
 
+       [8b74028295fd]
6201
 
+
6202
 
+2007-12-26  Stephan Bosch  <stephan@rename-it.nl>
6203
 
+
6204
 
+       * src/lib-sieve/sieve-address-parts.c, src/lib-sieve/sieve-address-
6205
 
+       parts.h, src/lib-sieve/sieve-ast.h, src/lib-sieve/sieve-commands.c,
6206
 
+       src/lib-sieve/sieve-commands.h, src/lib-sieve/sieve-comparators.c,
6207
 
+       src/lib-sieve/sieve-comparators.h, src/lib-sieve/sieve-match-
6208
 
+       types.c, src/lib-sieve/sieve-match-types.h, src/lib-sieve/sieve-
6209
 
+       validator.c, src/lib-sieve/sieve-validator.h:
6210
 
+       Changed implementation of command context handling and instanced
6211
 
+       tags to avoid duplicate lookups.
6212
 
+       [74d12bfed7c8]
6213
 
+
6214
 
+       * src/lib-sieve/plugins/variables/Makefile.am, src/lib-
6215
 
+       sieve/plugins/variables/cmd-set.c, src/lib-sieve/plugins/variables
6216
 
+       /ext-variables-common.c, src/lib-sieve/plugins/variables/ext-
6217
 
+       variables-common.h, src/lib-sieve/plugins/variables/ext-variables.c,
6218
 
+       src/lib-sieve/plugins/variables/tst-string.c, src/lib-
6219
 
+       sieve/plugins/variables/variables.sieve:
6220
 
+       Further developed the variables extension.
6221
 
+       [492938049fc1]
6222
 
+
6223
 
+2007-12-25  Stephan Bosch  <stephan@rename-it.nl>
6224
 
+
6225
 
+       * README, configure.in, src/lib-sieve/Makefile.am, src/lib-
6226
 
+       sieve/plugins/Makefile.am, src/lib-
6227
 
+       sieve/plugins/variables/Makefile.am, src/lib-sieve/plugins/variables
6228
 
+       /draft-ietf-sieve-variables-08.txt, src/lib-sieve/plugins/variables
6229
 
+       /ext-variables.c, src/lib-sieve/plugins/variables/variables.sieve,
6230
 
+       src/lib-sieve/sieve-extensions.c:
6231
 
+       Started skeleton implementation of variables extension.
6232
 
+       [cac5b0cdb8e6]
6233
 
+
6234
 
+       * sieve/tests/encoded-character.sieve, src/lib-sieve/ext-encoded-
6235
 
+       character.c:
6236
 
+       Fixed non-standard behavior for the encoded-character extension.
6237
 
+       [6900d4693821]
6238
 
+
6239
 
+       * README, sieve/errors/encoded-character.sieve, sieve/tests/encoded-
6240
 
+       character.sieve, src/lib-sieve/ext-encoded-character.c, src/lib-
6241
 
+       sieve/ext-envelope.c, src/lib-sieve/ext-fileinto.c, src/sieve-bin
6242
 
+       /mail-raw.c:
6243
 
+       Finished encoded-character extension.
6244
 
+       [dd6a814d5350]
6245
 
+
6246
 
+       * doc/rfc/rfc3629.txt:
6247
 
+       Added UTF-8 rfc to doc/rfc directory.
6248
 
+       [772db2c40fd1]
6249
 
+
6250
 
+       * sieve/tests/encoded-character.sieve, src/lib-sieve/ext-encoded-
6251
 
+       character.c, src/lib-sieve/sieve-validator.c:
6252
 
+       Built a little more extensive tests for the encoded-character
6253
 
+       extension.
6254
 
+       [f6cba45b3299]
6255
 
+
6256
 
+2007-12-24  Stephan Bosch  <stephan@rename-it.nl>
6257
 
+
6258
 
+       * sieve/tests/encoded-character.sieve, src/lib-sieve/cmd-redirect.c,
6259
 
+       src/lib-sieve/ext-encoded-character.c, src/lib-sieve/ext-envelope.c,
6260
 
+       src/lib-sieve/ext-fileinto.c, src/lib-sieve/ext-reject.c, src/lib-
6261
 
+       sieve/plugins/body/tst-body.c, src/lib-sieve/plugins/imapflags/ext-
6262
 
+       imapflags-common.c, src/lib-sieve/plugins/imapflags/tst-hasflag.c,
6263
 
+       src/lib-sieve/plugins/vacation/ext-vacation.c, src/lib-sieve/sieve-
6264
 
+       ast.h, src/lib-sieve/sieve-validator.c, src/lib-sieve/sieve-
6265
 
+       validator.h, src/lib-sieve/tst-address.c, src/lib-sieve/tst-
6266
 
+       exists.c, src/lib-sieve/tst-header.c, src/lib-sieve/tst-size.c:
6267
 
+       Encoded character extension basicly works, but no unicode support is
6268
 
+       implemented.
6269
 
+       [0c62d3501b83]
6270
 
+
6271
 
+2007-12-19  Stephan Bosch  <stephan@rename-it.nl>
6272
 
+
6273
 
+       * src/lib-sieve/cmd-discard.c, src/lib-sieve/cmd-keep.c, src/lib-sieve
6274
 
+       /cmd-redirect.c, src/lib-sieve/cmd-require.c, src/lib-sieve/ext-
6275
 
+       encoded-character.c, src/lib-sieve/ext-envelope.c, src/lib-sieve
6276
 
+       /ext-fileinto.c, src/lib-sieve/ext-reject.c, src/lib-
6277
 
+       sieve/plugins/body/tst-body.c, src/lib-sieve/plugins/imapflags/cmd-
6278
 
+       addflag.c, src/lib-sieve/plugins/imapflags/cmd-setflag.c, src/lib-
6279
 
+       sieve/plugins/imapflags/ext-imapflags-common.c, src/lib-
6280
 
+       sieve/plugins/imapflags/tag-flags.c, src/lib-sieve/plugins/imapflags
6281
 
+       /tst-hasflag.c, src/lib-sieve/plugins/include/cmd-return.c, src/lib-
6282
 
+       sieve/plugins/vacation/ext-vacation.c, src/lib-sieve/sieve-address-
6283
 
+       parts.c, src/lib-sieve/sieve-ast.h, src/lib-sieve/sieve-code-
6284
 
+       dumper.c, src/lib-sieve/sieve-commands.c, src/lib-sieve/sieve-
6285
 
+       commands.h, src/lib-sieve/sieve-comparators.c, src/lib-sieve/sieve-
6286
 
+       comparators.h, src/lib-sieve/sieve-generator.h, src/lib-sieve/sieve-
6287
 
+       interpreter.c, src/lib-sieve/sieve-parser.h, src/lib-sieve/sieve-
6288
 
+       validator.c, src/lib-sieve/sieve-validator.h, src/lib-sieve/tst-
6289
 
+       address.c, src/lib-sieve/tst-allof.c, src/lib-sieve/tst-anyof.c, src
6290
 
+       /lib-sieve/tst-exists.c, src/lib-sieve/tst-header.c, src/lib-sieve
6291
 
+       /tst-not.c, src/lib-sieve/tst-size.c:
6292
 
+       Implemented support for overriding default argument implementations
6293
 
+       of number, string and string-list.
6294
 
+       [811636f212aa]
6295
 
+
6296
 
+2007-12-18  Stephan Bosch  <stephan@rename-it.nl>
6297
 
+
6298
 
+       * doc/rfc/draft-ietf-sieve-3028bis-13.txt, doc/rfc/rfc3028.txt:
6299
 
+       Added sieve rfc and new sieve 3028bis to the doc/rfc directory.
6300
 
+       [cf0d3511810b]
6301
 
+
6302
 
+       * doc/rfc:
6303
 
+       Removed erroneous rfc file from new doc dir.
6304
 
+       [50462444b677]
6305
 
+
6306
 
+       * doc/rfc, sieve/tests/encoded-character.sieve, src/lib-sieve/ext-
6307
 
+       encoded-character.c:
6308
 
+       Forgot to add new files.
6309
 
+       [ec01147fbf36]
6310
 
+
6311
 
+       * README:
6312
 
+       Updated documentation.
6313
 
+       [d870f0bb6228]
6314
 
+
6315
 
+       * src/lib-sieve/Makefile.am, src/lib-sieve/sieve-extensions.c:
6316
 
+       Started skeleton for the encoded-character extension.
6317
 
+       [915854a9a6e7]
6318
 
+
6319
 
+       * README:
6320
 
+       Updated TODO list.
6321
 
+       [c4f08e56f98f]
6322
 
+
6323
 
+       * README, src/lib-sieve/plugins/body/ext-body.c:
6324
 
+       Updated documentation.
6325
 
+       [7853b0fd8c2f]
6326
 
+
6327
 
+       * src/lib-sieve/plugins/imapflags/cmd-addflag.c, src/lib-
6328
 
+       sieve/plugins/imapflags/cmd-removeflag.c, src/lib-
6329
 
+       sieve/plugins/imapflags/cmd-setflag.c, src/lib-
6330
 
+       sieve/plugins/imapflags/ext-imapflags-common.c, src/lib-
6331
 
+       sieve/plugins/imapflags/ext-imapflags-common.h, src/lib-
6332
 
+       sieve/plugins/imapflags/ext-imapflags.c, src/lib-
6333
 
+       sieve/plugins/imapflags/tst-hasflag.c:
6334
 
+       Changed imapflags extension to use the message context instead of
6335
 
+       the interpreter context.
6336
 
+       [73f99ee08abb]
6337
 
+
6338
 
+       * src/lib-sieve/plugins/body/ext-body-common.c:
6339
 
+       Changed body extension to use the message context instead of the
6340
 
+       interpreter context.
6341
 
+       [c769d7261264]
6342
 
+
6343
 
+       * src/lib-sieve/plugins/include/ext-include-common.c, src/lib-sieve
6344
 
+       /sieve-interpreter.c, src/lib-sieve/sieve-interpreter.h:
6345
 
+       Introduced message context to give extensions the ability to
6346
 
+       associate context data with the currently processed message.
6347
 
+       [08a085d3c1b9]
6348
 
+
6349
 
+       * README, src/lib-sieve/plugins/body/ext-body.c:
6350
 
+       Updated documentation.
6351
 
+       [d47f4b7439d2]
6352
 
+
6353
 
+       * src/lib-sieve/plugins/body/body.sieve, src/lib-sieve/plugins/body
6354
 
+       /ext-body-common.c, src/lib-sieve/plugins/body/tst-body.c:
6355
 
+       Fixed minor bug in the body extension.
6356
 
+       [c8ea2fb589cc]
6357
 
+
6358
 
+       * AUTHORS, src/lib-sieve/plugins/body/Makefile.am, src/lib-
6359
 
+       sieve/plugins/body/body.sieve, src/lib-sieve/plugins/body/ext-body-
6360
 
+       common.c, src/lib-sieve/plugins/body/ext-body-common.h, src/lib-
6361
 
+       sieve/plugins/body/ext-body.c, src/lib-sieve/plugins/body/tst-
6362
 
+       body.c, src/lib-sieve/plugins/imapflags/tst-hasflag.c, src/lib-sieve
6363
 
+       /sieve-address-parts.c, src/lib-sieve/sieve-match-types.c, src/lib-
6364
 
+       sieve/sieve-match-types.h, src/lib-sieve/tst-header.c:
6365
 
+       Implemented evaluation for the body test introduced by the body
6366
 
+       extension.
6367
 
+       [7dc23ed0c79f]
6368
 
+
6369
 
+       * src/lib-sieve/plugins/body/ext-body.c, src/lib-sieve/sieve-
6370
 
+       extensions.c, src/lib-sieve/sieve-generator.c, src/lib-sieve/sieve-
6371
 
+       generator.h:
6372
 
+       Implemented validation and code generation for body extension.
6373
 
+       [24a83b8759f7]
6374
 
+
6375
 
+       * README, configure.in, src/lib-sieve/Makefile.am, src/lib-
6376
 
+       sieve/plugins/Makefile.am, src/lib-sieve/plugins/body/Makefile.am,
6377
 
+       src/lib-sieve/plugins/body/draft-ietf-sieve-body-07.txt, src/lib-
6378
 
+       sieve/plugins/body/ext-body.c:
6379
 
+       Started skeleton for the body extension.
6380
 
+       [87141cd62e03]
6381
 
+
6382
 
+       * README, src/lib-sieve/plugins/include/ext-include.c:
6383
 
+       Updated documentation.
6384
 
+       [ebdc3d4b1ebb]
6385
 
+
6386
 
+       * src/lib-sieve/plugins/include/cmd-include.c, src/lib-
6387
 
+       sieve/plugins/include/cmd-return.c, src/lib-sieve/plugins/include
6388
 
+       /ext-include-common.c, src/lib-sieve/plugins/include/ext-include-
6389
 
+       common.h, src/lib-sieve/plugins/include/included2.sieve, src/lib-
6390
 
+       sieve/sieve-binary.c:
6391
 
+       Implemented return command for include extension.
6392
 
+       [2ecc3c3f89cf]
6393
 
+
6394
 
+       * src/lib-sieve/plugins/include/cmd-include.c, src/lib-
6395
 
+       sieve/plugins/include/ext-include-common.c, src/lib-
6396
 
+       sieve/plugins/include/ext-include-common.h, src/lib-
6397
 
+       sieve/plugins/include/ext-include.c, src/lib-sieve/sieve-binary.c,
6398
 
+       src/lib-sieve/sieve-binary.h, src/lib-sieve/sieve-error.c:
6399
 
+       Basic include functionality seems to be working and if source
6400
 
+       scripts are changed the binary is always recompiled.
6401
 
+       [4d87cc13eb79]
6402
 
+
6403
 
+2007-12-16  Stephan Bosch  <stephan@rename-it.nl>
6404
 
+
6405
 
+       * src/lib-sieve/plugins/include/ext-include-common.c, src/lib-
6406
 
+       sieve/plugins/include/ext-include.c, src/lib-sieve/sieve-binary.c,
6407
 
+       src/lib-sieve/sieve-binary.h, src/lib-sieve/sieve-script.c, src/lib-
6408
 
+       sieve/sieve-script.h, src/lib-sieve/sieve.c:
6409
 
+       Working towards proper dependency handling for sieve binaries.
6410
 
+       [7055341a175d]
6411
 
+
6412
 
+       * src/lib-sieve/sieve-binary.c:
6413
 
+       Added support for lazy binary load.
6414
 
+       [443f611ba331]
6415
 
+
6416
 
+2007-12-15  Stephan Bosch  <stephan@rename-it.nl>
6417
 
+
6418
 
+       * src/lib-sieve/plugins/include/ext-include-common.c, src/lib-
6419
 
+       sieve/plugins/include/ext-include-common.h, src/lib-sieve/sieve-
6420
 
+       binary.c:
6421
 
+       Added internal support for different methods of loading a binary.
6422
 
+       [06efb6d54463]
6423
 
+
6424
 
+       * src/lib-sieve/plugins/include/cmd-include.c, src/lib-
6425
 
+       sieve/plugins/include/ext-include-common.c, src/lib-
6426
 
+       sieve/plugins/include/ext-include-common.h, src/lib-
6427
 
+       sieve/plugins/include/ext-include.c, src/lib-sieve/sieve-binary.c,
6428
 
+       src/lib-sieve/sieve-binary.h, src/lib-sieve/sieve.c, src/sieve-
6429
 
+       bin/sieved.c:
6430
 
+       Working towards complete binary support for the include extension.
6431
 
+       [1f60d0e233a2]
6432
 
+
6433
 
+2007-12-14  Stephan Bosch  <stephan@rename-it.nl>
6434
 
+
6435
 
+       * README:
6436
 
+       Updated documentation.
6437
 
+       [cd70b1e8764f]
6438
 
+
6439
 
+       * src/lib-sieve/plugins/include/ext-include-common.c, src/lib-
6440
 
+       sieve/plugins/include/included2.sieve, src/lib-sieve/sieve-binary.c,
6441
 
+       src/lib-sieve/sieve-interpreter.c:
6442
 
+       Fixed bug regarding stop command in combination with include
6443
 
+       extension.
6444
 
+       [84c480ec5cd3]
6445
 
+
6446
 
+       * src/lib-sieve/plugins/include/ext-include-common.c:
6447
 
+       Simplified the include loop a little.
6448
 
+       [e930ac1deb4e]
6449
 
+
6450
 
+       * src/lib-sieve/plugins/include/ext-include-common.c, src/lib-
6451
 
+       sieve/plugins/include/include.sieve, src/lib-
6452
 
+       sieve/plugins/include/included2.sieve, src/lib-sieve/sieve-binary.c,
6453
 
+       src/lib-sieve/sieve-binary.h:
6454
 
+       Implemented mostly untested deep-level include execution support.
6455
 
+       [c88db860a282]
6456
 
+
6457
 
+2007-12-13  Stephan Bosch  <stephan@rename-it.nl>
6458
 
+
6459
 
+       * src/lib-sieve/plugins/include/cmd-include.c, src/lib-
6460
 
+       sieve/plugins/include/ext-include-common.c, src/lib-
6461
 
+       sieve/plugins/include/ext-include-common.h, src/lib-
6462
 
+       sieve/plugins/include/ext-include.c, src/lib-sieve/sieve-
6463
 
+       interpreter.c, src/lib-sieve/sieve-interpreter.h, src/lib-
6464
 
+       sieve/sieve.c:
6465
 
+       First successful (single level) execution of four consecutive
6466
 
+       includes.
6467
 
+       [5f1564b65675]
6468
 
+
6469
 
+       * src/lib-sieve/plugins/include/ext-include-common.c, src/lib-sieve
6470
 
+       /sieve-commands.c, src/lib-sieve/sieve-interpreter.c, src/lib-sieve
6471
 
+       /sieve-interpreter.h:
6472
 
+       Added support for interrupting an interpreter and continuing
6473
 
+       execution later.
6474
 
+       [1af35588edfc]
6475
 
+
6476
 
+       * src/lib-sieve/plugins/imapflags/ext-imapflags.c, src/lib-
6477
 
+       sieve/plugins/include/cmd-include.c, src/lib-sieve/plugins/include
6478
 
+       /ext-include-common.c, src/lib-sieve/plugins/include/ext-include-
6479
 
+       common.h, src/lib-sieve/plugins/include/ext-include.c:
6480
 
+       Include extension now generates include opcode. Not executable yet
6481
 
+       though.
6482
 
+       [ac8496b3d19c]
6483
 
+
6484
 
+       * src/lib-sieve/sieve-binary.c:
6485
 
+       Implemented the binary_free event for binary extensions. Script
6486
 
+       references in the include extension are now properly released.
6487
 
+       [d0a0bbdaf6b0]
6488
 
+
6489
 
+       * src/lib-sieve/plugins/include/ext-include-common.c, src/lib-
6490
 
+       sieve/plugins/include/ext-include-common.h, src/lib-
6491
 
+       sieve/plugins/include/ext-include.c, src/lib-sieve/sieve-binary.c,
6492
 
+       src/lib-sieve/sieve-binary.h, src/lib-sieve/sieve-common.h:
6493
 
+       Fixed behavior of binary object with respect to pre-loaded
6494
 
+       extensons. Broke it with last change.
6495
 
+       [ce0e32e63adc]
6496
 
+
6497
 
+       * src/lib-sieve/sieve-binary.c, src/lib-sieve/sieve-binary.h, src/lib-
6498
 
+       sieve/sieve-extensions.c, src/lib-sieve/sieve-extensions.h:
6499
 
+       Changed binary object's extension linkage for extending the binary
6500
 
+       itself.
6501
 
+       [5633827bd892]
6502
 
+
6503
 
+2007-12-11  Stephan Bosch  <stephan@rename-it.nl>
6504
 
+
6505
 
+       * src/lib-sieve/plugins/include/ext-include-common.c, src/lib-
6506
 
+       sieve/plugins/include/ext-include-common.h, src/lib-
6507
 
+       sieve/plugins/include/ext-include.c, src/lib-sieve/sieve-script.c,
6508
 
+       src/lib-sieve/sieve-script.h:
6509
 
+       Doubly included scripts are no longer compiled and included multiple
6510
 
+       times.
6511
 
+       [64ffbd9afaaa]
6512
 
+
6513
 
+       * src/lib-sieve/plugins/include/included1.sieve, src/lib-sieve/sieve-
6514
 
+       binary.c:
6515
 
+       Forgot to set the number of blocks in the binary header.
6516
 
+       [69967868a8cc]
6517
 
+
6518
 
+       * src/lib-sieve/plugins/include/ext-include-common.c, src/lib-
6519
 
+       sieve/plugins/include/included1.sieve:
6520
 
+       Re-established circular include detection for include extension.
6521
 
+       [e8867e044d2c]
6522
 
+
6523
 
+       * src/lib-sieve/plugins/include/ext-include-common.c, src/lib-
6524
 
+       sieve/plugins/include/included1.sieve, src/lib-sieve/sieve-binary.c,
6525
 
+       src/lib-sieve/sieve-generator.c, src/lib-sieve/sieve-generator.h,
6526
 
+       src/lib-sieve/sieve.c:
6527
 
+       Further developed the include extension to compile included scripts
6528
 
+       in additional blocks of the binary.
6529
 
+       [6d0b5b112f00]
6530
 
+
6531
 
+2007-12-10  Stephan Bosch  <stephan@rename-it.nl>
6532
 
+
6533
 
+       * src/lib-sieve/sieve-binary.c, src/lib-sieve/sieve-binary.h, src/lib-
6534
 
+       sieve/sieve-generator.c, src/lib-sieve/sieve-generator.h, src/lib-
6535
 
+       sieve/sieve.c:
6536
 
+       Further developed the binary format: binary can now contain multiple
6537
 
+       blocks with arbitrary data.
6538
 
+       [958ac41805fc]
6539
 
+
6540
 
+       * README:
6541
 
+       Updated documentation: Changed priorities in TODO list.
6542
 
+       [c27f92353192]
6543
 
+
6544
 
+       * README:
6545
 
+       Updated documentation.
6546
 
+       [b1b5f7d6ff6c]
6547
 
+
6548
 
+2007-12-09  Stephan Bosch  <stephan@rename-it.nl>
6549
 
+
6550
 
+       * src/lib-sieve/plugins/include/cmd-include.c, src/lib-
6551
 
+       sieve/plugins/include/ext-include-common.c, src/lib-
6552
 
+       sieve/plugins/include/ext-include-common.h, src/lib-
6553
 
+       sieve/plugins/include/ext-include.c, src/lib-
6554
 
+       sieve/plugins/include/included1.sieve, src/lib-sieve/sieve-ast.c,
6555
 
+       src/lib-sieve/sieve-ast.h, src/lib-sieve/sieve-binary.c, src/lib-
6556
 
+       sieve/sieve-binary.h, src/lib-sieve/sieve-commands.h, src/lib-sieve
6557
 
+       /sieve-error.h, src/lib-sieve/sieve-generator.c, src/lib-sieve
6558
 
+       /sieve-generator.h, src/lib-sieve/sieve-script.c, src/lib-sieve
6559
 
+       /sieve-validator.c, src/lib-sieve/sieve-validator.h, src/lib-
6560
 
+       sieve/sieve.c, src/sieve-bin/sieved.c:
6561
 
+       Moved actual include operation from validator to generator stage.
6562
 
+       [c49356652255]
6563
 
+
6564
 
+       * .hgignore, src/lib-sieve/sieve-binary.c, src/lib-sieve/sieve-
6565
 
+       script.c, src/lib-sieve/sieve-script.h, src/lib-sieve/sieve.c, src
6566
 
+       /lib-sieve/sieve.h, src/sieve-bin/bin-common.c, src/sieve-bin/bin-
6567
 
+       common.h, src/sieve-bin/sieve-exec.c, src/sieve-bin/sieve-test.c,
6568
 
+       src/sieve-bin/sievec.c:
6569
 
+       Sieve executables now work with binaries too.
6570
 
+       [8e7a1b3c0ad9]
6571
 
+
6572
 
+       * .hgignore, src/lib-sieve/sieve-binary.c, src/lib-sieve/sieve-
6573
 
+       binary.h, src/lib-sieve/sieve-code.c, src/lib-sieve/sieve-
6574
 
+       extensions.c, src/lib-sieve/sieve-extensions.h, src/lib-sieve/sieve-
6575
 
+       generator.c, src/lib-sieve/sieve-script.c, src/sieve-
6576
 
+       bin/Makefile.am, src/sieve-bin/sievec.c, src/sieve-bin/sieved.c:
6577
 
+       Made a basic implementation of saving binaries to disk.
6578
 
+       [60a7a53897cf]
6579
 
+
6580
 
+2007-12-08  Stephan Bosch  <stephan@rename-it.nl>
6581
 
+
6582
 
+       * src/lib-sieve/plugins/include/ext-include-common.c, src/lib-
6583
 
+       sieve/plugins/include/include.sieve, src/lib-
6584
 
+       sieve/plugins/include/included2.sieve, src/lib-sieve/sieve-ast.c,
6585
 
+       src/lib-sieve/sieve-ast.h, src/lib-sieve/sieve-parser.c, src/lib-
6586
 
+       sieve/sieve.c:
6587
 
+       Cleaned up ast implementation a little.
6588
 
+       [82fb78a39773]
6589
 
+
6590
 
+       * src/lib-sieve/plugins/include/ext-include-common.c, src/lib-
6591
 
+       sieve/plugins/include/included2.sieve, src/lib-
6592
 
+       sieve/plugins/include/included3.sieve, src/lib-sieve/sieve.c:
6593
 
+       Prevented more scripts from being included when errors have occured.
6594
 
+       [fade5794fecf]
6595
 
+
6596
 
+       * src/lib-sieve/plugins/include/cmd-include.c, src/lib-
6597
 
+       sieve/plugins/include/ext-include-common.c, src/lib-
6598
 
+       sieve/plugins/include/ext-include-common.h, src/lib-
6599
 
+       sieve/plugins/include/included3.sieve, src/lib-sieve/sieve-lexer.c,
6600
 
+       src/lib-sieve/sieve-script.c, src/lib-sieve/sieve-script.h, src/lib-
6601
 
+       sieve/sieve.c:
6602
 
+       Properly implemented circular include detection for the include
6603
 
+       extension.
6604
 
+       [d3b8e1347bb5]
6605
 
+
6606
 
+       * src/lib-sieve/Makefile.am, src/lib-
6607
 
+       sieve/plugins/include/Makefile.am, src/lib-sieve/plugins/include
6608
 
+       /cmd-include.c, src/lib-sieve/plugins/include/ext-include-common.c,
6609
 
+       src/lib-sieve/plugins/include/ext-include-common.h, src/lib-
6610
 
+       sieve/plugins/include/ext-include.c, src/lib-
6611
 
+       sieve/plugins/include/include.sieve, src/lib-
6612
 
+       sieve/plugins/include/included1.sieve, src/lib-
6613
 
+       sieve/plugins/include/included2.sieve, src/lib-
6614
 
+       sieve/plugins/include/included3.sieve, src/lib-sieve/sieve-ast.c,
6615
 
+       src/lib-sieve/sieve-ast.h, src/lib-sieve/sieve-commands.h, src/lib-
6616
 
+       sieve/sieve-common.h, src/lib-sieve/sieve-error.c, src/lib-sieve
6617
 
+       /sieve-error.h, src/lib-sieve/sieve-lexer.c, src/lib-sieve/sieve-
6618
 
+       lexer.h, src/lib-sieve/sieve-parser.c, src/lib-sieve/sieve-parser.h,
6619
 
+       src/lib-sieve/sieve-script.c, src/lib-sieve/sieve-script.h, src/lib-
6620
 
+       sieve/sieve-validator.c, src/lib-sieve/sieve-validator.h, src/lib-
6621
 
+       sieve/sieve.c, src/lib-sieve/sieve.h:
6622
 
+       First defined an encapsulating script object and implemented part of
6623
 
+       the include extension.
6624
 
+       [20278c7b7254]
6625
 
+
6626
 
+2007-12-07  Stephan Bosch  <stephan@rename-it.nl>
6627
 
+
6628
 
+       * README, configure.in, src/lib-sieve/Makefile.am, src/lib-
6629
 
+       sieve/plugins/Makefile.am, src/lib-
6630
 
+       sieve/plugins/include/Makefile.am, src/lib-sieve/plugins/include
6631
 
+       /cmd-include.c, src/lib-sieve/plugins/include/cmd-return.c, src/lib-
6632
 
+       sieve/plugins/include/draft-daboo-sieve-include-05.txt, src/lib-
6633
 
+       sieve/plugins/include/ext-include-common.h, src/lib-
6634
 
+       sieve/plugins/include/ext-include.c, src/lib-
6635
 
+       sieve/plugins/include/include.sieve, src/lib-sieve/sieve-
6636
 
+       extensions.c:
6637
 
+       Started skeleton implementation for the include extension.
6638
 
+       [fae946e07bd2]
6639
 
+
6640
 
+       * README, src/lib-sieve/plugins/vacation/ext-vacation.c:
6641
 
+       Updated documentation.
6642
 
+       [3ffe74253949]
6643
 
+
6644
 
+2007-12-06  Stephan Bosch  <stephan@rename-it.nl>
6645
 
+
6646
 
+       * sieve/tests/vacation.sieve, src/lib-sieve/plugins/vacation/ext-
6647
 
+       vacation.c:
6648
 
+       Added :addresses support to the vacation extension.
6649
 
+       [22045e56dec8]
6650
 
+
6651
 
+       * src/lib-sieve/ext-envelope.c, src/lib-sieve/plugins/imapflags/cmd-
6652
 
+       addflag.c, src/lib-sieve/plugins/imapflags/cmd-removeflag.c, src
6653
 
+       /lib-sieve/plugins/imapflags/cmd-setflag.c, src/lib-
6654
 
+       sieve/plugins/imapflags/tag-flags.c, src/lib-sieve/sieve-code.c, src
6655
 
+       /lib-sieve/sieve-code.h, src/lib-sieve/tst-address.c, src/lib-sieve
6656
 
+       /tst-exists.c, src/lib-sieve/tst-header.c:
6657
 
+       Added support for reading an entire stringlist into memory. Also
6658
 
+       fixed various identical bugs in stringlist-related error handling.
6659
 
+       [a2ae74cddb58]
6660
 
+
6661
 
+       * README:
6662
 
+       Added two TODO items.
6663
 
+       [5b3f80ba5fa5]
6664
 
+
6665
 
+       * README, src/lib-sieve/plugins/vacation/ext-vacation.c:
6666
 
+       Tiny update to documentation and removed a compiler warning.
6667
 
+       [57bef612b360]
6668
 
+
6669
 
+       * src/lib-sieve/plugins/vacation/ext-vacation.c, src/lib-sieve/sieve-
6670
 
+       generator.c:
6671
 
+       Added :mime support to vacation extension.
6672
 
+       [e0170e8422a7]
6673
 
+
6674
 
+       * src/lib-sieve/cmd-keep.c, src/lib-sieve/cmd-redirect.c, src/lib-
6675
 
+       sieve/ext-reject.c, src/lib-sieve/plugins/vacation/ext-vacation.c,
6676
 
+       src/lib-sieve/sieve-actions.c, src/lib-sieve/sieve-actions.h, src
6677
 
+       /lib-sieve/sieve-interpreter.c, src/lib-sieve/sieve-interpreter.h,
6678
 
+       src/lib-sieve/sieve-result.c, src/lib-sieve/sieve-result.h, src/lib-
6679
 
+       sieve/sieve.c, src/lib-sieve/sieve.h, src/plugins/lda-sieve/lda-
6680
 
+       sieve-plugin.c, src/sieve-bin/sieve-exec.c, src/sieve-bin/sieve-
6681
 
+       test.c:
6682
 
+       Renamed mail_environment to script_env.
6683
 
+       [357df85b1c14]
6684
 
+
6685
 
+       * README, src/lib-sieve/cmd-redirect.c:
6686
 
+       Added mail-loop detection to the redirect action.
6687
 
+       [5208c9de6da9]
6688
 
+
6689
 
+       * src/lib-sieve/sieve-interpreter.c, src/lib-sieve/sieve-
6690
 
+       interpreter.h, src/lib-sieve/sieve-result.c, src/lib-sieve/sieve-
6691
 
+       result.h, src/lib-sieve/sieve.c, src/lib-sieve/sieve.h, src/plugins
6692
 
+       /lda-sieve/lda-sieve-plugin.c, src/sieve-bin/sieve-exec.c:
6693
 
+       Changed execution error handling a little.
6694
 
+       [9bedd7aaed60]
6695
 
+
6696
 
+       * src/lib-sieve/ext-reject.c, src/lib-sieve/sieve-address-parts.c, src
6697
 
+       /lib-sieve/sieve-ast.c, src/lib-sieve/sieve-commands.c, src/lib-
6698
 
+       sieve/sieve-error.c, src/lib-sieve/sieve-error.h, src/lib-sieve
6699
 
+       /sieve-generator.c, src/lib-sieve/sieve-interpreter.c, src/lib-sieve
6700
 
+       /sieve-lexer.c, src/lib-sieve/sieve-parser.c, src/lib-sieve/sieve-
6701
 
+       validator.c:
6702
 
+       Adopted code to use Dovecot's new T_FRAME* macros.
6703
 
+       [7d056b0525a8]
6704
 
+
6705
 
+       * src/lib-sieve/plugins/vacation/ext-vacation.c, src/lib-sieve/sieve-
6706
 
+       code-dumper.h, src/lib-sieve/sieve-error.h, src/lib-sieve/sieve-
6707
 
+       interpreter.h, src/lib-sieve/sieve-lexer.c, src/lib-sieve/sieve-
6708
 
+       parser.c, src/lib-sieve/sieve-result.h, src/lib-sieve/sieve-
6709
 
+       validator.h:
6710
 
+       Added proper ATTR_FORMAT to all functions that accept a string
6711
 
+       format and fixed one bug in the process.
6712
 
+       [ed5bbe4892fe]
6713
 
+
6714
 
+       * README:
6715
 
+       Further updated documentation and cleaned up the README file.
6716
 
+       [34dd6d80f884]
6717
 
+
6718
 
+       * INSTALL, README:
6719
 
+       Updated documentation. We are gettin closer to a first release.
6720
 
+       [ba0d6c952726]
6721
 
+
6722
 
+       * src/lib-sieve/ext-fileinto.c, src/lib-sieve/sieve-interpreter.c, src
6723
 
+       /lib-sieve/sieve-result.c, src/sieve-bin/bin-common.c, src/sieve-bin
6724
 
+       /sieve-exec.c:
6725
 
+       Implemented implicit keep to execute when not canceled or when the
6726
 
+       preceeding action execution fails.
6727
 
+       [83139c099737]
6728
 
+
6729
 
+2007-12-05  Stephan Bosch  <stephan@rename-it.nl>
6730
 
+
6731
 
+       * src/lib-sieve/sieve-error.c, src/lib-sieve/sieve-interpreter.c:
6732
 
+       Fixed minor bugs in the error reporting.
6733
 
+       [3cf617a5c19b]
6734
 
+
6735
 
+       * src/plugins/lda-sieve/lda-sieve-plugin.c:
6736
 
+       Fixed tiny bug in the error reporting in the lda-sieve plugin.
6737
 
+       [dd6d34c328e0]
6738
 
+
6739
 
+       * src/lib-sieve/sieve-error.c, src/lib-sieve/sieve-error.h, src/lib-
6740
 
+       sieve/sieve-interpreter.c, src/lib-sieve/sieve-interpreter.h, src
6741
 
+       /lib-sieve/sieve-result.c, src/lib-sieve/sieve-result.h, src/lib-
6742
 
+       sieve/sieve.c, src/lib-sieve/sieve.h, src/plugins/lda-sieve/lda-
6743
 
+       sieve-plugin.c, src/sieve-bin/sieve-exec.c, src/sieve-bin/sieve-
6744
 
+       test.c:
6745
 
+       Further developed the error handling.
6746
 
+       [b440e2ecb968]
6747
 
+
6748
 
+2007-12-04  Stephan Bosch  <stephan@rename-it.nl>
6749
 
+
6750
 
+       * src/plugins/lda-sieve/lda-sieve-plugin.c:
6751
 
+       Added a little more error logging to the lda-sieve plugin.
6752
 
+       [22100a6b83a0]
6753
 
+
6754
 
+       * src/lib-sieve/sieve-error.c, src/lib-sieve/sieve-error.h,
6755
 
+       src/plugins/lda-sieve/lda-sieve-plugin.c:
6756
 
+       Implemented logfile error handler and assigned it to the lda-sieve
6757
 
+       plugin.
6758
 
+       [1dd0d188e90d]
6759
 
+
6760
 
+2007-12-03  Stephan Bosch  <stephan@rename-it.nl>
6761
 
+
6762
 
+       * src/lib-sieve/sieve-ast.c, src/lib-sieve/sieve-ast.h, src/lib-sieve
6763
 
+       /sieve-error.c, src/lib-sieve/sieve-error.h, src/lib-sieve/sieve-
6764
 
+       lexer.c, src/lib-sieve/sieve-lexer.h, src/lib-sieve/sieve-parser.c,
6765
 
+       src/lib-sieve/sieve-parser.h, src/lib-sieve/sieve-validator.c, src
6766
 
+       /lib-sieve/sieve.c, src/lib-sieve/sieve.h, src/plugins/lda-sieve
6767
 
+       /lda-sieve-plugin.c, src/sieve-bin/bin-common.c, src/sieve-
6768
 
+       bin/sievec.c:
6769
 
+       Further developed error handling.
6770
 
+       [38b7c79a1bc9]
6771
 
+
6772
 
+2007-12-02  Stephan Bosch  <stephan@rename-it.nl>
6773
 
+
6774
 
+       * src/plugins/lda-sieve/lda-sieve-plugin.c:
6775
 
+       Forgot to initialize sieve library in lda-sieve plugin. It has now
6776
 
+       successfully delivered its first message.
6777
 
+       [0bb383b96a44]
6778
 
+
6779
 
+       * src/plugins/lda-sieve/lda-sieve-plugin.c, src/plugins/lda-sieve/lda-
6780
 
+       sieve-plugin.h:
6781
 
+       Fixed misnamed module entry points for the lda-sieve plugin.
6782
 
+       [b8b366a08231]
6783
 
+
6784
 
+       * configure.in, src/Makefile.am, src/lib-sieve/sieve.c, src/lib-
6785
 
+       sieve/sieve.h, src/plugins/lda-sieve/Makefile.am, src/plugins/lda-
6786
 
+       sieve/lda-sieve-plugin.c, src/plugins/lda-sieve/lda-sieve-plugin.h,
6787
 
+       src/sieve-bin/bin-common.c:
6788
 
+       Included sieve plugin into the build process.
6789
 
+       [0eee6014369f]
6790
 
+
6791
 
+       * README, src/lib-sieve/ext-fileinto.c, src/lib-sieve/ext-reject.c,
6792
 
+       src/lib-sieve/plugins/vacation/ext-vacation.c, src/lib-
6793
 
+       sieve/sieve.c, src/lib-sieve/sieve.h, src/plugins/lda-sieve/lda-
6794
 
+       sieve-plugin.c, src/sieve-bin/sievec.c:
6795
 
+       Documentation updates.
6796
 
+       [f48f95ebfcad]
6797
 
+
6798
 
+       * src/lib-sieve/plugins/imapflags/tag-flags.c, src/lib-sieve/sieve-
6799
 
+       actions.c, src/lib-sieve/sieve-code-dumper.c, src/lib-sieve/sieve-
6800
 
+       error.c, src/lib-sieve/sieve-validator.c, src/lib-sieve/sieve.c, src
6801
 
+       /lib-sieve/sieve.h, src/sieve-bin/bin-common.c, src/sieve-bin/bin-
6802
 
+       common.h, src/sieve-bin/sieve-exec.c, src/sieve-bin/sieve-test.c,
6803
 
+       src/sieve-bin/sievec.c:
6804
 
+       Implemented sieve test binaries further. They now have proper
6805
 
+       command line arguments.
6806
 
+       [c1e500086b9c]
6807
 
+
6808
 
+       * src/sieve-bin/Makefile.am, src/sieve-bin/bin-common.c, src/sieve-bin
6809
 
+       /bin-common.h, src/sieve-bin/sieve-exec.c, src/sieve-bin/sieve-
6810
 
+       test.c, src/sieve-bin/sievec.c:
6811
 
+       Updated and cleaned-up the sieve test binaries.
6812
 
+       [9ed2f2979c35]
6813
 
+
6814
 
+       * src/lib-sieve/cmd-redirect.c, src/lib-sieve/ext-envelope.c, src/lib-
6815
 
+       sieve/ext-fileinto.c, src/lib-sieve/ext-reject.c, src/lib-
6816
 
+       sieve/plugins/copy/ext-copy.c, src/lib-sieve/plugins/imapflags/ext-
6817
 
+       imapflags-common.c, src/lib-sieve/plugins/imapflags/tag-flags.c, src
6818
 
+       /lib-sieve/plugins/imapflags/tst-hasflag.c, src/lib-
6819
 
+       sieve/plugins/vacation/ext-vacation.c, src/lib-sieve/sieve-
6820
 
+       actions.c, src/lib-sieve/sieve-actions.h, src/lib-sieve/sieve-
6821
 
+       address-parts.c, src/lib-sieve/sieve-code-dumper.c, src/lib-sieve
6822
 
+       /sieve-code-dumper.h, src/lib-sieve/sieve-code.c, src/lib-sieve
6823
 
+       /sieve-comparators.c, src/lib-sieve/sieve-interpreter.c, src/lib-
6824
 
+       sieve/sieve-match-types.c, src/lib-sieve/sieve.c, src/lib-
6825
 
+       sieve/sieve.h, src/lib-sieve/tst-address.c, src/lib-sieve/tst-
6826
 
+       exists.c, src/lib-sieve/tst-header.c, src/lib-sieve/tst-size.c, src
6827
 
+       /sieve-bin/sieve-exec.c, src/sieve-bin/sieve-test.c, src/sieve-
6828
 
+       bin/sievec.c:
6829
 
+       Properly implemented the code dumper. Dumps are now printed in a
6830
 
+       stream. The individual opcode and operand implementations no longer
6831
 
+       use printf()s.
6832
 
+       [b68f9e45a6bd]
6833
 
+
6834
 
+       * src/lib-sieve/sieve-code-dumper.c, src/lib-sieve/sieve-code-
6835
 
+       dumper.h:
6836
 
+       Forgot to add new files.
6837
 
+       [3a75f9a2a4ac]
6838
 
+
6839
 
+       * src/lib-sieve/Makefile.am, src/lib-sieve/cmd-redirect.c, src/lib-
6840
 
+       sieve/ext-envelope.c, src/lib-sieve/ext-fileinto.c, src/lib-sieve
6841
 
+       /ext-reject.c, src/lib-sieve/plugins/copy/ext-copy.c, src/lib-
6842
 
+       sieve/plugins/imapflags/ext-imapflags-common.c, src/lib-
6843
 
+       sieve/plugins/imapflags/ext-imapflags-common.h, src/lib-
6844
 
+       sieve/plugins/imapflags/tag-flags.c, src/lib-sieve/plugins/imapflags
6845
 
+       /tst-hasflag.c, src/lib-sieve/plugins/vacation/ext-vacation.c, src
6846
 
+       /lib-sieve/sieve-actions.h, src/lib-sieve/sieve-address-parts.c, src
6847
 
+       /lib-sieve/sieve-address-parts.h, src/lib-sieve/sieve-code.c, src
6848
 
+       /lib-sieve/sieve-code.h, src/lib-sieve/sieve-common.h, src/lib-sieve
6849
 
+       /sieve-comparators.c, src/lib-sieve/sieve-comparators.h, src/lib-
6850
 
+       sieve/sieve-generator.c, src/lib-sieve/sieve-interpreter.c, src/lib-
6851
 
+       sieve/sieve-interpreter.h, src/lib-sieve/sieve-match-types.c, src
6852
 
+       /lib-sieve/sieve-match-types.h, src/lib-sieve/sieve.c, src/lib-sieve
6853
 
+       /tst-address.c, src/lib-sieve/tst-exists.c, src/lib-sieve/tst-
6854
 
+       header.c, src/lib-sieve/tst-size.c:
6855
 
+       Exported sieve-code-dumper from sieve-interpreter containing all
6856
 
+       code dumping related implementation. Now to remove all printfs....
6857
 
+       [ca3bfa6b2284]
6858
 
+
6859
 
+2007-12-01  Stephan Bosch  <stephan@rename-it.nl>
6860
 
+
6861
 
+       * src/lib-sieve/sieve-code.c, src/lib-sieve/sieve-code.h:
6862
 
+       Fixed bug in handling optional operands to opcodes that have no
6863
 
+       mandatory operands (0 is no longer a valid opcode)
6864
 
+       [77e421643cc2]
6865
 
+
6866
 
+       * sieve/errors/action-conflicts.sieve, sieve/errors/action-
6867
 
+       duplicates.sieve, src/lib-sieve/cmd-discard.c, src/lib-sieve/cmd-
6868
 
+       keep.c, src/lib-sieve/cmd-redirect.c, src/lib-sieve/ext-fileinto.c,
6869
 
+       src/lib-sieve/ext-reject.c, src/lib-sieve/plugins/vacation/ext-
6870
 
+       vacation.c, src/lib-sieve/sieve-actions.c, src/lib-sieve/sieve-
6871
 
+       actions.h, src/lib-sieve/sieve-commands-private.h, src/lib-sieve
6872
 
+       /sieve-interpreter.c, src/lib-sieve/sieve-interpreter.h, src/lib-
6873
 
+       sieve/sieve-result.c, src/lib-sieve/sieve-result.h:
6874
 
+       Added conflict and duplicate checking to vacation and reject
6875
 
+       actions.
6876
 
+       [c33bb67f8b09]
6877
 
+
6878
 
+       * sieve/tests/vacation.sieve, src/lib-sieve/cmd-redirect.c, src/lib-
6879
 
+       sieve/ext-reject.c, src/lib-sieve/plugins/vacation/ext-vacation.c,
6880
 
+       src/lib-sieve/sieve-actions.c, src/lib-sieve/sieve-actions.h, src
6881
 
+       /lib-sieve/sieve-address-parts.c, src/lib-sieve/sieve.h, src/sieve-
6882
 
+       bin/sieve-exec.c, src/sieve-bin/sieve-test.c:
6883
 
+       Implemented actions reject and vacation.
6884
 
+       [d34c2fe9ac63]
6885
 
+
6886
 
+       * src/lib-sieve/ext-envelope.c:
6887
 
+       Fixed minor bug in envelope extension.
6888
 
+       [e39957361fed]
6889
 
+
6890
 
+2007-11-30  Stephan Bosch  <stephan@rename-it.nl>
6891
 
+
6892
 
+       * src/lib-sieve/plugins/imapflags/ext-imapflags-common.c, src/lib-
6893
 
+       sieve/plugins/imapflags/ext-imapflags-common.h, src/lib-
6894
 
+       sieve/plugins/imapflags/imapflags.sieve, src/lib-
6895
 
+       sieve/plugins/imapflags/tag-flags.c, src/lib-sieve/sieve-actions.c,
6896
 
+       src/lib-sieve/sieve-actions.h, src/lib-sieve/sieve-result.c, src
6897
 
+       /lib-sieve/sieve-result.h, src/lib-sieve/sieve-validator.c:
6898
 
+       Further developed imapflags extension and added proper logging
6899
 
+       functions to the result object.
6900
 
+       [bc668e541c89]
6901
 
+
6902
 
+2007-11-29  Stephan Bosch  <stephan@rename-it.nl>
6903
 
+
6904
 
+       * src/lib-sieve/plugins/copy/ext-copy.c, src/lib-
6905
 
+       sieve/plugins/imapflags/ext-imapflags.c, src/lib-
6906
 
+       sieve/plugins/imapflags/tag-flags.c, src/lib-sieve/sieve-actions.h,
6907
 
+       src/lib-sieve/sieve-interpreter.c:
6908
 
+       The :flags tag introduced by the imapflags extension now attaches
6909
 
+       side-effects to the appropriate action commands.
6910
 
+       [b3f4220296e2]
6911
 
+
6912
 
+       * README, src/lib-sieve/cmd-discard.c, src/lib-sieve/cmd-keep.c, src
6913
 
+       /lib-sieve/cmd-redirect.c, src/lib-sieve/ext-fileinto.c, src/lib-
6914
 
+       sieve/plugins/copy/ext-copy.c, src/lib-sieve/sieve-actions.c, src
6915
 
+       /lib-sieve/sieve-actions.h, src/lib-sieve/sieve-result.c:
6916
 
+       Properly implemented handling of the implicit keep flag and fully
6917
 
+       implemented the copy extension.
6918
 
+       [24896ebd3e8d]
6919
 
+
6920
 
+       * src/lib-sieve/cmd-keep.c, src/lib-sieve/cmd-redirect.c, src/lib-
6921
 
+       sieve/ext-fileinto.c, src/lib-sieve/plugins/copy/ext-copy.c, src
6922
 
+       /lib-sieve/sieve-actions.c, src/lib-sieve/sieve-actions.h, src/lib-
6923
 
+       sieve/sieve-binary.c, src/lib-sieve/sieve-binary.h, src/lib-sieve
6924
 
+       /sieve-code.c, src/lib-sieve/sieve-common.h, src/lib-sieve/sieve-
6925
 
+       interpreter.c, src/lib-sieve/sieve-interpreter.h, src/lib-sieve
6926
 
+       /sieve-result.c, src/lib-sieve/sieve-result.h:
6927
 
+       Added basic execution support to copy extension. Not completely
6928
 
+       functional yet.
6929
 
+       [8ad6e3739a65]
6930
 
+
6931
 
+       * src/lib-sieve/plugins/copy/ext-copy.c, src/lib-sieve/sieve-
6932
 
+       actions.c, src/lib-sieve/sieve-actions.h, src/lib-sieve/sieve-
6933
 
+       address-parts.c, src/lib-sieve/sieve-binary.h, src/lib-sieve/sieve-
6934
 
+       code.c:
6935
 
+       Added support for reading side effect operands.
6936
 
+       [04e8fa76e983]
6937
 
+
6938
 
+       * src/lib-sieve/plugins/copy/ext-copy.c:
6939
 
+       Added registration of side-effect extension into binary.
6940
 
+       [98c1c9798c08]
6941
 
+
6942
 
+       * src/lib-sieve/plugins/copy/ext-copy.c, src/lib-
6943
 
+       sieve/plugins/imapflags/ext-imapflags.c, src/lib-sieve/sieve-
6944
 
+       actions.c, src/lib-sieve/sieve-actions.h:
6945
 
+       Defined side-effect object for the copy extension.
6946
 
+       [f22e0d5b9788]
6947
 
+
6948
 
+       * src/lib-sieve/plugins/imapflags/tst-hasflag.c, src/lib-
6949
 
+       sieve/plugins/vacation/ext-vacation.c, src/lib-sieve/sieve-address-
6950
 
+       parts.c, src/lib-sieve/sieve-code.c, src/lib-sieve/sieve-code.h, src
6951
 
+       /lib-sieve/sieve-generator.c, src/lib-sieve/tst-header.c:
6952
 
+       Incorporated the signedness of the id_code in the optional_read
6953
 
+       functions as well
6954
 
+       [2923c10f41b9]
6955
 
+
6956
 
+2007-11-28  Stephan Bosch  <stephan@rename-it.nl>
6957
 
+
6958
 
+       * src/lib-sieve/plugins/copy/ext-copy.c, src/lib-sieve/sieve-address-
6959
 
+       parts.c, src/lib-sieve/sieve-address-parts.h, src/lib-sieve/sieve-
6960
 
+       binary.c, src/lib-sieve/sieve-comparators.c, src/lib-sieve/sieve-
6961
 
+       comparators.h, src/lib-sieve/sieve-extensions.c, src/lib-sieve
6962
 
+       /sieve-match-types.c, src/lib-sieve/sieve-match-types.h, src/lib-
6963
 
+       sieve/sieve-validator.c, src/lib-sieve/sieve-validator.h, src/lib-
6964
 
+       sieve/tst-size.c:
6965
 
+       Changed id_code for optional operands to signed and fixed a
6966
 
+       ext_my_id-related error in the vacation and copy extensions.
6967
 
+       [38a9854e21ca]
6968
 
+
6969
 
+       * src/lib-sieve/sieve-actions.c, src/lib-sieve/sieve-actions.h, src
6970
 
+       /lib-sieve/sieve-binary.h, src/lib-sieve/sieve-code.c, src/lib-sieve
6971
 
+       /sieve-code.h, src/lib-sieve/sieve-extensions.c:
6972
 
+       Added operand emission support for action side effects.
6973
 
+       [8b9ba3e6a631]
6974
 
+
6975
 
+       * src/lib-sieve/sieve-actions.c, src/lib-sieve/sieve-actions.h, src
6976
 
+       /lib-sieve/sieve-extensions.c, src/lib-sieve/sieve-extensions.h:
6977
 
+       Created pre-loaded action side effects 'extension'.
6978
 
+       [37a2969e9787]
6979
 
+
6980
 
+       * src/lib-sieve/sieve-address-parts.c, src/lib-sieve/sieve-binary.c,
6981
 
+       src/lib-sieve/sieve-binary.h, src/lib-sieve/sieve-comparators.c, src
6982
 
+       /lib-sieve/sieve-match-types.c:
6983
 
+       Removed part of the code duplication between address-part, match-
6984
 
+       type and comparator implementations.
6985
 
+       [34b4be8738f2]
6986
 
+
6987
 
+       * src/lib-sieve/sieve-actions.h, src/lib-sieve/sieve-common.h, src
6988
 
+       /lib-sieve/sieve-result.c, src/lib-sieve/sieve-result.h:
6989
 
+       Added untested support for side effects to result object.
6990
 
+       [ec22e9a0a06d]
6991
 
+
6992
 
+2007-11-27  Stephan Bosch  <stephan@rename-it.nl>
6993
 
+
6994
 
+       * src/lib-sieve/plugins/copy/ext-copy.c, src/lib-
6995
 
+       sieve/plugins/imapflags/Makefile.am, src/lib-sieve/plugins/imapflags
6996
 
+       /ext-imapflags.c, src/lib-sieve/plugins/imapflags/imapflags.sieve,
6997
 
+       src/lib-sieve/plugins/imapflags/tag-flags.c, src/lib-sieve/sieve-
6998
 
+       actions.c, src/lib-sieve/sieve-result.c:
6999
 
+       Added :flags tag to the imapflags extension and fixed bug in the
7000
 
+       result execution.
7001
 
+       [e4ccc420bbc8]
7002
 
+
7003
 
+       * README:
7004
 
+       Updated documentation.
7005
 
+       [0b63e817f6b6]
7006
 
+
7007
 
+       * src/lib-sieve/plugins/copy/copy.sieve, src/lib-sieve/plugins/copy
7008
 
+       /ext-copy.c, src/lib-sieve/sieve-validator.c, src/lib-sieve/sieve-
7009
 
+       validator.h:
7010
 
+       Added support for externally adding tags to (possibly not yet
7011
 
+       registered) command. The copy extension now adds such a tag to
7012
 
+       fileinto and redirect.
7013
 
+       [9ad768a6d2b9]
7014
 
+
7015
 
+       * configure.in, src/lib-sieve/Makefile.am, src/lib-
7016
 
+       sieve/plugins/Makefile.am, src/lib-sieve/plugins/copy/Makefile.am,
7017
 
+       src/lib-sieve/plugins/copy/ext-copy.c, src/lib-
7018
 
+       sieve/plugins/copy/rfc3894.txt, src/lib-sieve/sieve-extensions.c,
7019
 
+       src/sieve-bin/sieve-exec.c:
7020
 
+       Added skeleton for the copy extension.
7021
 
+       [f4d0e3674a8c]
7022
 
+
7023
 
+       * sieve/tests/actions.sieve, src/lib-sieve/sieve-actions.c:
7024
 
+       Minor changes
7025
 
+       [da31c25af3df]
7026
 
+
7027
 
+       * sieve/tests/actions.sieve, src/lib-sieve/sieve-actions.c, src/sieve-
7028
 
+       bin/sieve-exec.c:
7029
 
+       Store action seems to work properly now.
7030
 
+       [eec88e2b625d]
7031
 
+
7032
 
+       * sieve/tests/actions.sieve, src/lib-sieve/sieve-actions.c, src/lib-
7033
 
+       sieve/sieve-actions.h, src/lib-sieve/sieve-result.c, src/lib-
7034
 
+       sieve/sieve.h, src/sieve-bin/Makefile.am, src/sieve-bin/mail-raw.c,
7035
 
+       src/sieve-bin/mail-raw.h, src/sieve-bin/namespaces.c, src/sieve-
7036
 
+       bin/namespaces.h, src/sieve-bin/sieve-exec.c, src/sieve-bin/sieve-
7037
 
+       test.c:
7038
 
+       Almost finished implementing the store action. But, I still get
7039
 
+       strange errors when the mail transaction commits. Mail is stored
7040
 
+       though.
7041
 
+       [246c88fea246]
7042
 
+
7043
 
+       * src/lib-sieve/cmd-keep.c, src/lib-sieve/cmd-redirect.c, src/lib-
7044
 
+       sieve/sieve-actions.c, src/lib-sieve/sieve-actions.h, src/lib-sieve
7045
 
+       /sieve-result.c:
7046
 
+       Turned action execution into a transaction.
7047
 
+       [d9a51d8e6d16]
7048
 
+
7049
 
+       * README, src/lib-sieve/cmd-discard.c, src/lib-sieve/cmd-keep.c, src
7050
 
+       /lib-sieve/cmd-redirect.c, src/lib-sieve/ext-fileinto.c, src/lib-
7051
 
+       sieve/sieve-result.c, src/lib-sieve/sieve-result.h:
7052
 
+       Added (not yet active) handling of implicit keep and adjusted
7053
 
+       commands accordingly.
7054
 
+       [d8eaf00dd960]
7055
 
+
7056
 
+       * README:
7057
 
+       Added TODO item.
7058
 
+       [2e2cbe36ac1d]
7059
 
+
7060
 
+2007-11-26  Stephan Bosch  <stephan@rename-it.nl>
7061
 
+
7062
 
+       * src/lib-sieve/cmd-keep.c, src/lib-sieve/sieve.c, src/lib-
7063
 
+       sieve/sieve.h, src/sieve-bin/sieve-exec.c, src/sieve-bin/sieve-
7064
 
+       test.c:
7065
 
+       Added inbox location to mail environment and made keep command use
7066
 
+       it to generate its store action.
7067
 
+       [1fabb5b3de8f]
7068
 
+
7069
 
+       * README, src/lib-sieve/ext-fileinto.c:
7070
 
+       Updated documentation.
7071
 
+       [b77f5ae48116]
7072
 
+
7073
 
+       * sieve/tests/actions.sieve, src/lib-sieve/Makefile.am, src/lib-sieve
7074
 
+       /cmd-discard.c, src/lib-sieve/cmd-keep.c, src/lib-sieve/cmd-
7075
 
+       redirect.c, src/lib-sieve/ext-fileinto.c, src/lib-sieve/sieve-
7076
 
+       actions.c, src/lib-sieve/sieve-actions.h, src/lib-sieve/sieve-
7077
 
+       common.h, src/lib-sieve/sieve-result.c, src/lib-sieve/sieve-
7078
 
+       result.h:
7079
 
+       Fileinto command now produces a store action which is now produced
7080
 
+       by the keep command as well.
7081
 
+       [b59ff97b1b4b]
7082
 
+
7083
 
+       * sieve/tests/actions.sieve, src/lib-sieve/cmd-discard.c, src/lib-
7084
 
+       sieve/cmd-keep.c:
7085
 
+       Made discard command add discard action to the result.
7086
 
+       [d00c1ecbe750]
7087
 
+
7088
 
+       * src/lib-sieve/Makefile.am, src/lib-sieve/cmd-discard.c, src/lib-
7089
 
+       sieve/cmd-keep.c, src/lib-sieve/sieve-commands.c:
7090
 
+       Exported discard command to its own separate file.
7091
 
+       [8bedc7e9f17e]
7092
 
+
7093
 
+       * src/lib-sieve/cmd-keep.c, src/lib-sieve/cmd-redirect.c, src/lib-
7094
 
+       sieve/sieve-result.c, src/lib-sieve/sieve-result.h:
7095
 
+       Added support for detecting action conflicts.
7096
 
+       [37fcab36395a]
7097
 
+
7098
 
+       * README:
7099
 
+       Updated documentation.
7100
 
+       [eb3c1925ac1f]
7101
 
+
7102
 
+       * sieve/tests/redirect.sieve, src/lib-sieve/cmd-keep.c, src/lib-sieve
7103
 
+       /cmd-redirect.c, src/lib-sieve/sieve-result.c, src/lib-sieve/sieve-
7104
 
+       result.h:
7105
 
+       Added support for avoiding duplicate actions in the sieve result.
7106
 
+       [7fa2aeb9a269]
7107
 
+
7108
 
+       * src/lib-sieve/cmd-keep.c, src/lib-sieve/cmd-redirect.c:
7109
 
+       Made keep command add keep action to the result.
7110
 
+       [b4ac2186369d]
7111
 
+
7112
 
+       * src/lib-sieve/Makefile.am, src/lib-sieve/cmd-keep.c, src/lib-sieve
7113
 
+       /sieve-commands-private.h, src/lib-sieve/sieve-commands.c:
7114
 
+       Exported keep command to its own separate file.
7115
 
+       [a061b79e6eb1]
7116
 
+
7117
 
+2007-11-25  Stephan Bosch  <stephan@rename-it.nl>
7118
 
+
7119
 
+       * src/sieve-bin/bin-common.c, src/sieve-bin/sieve-exec.c, src/sieve-
7120
 
+       bin/sieve-test.c:
7121
 
+       Minor changes to the executables.
7122
 
+       [1c349f5cf532]
7123
 
+
7124
 
+       * README, src/lib-sieve/sieve-interpreter.c, src/sieve-bin/sieve-
7125
 
+       exec.c, src/sieve-bin/sieve-test.c:
7126
 
+       Added mail-file parameter to the sieve-test and sieve-exec binaries.
7127
 
+       [38ff5f7794ad]
7128
 
+
7129
 
+       * .hgignore, sieve/tests/redirect.sieve, src/lib-sieve/sieve-binary.c,
7130
 
+       src/lib-sieve/sieve-interpreter.c, src/lib-sieve/sieve-result.c, src
7131
 
+       /lib-sieve/sieve.c, src/lib-sieve/sieve.h, src/sieve-
7132
 
+       bin/Makefile.am, src/sieve-bin/bin-common.c, src/sieve-bin/bin-
7133
 
+       common.h, src/sieve-bin/mail-raw.c, src/sieve-bin/mail-raw.h, src
7134
 
+       /sieve-bin/sieve-exec.c, src/sieve-bin/sieve-test.c, src/sieve-
7135
 
+       bin/sieve_test.c, src/sieve-bin/sievec.c:
7136
 
+       Cleaned up implementation of sieve test binaries and added sieve-
7137
 
+       exec
7138
 
+       [ab2fd12a0195]
7139
 
+
7140
 
+       * src/lib-sieve/sieve-match-types.c:
7141
 
+       Removed spurious debug message.
7142
 
+       [5b53dd17b678]
7143
 
+
7144
 
+2007-11-24  Stephan Bosch  <stephan@rename-it.nl>
7145
 
+
7146
 
+       * src/lib-sieve/cmd-redirect.c, src/lib-sieve/sieve-interpreter.c, src
7147
 
+       /lib-sieve/sieve-interpreter.h, src/lib-sieve/sieve-result.c, src
7148
 
+       /lib-sieve/sieve-result.h, src/lib-sieve/sieve.c, src/lib-
7149
 
+       sieve/sieve.h, src/sieve-bin/Makefile.am, src/sieve-
7150
 
+       bin/sieve_test.c:
7151
 
+       Added first action execution support. Redirect is the first command
7152
 
+       to actually work.
7153
 
+       [3ea3f400caa9]
7154
 
+
7155
 
+       * README:
7156
 
+       Added TODO item.
7157
 
+       [312bfe51f644]
7158
 
+
7159
 
+       * src/lib-sieve/ext-envelope.c, src/lib-sieve/plugins/comparator-i
7160
 
+       -ascii-numeric/ext-cmp-i-ascii-numeric.c, src/lib-
7161
 
+       sieve/plugins/imapflags/tst-hasflag.c, src/lib-sieve/plugins/regex
7162
 
+       /ext-regex.c, src/lib-sieve/plugins/relational/ext-relational.c, src
7163
 
+       /lib-sieve/plugins/relational/relational.sieve, src/lib-
7164
 
+       sieve/plugins/subaddress/ext-subaddress.c, src/lib-sieve/sieve-
7165
 
+       address-parts.c, src/lib-sieve/sieve-address-parts.h, src/lib-sieve
7166
 
+       /sieve-binary.c, src/lib-sieve/sieve-binary.h, src/lib-sieve/sieve-
7167
 
+       comparators.c, src/lib-sieve/sieve-comparators.h, src/lib-sieve
7168
 
+       /sieve-match-types.c, src/lib-sieve/sieve-match-types.h, src/lib-
7169
 
+       sieve/tst-address.c, src/lib-sieve/tst-header.c:
7170
 
+       Moved address-part, match-type and comparator code registries from
7171
 
+       interpreter to binary where they belong.
7172
 
+       [17fe832ec983]
7173
 
+
7174
 
+       * src/lib-sieve/sieve-binary.c, src/lib-sieve/sieve-binary.h, src/lib-
7175
 
+       sieve/sieve-interpreter.c:
7176
 
+       Added extension context storage support to the sieve binary.
7177
 
+       [bf61316d9b84]
7178
 
+
7179
 
+       * src/lib-sieve/ext-envelope.c, src/lib-sieve/ext-fileinto.c, src/lib-
7180
 
+       sieve/ext-reject.c, src/lib-sieve/plugins/comparator-i-ascii-numeric
7181
 
+       /ext-cmp-i-ascii-numeric.c, src/lib-sieve/plugins/imapflags/ext-
7182
 
+       imapflags.c, src/lib-sieve/plugins/regex/ext-regex.c, src/lib-
7183
 
+       sieve/plugins/relational/ext-relational.c, src/lib-
7184
 
+       sieve/plugins/subaddress/ext-subaddress.c, src/lib-
7185
 
+       sieve/plugins/vacation/ext-vacation.c, src/lib-sieve/sieve-address-
7186
 
+       parts.c, src/lib-sieve/sieve-binary.c, src/lib-sieve/sieve-binary.h,
7187
 
+       src/lib-sieve/sieve-comparators.c, src/lib-sieve/sieve-extensions.c,
7188
 
+       src/lib-sieve/sieve-extensions.h, src/lib-sieve/sieve-interpreter.c,
7189
 
+       src/lib-sieve/sieve-match-types.c:
7190
 
+       Added binary_load event to the sieve extensions.
7191
 
+       [abc3d97f3cfe]
7192
 
+
7193
 
+       * src/lib-sieve/cmd-redirect.c, src/lib-sieve/ext-envelope.c, src/lib-
7194
 
+       sieve/ext-fileinto.c, src/lib-sieve/ext-reject.c, src/lib-
7195
 
+       sieve/plugins/imapflags/cmd-addflag.c, src/lib-
7196
 
+       sieve/plugins/imapflags/cmd-removeflag.c, src/lib-
7197
 
+       sieve/plugins/imapflags/cmd-setflag.c, src/lib-
7198
 
+       sieve/plugins/imapflags/ext-imapflags-common.c, src/lib-
7199
 
+       sieve/plugins/imapflags/ext-imapflags-common.h, src/lib-
7200
 
+       sieve/plugins/imapflags/tst-hasflag.c, src/lib-
7201
 
+       sieve/plugins/vacation/ext-vacation.c, src/lib-sieve/sieve-address-
7202
 
+       parts.c, src/lib-sieve/sieve-address-parts.h, src/lib-sieve/sieve-
7203
 
+       binary.c, src/lib-sieve/sieve-code.c, src/lib-sieve/sieve-code.h,
7204
 
+       src/lib-sieve/sieve-commands.c, src/lib-sieve/sieve-common.h, src
7205
 
+       /lib-sieve/sieve-comparators.c, src/lib-sieve/sieve-comparators.h,
7206
 
+       src/lib-sieve/sieve-interpreter.c, src/lib-sieve/sieve-
7207
 
+       interpreter.h, src/lib-sieve/sieve-match-types.c, src/lib-sieve
7208
 
+       /sieve-match-types.h, src/lib-sieve/sieve-result.c, src/lib-sieve
7209
 
+       /sieve-result.h, src/lib-sieve/sieve.c, src/lib-sieve/tst-address.c,
7210
 
+       src/lib-sieve/tst-exists.c, src/lib-sieve/tst-header.c, src/lib-
7211
 
+       sieve/tst-size.c:
7212
 
+       Grouped runtime parameters into a single runtime environment and
7213
 
+       started implementation of result composition/execution.
7214
 
+       [7c800bfa74cc]
7215
 
+
7216
 
+       * src/lib-sieve/sieve-interpreter.c:
7217
 
+       Changed interpreter in the event of an unimplemented opcode.
7218
 
+       [91fd90402931]
7219
 
+
7220
 
+       * README, src/lib-sieve/plugins/imapflags/ext-imapflags.c:
7221
 
+       Updated documentation.
7222
 
+       [9dd4fe921d74]
7223
 
+
7224
 
+       * src/lib-sieve/plugins/imapflags/cmd-addflag.c, src/lib-
7225
 
+       sieve/plugins/imapflags/cmd-removeflag.c, src/lib-
7226
 
+       sieve/plugins/imapflags/cmd-setflag.c, src/lib-
7227
 
+       sieve/plugins/imapflags/ext-imapflags-common.c, src/lib-
7228
 
+       sieve/plugins/imapflags/ext-imapflags-common.h, src/lib-
7229
 
+       sieve/plugins/imapflags/imapflags-2.sieve, src/lib-
7230
 
+       sieve/plugins/imapflags/tst-hasflag.c:
7231
 
+       Implemented hasflag command interpretation for the imapflags
7232
 
+       extension.
7233
 
+       [30917ef6965c]
7234
 
+
7235
 
+2007-11-23  Stephan Bosch  <stephan@rename-it.nl>
7236
 
+
7237
 
+       * src/lib-sieve/plugins/imapflags/cmd-addflag.c, src/lib-
7238
 
+       sieve/plugins/imapflags/cmd-removeflag.c, src/lib-
7239
 
+       sieve/plugins/imapflags/cmd-setflag.c, src/lib-
7240
 
+       sieve/plugins/imapflags/ext-imapflags-common.c, src/lib-
7241
 
+       sieve/plugins/imapflags/ext-imapflags-common.h, src/lib-
7242
 
+       sieve/plugins/imapflags/ext-imapflags.c, src/lib-
7243
 
+       sieve/plugins/imapflags/imapflags-2.sieve, src/lib-
7244
 
+       sieve/plugins/imapflags/imapflags.sieve, src/lib-
7245
 
+       sieve/plugins/imapflags/tst-hasflag.c, src/lib-
7246
 
+       sieve/plugins/relational/ext-relational.c, src/lib-
7247
 
+       sieve/plugins/vacation/ext-vacation.c, src/lib-sieve/sieve-ast.c,
7248
 
+       src/lib-sieve/sieve-ast.h, src/lib-sieve/sieve-comparators.c, src
7249
 
+       /lib-sieve/tst-size.c:
7250
 
+       Added actual flag management to the imapflags extension. Addflag,
7251
 
+       removeflag and setflag now do what they should do.
7252
 
+       [610b5f638c33]
7253
 
+
7254
 
+       * README, src/lib-sieve/cmd-if.c, src/lib-sieve/plugins/comparator-i
7255
 
+       -ascii-numeric/ext-cmp-i-ascii-numeric.c, src/lib-
7256
 
+       sieve/plugins/relational/relational.sieve, src/lib-sieve/tst-
7257
 
+       allof.c, src/lib-sieve/tst-anyof.c:
7258
 
+       Finished i;ascii-numeric comparator and fixed a segfault bug in the
7259
 
+       process.
7260
 
+       [8cd504cc2e3a]
7261
 
+
7262
 
+       * README, src/lib-sieve/plugins/imapflags/Makefile.am, src/lib-
7263
 
+       sieve/plugins/imapflags/ext-imapflags-common.h, src/lib-
7264
 
+       sieve/plugins/imapflags/ext-imapflags.c, src/lib-
7265
 
+       sieve/plugins/imapflags/imapflags-errors.sieve, src/lib-
7266
 
+       sieve/plugins/imapflags/imapflags.sieve, src/lib-
7267
 
+       sieve/plugins/imapflags/tst-hasflag.c, src/lib-sieve/tst-header.c:
7268
 
+       Added hasflag test to the imapflags extension.
7269
 
+       [cc5f85570a9a]
7270
 
+
7271
 
+       * src/lib-sieve/plugins/imapflags/cmd-addflag.c, src/lib-
7272
 
+       sieve/plugins/imapflags/cmd-removeflag.c, src/lib-
7273
 
+       sieve/plugins/imapflags/cmd-setflag.c, src/lib-
7274
 
+       sieve/plugins/imapflags/ext-imapflags-common.c, src/lib-
7275
 
+       sieve/plugins/imapflags/ext-imapflags.c, src/lib-
7276
 
+       sieve/plugins/imapflags/imapflags.sieve, src/lib-sieve/sieve-code.c,
7277
 
+       src/lib-sieve/sieve-code.h:
7278
 
+       Implemented code generation and interpretation for the commands
7279
 
+       introduced by the imapflags extension.
7280
 
+       [f0c34dee6ae7]
7281
 
+
7282
 
+       * src/lib-sieve/cmd-redirect.c, src/lib-sieve/ext-envelope.c, src/lib-
7283
 
+       sieve/ext-fileinto.c, src/lib-sieve/ext-reject.c, src/lib-
7284
 
+       sieve/plugins/comparator-i-ascii-numeric/ext-cmp-i-ascii-numeric.c,
7285
 
+       src/lib-sieve/plugins/imapflags/cmd-addflag.c, src/lib-
7286
 
+       sieve/plugins/imapflags/cmd-removeflag.c, src/lib-
7287
 
+       sieve/plugins/imapflags/cmd-setflag.c, src/lib-
7288
 
+       sieve/plugins/imapflags/ext-imapflags-common.c, src/lib-
7289
 
+       sieve/plugins/imapflags/ext-imapflags-common.h, src/lib-
7290
 
+       sieve/plugins/imapflags/ext-imapflags.c, src/lib-sieve/plugins/regex
7291
 
+       /ext-regex.c, src/lib-sieve/plugins/relational/ext-relational.c, src
7292
 
+       /lib-sieve/plugins/subaddress/ext-subaddress.c, src/lib-
7293
 
+       sieve/plugins/vacation/ext-vacation.c, src/lib-sieve/sieve-address-
7294
 
+       parts.c, src/lib-sieve/sieve-code.c, src/lib-sieve/sieve-code.h, src
7295
 
+       /lib-sieve/sieve-commands.c, src/lib-sieve/sieve-comparators.c, src
7296
 
+       /lib-sieve/sieve-extensions.c, src/lib-sieve/sieve-extensions.h, src
7297
 
+       /lib-sieve/sieve-generator.c, src/lib-sieve/sieve-generator.h, src
7298
 
+       /lib-sieve/sieve-interpreter.c, src/lib-sieve/sieve-match-types.c,
7299
 
+       src/lib-sieve/tst-address.c, src/lib-sieve/tst-exists.c, src/lib-
7300
 
+       sieve/tst-header.c, src/lib-sieve/tst-size.c:
7301
 
+       Upgraded opcode extension support to handle more than one opcode per
7302
 
+       extension.
7303
 
+       [2a2d82471e77]
7304
 
+
7305
 
+2007-11-22  Stephan Bosch  <stephan@rename-it.nl>
7306
 
+
7307
 
+       * src/lib-sieve/plugins/imapflags/ext-imapflags-common.c, src/lib-
7308
 
+       sieve/plugins/imapflags/imapflags.sieve:
7309
 
+       imapflags: Added (dummy) check for the existance of the variables
7310
 
+       extension.
7311
 
+       [9d97ea5c52c6]
7312
 
+
7313
 
+       * src/lib-sieve/plugins/imapflags/ext-imapflags-common.c, src/lib-
7314
 
+       sieve/plugins/imapflags/imapflags-errors.sieve, src/lib-sieve/sieve-
7315
 
+       validator.c:
7316
 
+       Implemented validation for the commands introduced by the imapflags
7317
 
+       extension.
7318
 
+       [82e86518dfc9]
7319
 
+
7320
 
+       * src/lib-sieve/plugins/imapflags/Makefile.am, src/lib-
7321
 
+       sieve/plugins/imapflags/cmd-addflag.c, src/lib-
7322
 
+       sieve/plugins/imapflags/cmd-removeflag.c, src/lib-
7323
 
+       sieve/plugins/imapflags/cmd-setflag.c, src/lib-
7324
 
+       sieve/plugins/imapflags/ext-imapflags-common.c, src/lib-
7325
 
+       sieve/plugins/imapflags/ext-imapflags-common.h, src/lib-
7326
 
+       sieve/plugins/imapflags/ext-imapflags.c, src/lib-
7327
 
+       sieve/plugins/imapflags/imapflags.sieve, src/lib-sieve/sieve-
7328
 
+       commands.h, src/lib-sieve/sieve-extensions.c, src/lib-sieve/sieve-
7329
 
+       validator.c:
7330
 
+       Created skeletons for the commands introduced by the imapflags
7331
 
+       extension.
7332
 
+       [c0471778290f]
7333
 
+
7334
 
+       * configure.in, src/lib-sieve/Makefile.am, src/lib-
7335
 
+       sieve/plugins/Makefile.am, src/lib-
7336
 
+       sieve/plugins/imapflags/Makefile.am, src/lib-sieve/plugins/imapflags
7337
 
+       /draft-ietf-sieve-imapflags-05.txt, src/lib-sieve/plugins/imapflags
7338
 
+       /ext-imapflags.c:
7339
 
+       Started skeleton for the imapflags extension.
7340
 
+       [6ea6b7699606]
7341
 
+
7342
 
+       * src/lib-sieve/Makefile.am, src/lib-sieve/plugins/Makefile.am, src
7343
 
+       /lib-sieve/plugins/comparator-i-ascii-numeric/Makefile.am, src/lib-
7344
 
+       sieve/plugins/regex/Makefile.am, src/lib-
7345
 
+       sieve/plugins/relational/Makefile.am, src/lib-
7346
 
+       sieve/plugins/subaddress/Makefile.am, src/lib-
7347
 
+       sieve/plugins/vacation/Makefile.am, src/sieve-bin/Makefile.am:
7348
 
+       Cleaned up make process and included the 'plugins' into the main
7349
 
+       sieve library archive.
7350
 
+       [b669519df1b5]
7351
 
+
7352
 
+       * README, src/lib-sieve/sieve-commands.c:
7353
 
+       Updated documentation.
7354
 
+       [ab270d1accc1]
7355
 
+
7356
 
+       * sieve/examples/vivil.sieve, sieve/tests/stop.sieve, src/lib-sieve
7357
 
+       /cmd-if.c, src/lib-sieve/sieve-commands.c, src/lib-sieve/sieve-
7358
 
+       commands.h, src/lib-sieve/sieve-generator.c, src/lib-sieve/sieve-
7359
 
+       generator.h:
7360
 
+       Removed unecessary jump after commands like stop.
7361
 
+       [a487f6447efa]
7362
 
+
7363
 
+       * sieve/tests/matches.sieve, src/lib-sieve/sieve-match-types.c:
7364
 
+       Debugged :matches match type and no more bugs are currently known.
7365
 
+       [acdcd1d8f031]
7366
 
+
7367
 
+       * sieve/tests/matches.sieve, src/lib-sieve/plugins/comparator-i-ascii-
7368
 
+       numeric/ext-cmp-i-ascii-numeric.c, src/lib-sieve/sieve-
7369
 
+       comparators.c, src/lib-sieve/sieve-comparators.h, src/lib-sieve
7370
 
+       /sieve-match-types.c:
7371
 
+       Made first buggy implementation of :matches match type.
7372
 
+       [d3756743700b]
7373
 
+
7374
 
+2007-11-21  Stephan Bosch  <stephan@rename-it.nl>
7375
 
+
7376
 
+       * README:
7377
 
+       Updated documentation with respect to extensions.
7378
 
+       [cd8b13651e87]
7379
 
+
7380
 
+       * sieve/tests/reject.sieve, src/lib-sieve/ext-reject.c:
7381
 
+       Added dummy execution support to reject extension.
7382
 
+       [29620589f088]
7383
 
+
7384
 
+       * README, src/lib-sieve/plugins/vacation/ext-vacation.c:
7385
 
+       Updated documentation.
7386
 
+       [3dcfafbef34d]
7387
 
+
7388
 
+       * sieve/tests/vacation.sieve, src/lib-sieve/plugins/vacation/ext-
7389
 
+       vacation.c, src/lib-sieve/sieve-validator.c, src/lib-sieve/sieve-
7390
 
+       validator.h:
7391
 
+       Implemented dummy execution for vacation extension.
7392
 
+       [ef682330f822]
7393
 
+
7394
 
+       * src/lib-sieve/ext-envelope.c:
7395
 
+       Resolved compiler warning in envelope extension.
7396
 
+       [7e2d6e8893dc]
7397
 
+
7398
 
+       * sieve/tests/redirect.sieve:
7399
 
+       Added test script for redirect command.
7400
 
+       [30ec001eaee2]
7401
 
+
7402
 
+       * src/lib-sieve/sieve-code.c, src/lib-sieve/sieve-interpreter.c, src
7403
 
+       /lib-sieve/sieve-interpreter.h:
7404
 
+       Properly implemented stop command and associated opcode.
7405
 
+       [cb2ac2578b83]
7406
 
+
7407
 
+       * src/sieve-bin/sieve_test.c:
7408
 
+       Added status message to sieve_test to indicate successful script
7409
 
+       run.
7410
 
+       [64e0b6403468]
7411
 
+
7412
 
+       * src/lib-sieve/cmd-redirect.c, src/lib-sieve/ext-fileinto.c, src/lib-
7413
 
+       sieve/sieve-code.c, src/lib-sieve/sieve-code.h, src/lib-sieve/sieve-
7414
 
+       interpreter.h:
7415
 
+       Created dummy interpretation support for the redirect command.
7416
 
+       [382920e5c5ae]
7417
 
+
7418
 
+       * sieve/tests/fileinto.sieve, src/lib-sieve/ext-fileinto.c:
7419
 
+       Created dummy interpretation support for the fileinto extension.
7420
 
+       [c410f5746af3]
7421
 
+
7422
 
+       * src/lib-sieve/ext-envelope.c:
7423
 
+       Removed debug lines in envelope extension.
7424
 
+       [0d144c5c6726]
7425
 
+
7426
 
+       * src/lib-sieve/ext-envelope.c:
7427
 
+       Made ext_envelope_get_fields cleaner.
7428
 
+       [962e5ed2a7b0]
7429
 
+
7430
 
+       * README, src/lib-sieve/ext-envelope.c:
7431
 
+       Updated documentation.
7432
 
+       [c05059b64271]
7433
 
+
7434
 
+       * sieve/tests/envelope.sieve, src/lib-sieve/ext-envelope.c, src/lib-
7435
 
+       sieve/sieve-address-parts.c, src/lib-sieve/sieve-address-parts.h,
7436
 
+       src/lib-sieve/sieve.h, src/lib-sieve/tst-address.c, src/sieve-
7437
 
+       bin/sieve_test.c:
7438
 
+       Made basic execution implementation of the envelope extension.
7439
 
+       [6bf04ad6e814]
7440
 
+
7441
 
+       * src/lib-sieve/ext-envelope.c, src/lib-sieve/sieve-common.h, src/lib-
7442
 
+       sieve/sieve-interpreter.c, src/lib-sieve/sieve-interpreter.h, src
7443
 
+       /lib-sieve/sieve.c, src/lib-sieve/sieve.h, src/lib-sieve/tst-
7444
 
+       address.c, src/lib-sieve/tst-exists.c, src/lib-sieve/tst-header.c,
7445
 
+       src/lib-sieve/tst-size.c, src/sieve-bin/sieve_test.c:
7446
 
+       Added envelope data to the interpreter environment.
7447
 
+       [b9cf89b005f2]
7448
 
+
7449
 
+       * README, src/lib-sieve/plugins/comparator-i-ascii-numeric/ext-cmp-i
7450
 
+       -ascii-numeric.c, src/lib-sieve/plugins/regex/ext-regex.c, src/lib-
7451
 
+       sieve/plugins/relational/ext-relational.c, src/lib-
7452
 
+       sieve/plugins/relational/relational.sieve, src/lib-sieve/sieve-
7453
 
+       match-types.c, src/lib-sieve/sieve-match-types.h, src/lib-sieve/tst-
7454
 
+       address.c, src/lib-sieve/tst-header.c:
7455
 
+       Completed implementation of the relational extension.
7456
 
+       [7dd971306703]
7457
 
+
7458
 
+       * src/lib-sieve/plugins/regex/ext-regex.c, src/lib-
7459
 
+       sieve/plugins/regex/regex.sieve, src/lib-sieve/plugins/relational
7460
 
+       /ext-relational.c, src/lib-sieve/sieve-match-types.c, src/lib-sieve
7461
 
+       /sieve-match-types.h:
7462
 
+       Improved match handling and started implementing the interpretation
7463
 
+       of the relational match type.
7464
 
+       [158169910d95]
7465
 
+
7466
 
+2007-11-20  Stephan Bosch  <stephan@rename-it.nl>
7467
 
+
7468
 
+       * sieve/errors/match-type-errors.sieve, sieve/tests/match-type.sieve,
7469
 
+       src/lib-sieve/sieve-comparators.c, src/lib-sieve/sieve-
7470
 
+       comparators.h, src/lib-sieve/sieve-match-types.c:
7471
 
+       Implemented context validation for :contains match type.
7472
 
+       [6f1dcac24c57]
7473
 
+
7474
 
+       * README, src/lib-sieve/plugins/regex/ext-regex.c:
7475
 
+       Updated documentation with respect to regex externsion and match-
7476
 
+       type support.
7477
 
+       [37fd899b7dca]
7478
 
+
7479
 
+       * src/lib-sieve/sieve-match-types.c:
7480
 
+       Last commit broke execution of match types other than
7481
 
+       :regex...fixed.
7482
 
+       [f9e2b975f5eb]
7483
 
+
7484
 
+       * src/lib-sieve/plugins/regex/ext-regex.c, src/lib-
7485
 
+       sieve/plugins/regex/regex.sieve, src/lib-sieve/plugins/relational
7486
 
+       /ext-relational.c, src/lib-sieve/sieve-address-parts.c, src/lib-
7487
 
+       sieve/sieve-address-parts.h, src/lib-sieve/sieve-common.h, src/lib-
7488
 
+       sieve/sieve-match-types.c, src/lib-sieve/sieve-match-types.h, src
7489
 
+       /lib-sieve/tst-address.c, src/lib-sieve/tst-header.c:
7490
 
+       Implemented regex match execution.
7491
 
+       [114ec23016dd]
7492
 
+
7493
 
+       * sieve/examples/sanjay.sieve:
7494
 
+       Fixed missing require in sanjay.sieve example
7495
 
+       [81baf031527e]
7496
 
+
7497
 
+       * src/lib-sieve/plugins/regex/ext-regex.c:
7498
 
+       Forgot to handle stringlists in :regex validation.
7499
 
+       [4e082129513a]
7500
 
+
7501
 
+       * src/lib-sieve/ext-envelope.c, src/lib-sieve/plugins/regex/ext-
7502
 
+       regex.c, src/lib-sieve/plugins/regex/regex-errors.sieve, src/lib-
7503
 
+       sieve/sieve-match-types.c, src/lib-sieve/sieve-match-types.h, src
7504
 
+       /lib-sieve/tst-address.c, src/lib-sieve/tst-header.c:
7505
 
+       Implemented :regex match validation.
7506
 
+       [fefebffac65f]
7507
 
+
7508
 
+       * sieve/errors/address-part-errors.sieve,
7509
 
+       sieve/errors/interesting.sieve, sieve/errors/match-type-
7510
 
+       errors.sieve, src/lib-sieve/sieve-address-parts.c, src/lib-sieve
7511
 
+       /sieve-ast.h, src/lib-sieve/sieve-match-types.c, src/lib-sieve
7512
 
+       /sieve-validator.c:
7513
 
+       Implemented detection of duplicate optional arguments.
7514
 
+       [9add85be3ddd]
7515
 
+
7516
 
+       * src/lib-sieve/plugins/regex/ext-regex.c, src/lib-sieve/plugins/regex
7517
 
+       /regex-errors.sieve, src/lib-sieve/sieve-commands.h, src/lib-sieve
7518
 
+       /sieve-comparators.c, src/lib-sieve/sieve-comparators.h, src/lib-
7519
 
+       sieve/sieve-validator.c:
7520
 
+       Made regex match complaint about comparators other than i;octet or i
7521
 
+       ;ascii-casemap
7522
 
+       [ebf35c004764]
7523
 
+
7524
 
+       * src/lib-sieve/plugins/regex/ext-regex.c, src/lib-
7525
 
+       sieve/plugins/relational/ext-relational.c, src/lib-sieve/sieve-
7526
 
+       match-types.c, src/lib-sieve/sieve-match-types.h:
7527
 
+       Added support for match-type argument context validation.
7528
 
+       [9db6e7335e9e]
7529
 
+
7530
 
+       * src/lib-sieve/sieve-validator.c:
7531
 
+       Added support for argument context validation.
7532
 
+       [7dcaf16bcf7d]
7533
 
+
7534
 
+       * src/lib-sieve/plugins/vacation/ext-vacation.c, src/lib-sieve/sieve-
7535
 
+       address-parts.c, src/lib-sieve/sieve-commands.c, src/lib-sieve
7536
 
+       /sieve-commands.h, src/lib-sieve/sieve-comparators.c, src/lib-sieve
7537
 
+       /sieve-match-types.c, src/lib-sieve/sieve-validator.c, src/lib-sieve
7538
 
+       /tst-size.c:
7539
 
+       Added validat_context method to command arguments for the to-be-
7540
 
+       implemented argument context validation.
7541
 
+       [754320bac6bb]
7542
 
+
7543
 
+       * src/lib-sieve/sieve-address-parts.c, src/lib-sieve/sieve-commands.c,
7544
 
+       src/lib-sieve/sieve-commands.h, src/lib-sieve/sieve-comparators.c,
7545
 
+       src/lib-sieve/sieve-generator.c, src/lib-sieve/sieve-match-types.c:
7546
 
+       Changed argument generator function prototype to assign
7547
 
+       responsibility of advancing to the next argument to the generator
7548
 
+       itself.
7549
 
+       [6ba97a809b25]
7550
 
+
7551
 
+       * src/lib-sieve/sieve-commands.c:
7552
 
+       Removed i_unreached() at inappropriate location.
7553
 
+       [80a6ca8aa099]
7554
 
+
7555
 
+       * src/lib-sieve/sieve-ast.c, src/lib-sieve/sieve-ast.h, src/lib-sieve
7556
 
+       /sieve-commands.c, src/lib-sieve/sieve-commands.h, src/lib-sieve
7557
 
+       /sieve-validator.c:
7558
 
+       Removed code duplication in validator: merged command and test
7559
 
+       validation in one function.
7560
 
+       [55047d9405c9]
7561
 
+
7562
 
+       * src/lib-sieve/sieve-validator.c:
7563
 
+       Fixed bug in the command validation.
7564
 
+       [0f7c34ca82a9]
7565
 
+
7566
 
+       * src/lib-sieve/cmd-if.c, src/lib-sieve/cmd-require.c, src/lib-sieve
7567
 
+       /sieve-commands.h:
7568
 
+       Improved validation of command placement for if and require
7569
 
+       commands.
7570
 
+       [7666f12ccc2a]
7571
 
+
7572
 
+       * src/lib-sieve/cmd-if.c, src/lib-sieve/cmd-redirect.c, src/lib-sieve
7573
 
+       /cmd-require.c, src/lib-sieve/ext-envelope.c, src/lib-sieve/ext-
7574
 
+       fileinto.c, src/lib-sieve/ext-reject.c, src/lib-
7575
 
+       sieve/plugins/vacation/ext-vacation.c, src/lib-sieve/sieve-commands-
7576
 
+       private.h, src/lib-sieve/sieve-commands.c, src/lib-sieve/sieve-
7577
 
+       commands.h, src/lib-sieve/sieve-validator.c, src/lib-sieve/sieve-
7578
 
+       validator.h, src/lib-sieve/tst-address.c, src/lib-sieve/tst-allof.c,
7579
 
+       src/lib-sieve/tst-anyof.c, src/lib-sieve/tst-exists.c, src/lib-sieve
7580
 
+       /tst-header.c, src/lib-sieve/tst-not.c, src/lib-sieve/tst-size.c:
7581
 
+       Changed validator's command syntax validation such that command
7582
 
+       implementations don't have to call the argument, test and block
7583
 
+       validation functions explicitly.
7584
 
+       [e43df7ab9749]
7585
 
+
7586
 
+2007-11-19  Stephan Bosch  <stephan@rename-it.nl>
7587
 
+
7588
 
+       * src/lib-sieve/cmd-if.c, src/lib-sieve/cmd-redirect.c, src/lib-sieve
7589
 
+       /cmd-require.c, src/lib-sieve/ext-envelope.c, src/lib-sieve/ext-
7590
 
+       fileinto.c, src/lib-sieve/ext-reject.c, src/lib-
7591
 
+       sieve/plugins/vacation/ext-vacation.c, src/lib-sieve/sieve-ast.h,
7592
 
+       src/lib-sieve/sieve-commands.h, src/lib-sieve/sieve-validator.c, src
7593
 
+       /lib-sieve/sieve-validator.h, src/lib-sieve/tst-address.c, src/lib-
7594
 
+       sieve/tst-allof.c, src/lib-sieve/tst-anyof.c, src/lib-sieve/tst-
7595
 
+       exists.c, src/lib-sieve/tst-header.c, src/lib-sieve/tst-not.c, src
7596
 
+       /lib-sieve/tst-size.c:
7597
 
+       Changed argument validation to record the first positional argument
7598
 
+       into the command context by default. Also furter improved
7599
 
+       validator's error handling.
7600
 
+       [d357da9effa4]
7601
 
+
7602
 
+       * sieve/errors/address-errors.sieve, sieve/errors/header-errors.sieve,
7603
 
+       src/lib-sieve/cmd-redirect.c, src/lib-sieve/cmd-require.c, src/lib-
7604
 
+       sieve/ext-envelope.c, src/lib-sieve/ext-fileinto.c, src/lib-sieve
7605
 
+       /ext-reject.c, src/lib-sieve/plugins/subaddress/subaddress.sieve,
7606
 
+       src/lib-sieve/plugins/vacation/ext-vacation.c, src/lib-sieve/sieve-
7607
 
+       ast.c, src/lib-sieve/sieve-ast.h, src/lib-sieve/sieve-common.h, src
7608
 
+       /lib-sieve/sieve-validator.c, src/lib-sieve/sieve-validator.h, src
7609
 
+       /lib-sieve/tst-address.c, src/lib-sieve/tst-exists.c, src/lib-sieve
7610
 
+       /tst-header.c, src/lib-sieve/tst-size.c:
7611
 
+       Revised positional argument checking and fixed the validator's error
7612
 
+       handling.
7613
 
+       [31ade1ddf884]
7614
 
+
7615
 
+       * src/lib-sieve/sieve-match-types.c:
7616
 
+       Prevent unimplemented match type from causing a segfault.
7617
 
+       [614e7a053e31]
7618
 
+
7619
 
+       * src/lib-sieve/plugins/comparator-i-ascii-numeric/ext-cmp-i-ascii-
7620
 
+       numeric.c, src/lib-sieve/plugins/regex/ext-regex.c, src/lib-
7621
 
+       sieve/plugins/relational/ext-relational.c, src/lib-sieve/sieve-
7622
 
+       address-parts.c, src/lib-sieve/sieve-address-parts.h, src/lib-sieve
7623
 
+       /sieve-common.h, src/lib-sieve/sieve-comparators.c, src/lib-sieve
7624
 
+       /sieve-comparators.h, src/lib-sieve/sieve-interpreter.c, src/lib-
7625
 
+       sieve/sieve-interpreter.h, src/lib-sieve/sieve-match-types.c, src
7626
 
+       /lib-sieve/sieve-match-types.h, src/lib-sieve/tst-address.c, src
7627
 
+       /lib-sieve/tst-header.c:
7628
 
+       Implemented match type execution and activated match types :is and
7629
 
+       :contains.
7630
 
+       [44f7b3f89e34]
7631
 
+
7632
 
+2007-11-17  Stephan Bosch  <stephan@rename-it.nl>
7633
 
+
7634
 
+       * README, src/lib-sieve/plugins/regex/ext-regex.c, src/lib-
7635
 
+       sieve/plugins/relational/ext-relational.c:
7636
 
+       Minor updates to the documentation.
7637
 
+       [033d7cb3a8dd]
7638
 
+
7639
 
+       * src/lib-sieve/plugins/relational/ext-relational.c, src/lib-
7640
 
+       sieve/plugins/relational/relational.sieve, src/lib-sieve/sieve-
7641
 
+       match-types.c, src/lib-sieve/sieve-match-types.h:
7642
 
+       Fixed code generation for relational extension.
7643
 
+       [9aedfec64626]
7644
 
+
7645
 
+       * src/lib-sieve/plugins/regex/ext-regex.c, src/lib-
7646
 
+       sieve/plugins/relational/ext-relational.c, src/lib-sieve/sieve-
7647
 
+       match-types.c, src/lib-sieve/sieve-match-types.h:
7648
 
+       Implemented support for additional parameters to match-types and
7649
 
+       implemented validation for the relational extension.
7650
 
+       [c49afa847933]
7651
 
+
7652
 
+       * configure.in, sieve/tests/match-type.sieve, src/lib-
7653
 
+       sieve/plugins/Makefile.am, src/lib-sieve/plugins/regex/Makefile.am,
7654
 
+       src/lib-sieve/plugins/regex/draft-murchison-sieve-regex-07.txt, src
7655
 
+       /lib-sieve/plugins/regex/ext-regex.c, src/lib-
7656
 
+       sieve/plugins/regex/regex.sieve, src/lib-
7657
 
+       sieve/plugins/relational/Makefile.am, src/lib-
7658
 
+       sieve/plugins/relational/ext-relational.c, src/lib-
7659
 
+       sieve/plugins/relational/relational.sieve, src/lib-
7660
 
+       sieve/plugins/relational/rfc3431.txt, src/lib-sieve/sieve-
7661
 
+       extensions.c, src/sieve-bin/Makefile.am:
7662
 
+       Created skeletons for regex and relational extensions. These are to
7663
 
+       be developed simultaneously with the match-type support in general.
7664
 
+       [f3db84e346eb]
7665
 
+
7666
 
+       * README, sieve/tests/match-type.sieve, src/lib-sieve/Makefile.am, src
7667
 
+       /lib-sieve/ext-envelope.c, src/lib-sieve/sieve-address-parts.c, src
7668
 
+       /lib-sieve/sieve-code.c, src/lib-sieve/sieve-comparators.c, src/lib-
7669
 
+       sieve/sieve-extensions.c, src/lib-sieve/sieve-extensions.h, src/lib-
7670
 
+       sieve/sieve-interpreter.c, src/lib-sieve/sieve-match-types.c, src
7671
 
+       /lib-sieve/sieve-match-types.h, src/lib-sieve/sieve-validator.c, src
7672
 
+       /lib-sieve/tst-address.c, src/lib-sieve/tst-header.c:
7673
 
+       Started implementation of match-type support and fixed compilation
7674
 
+       error.
7675
 
+       [b352686b0063]
7676
 
+
7677
 
+       * README, src/lib-sieve/plugins/comparator-i-ascii-numeric/ext-cmp-i
7678
 
+       -ascii-numeric.c, src/lib-sieve/plugins/vacation/ext-vacation.c, src
7679
 
+       /lib-sieve/sieve-comparators.c:
7680
 
+       Updated README and a few minor cosmetic changes to the code.
7681
 
+       [8eddb5ec9ddb]
7682
 
+
7683
 
+       * configure.in, src/lib-sieve/ext-envelope.c, src/lib-
7684
 
+       sieve/plugins/Makefile.am, src/lib-sieve/plugins/comparator-i-ascii-
7685
 
+       numeric/Makefile.am, src/lib-sieve/plugins/comparator-i-ascii-
7686
 
+       numeric/cmp-i-ascii-numeric.sieve, src/lib-
7687
 
+       sieve/plugins/comparator-i-ascii-numeric/ext-cmp-i-ascii-numeric.c,
7688
 
+       src/lib-sieve/plugins/comparator-i-ascii-numeric/rfc2244.txt, src
7689
 
+       /lib-sieve/plugins/subaddress/ext-subaddress.c, src/lib-sieve/sieve-
7690
 
+       address-parts.c, src/lib-sieve/sieve-address-parts.h, src/lib-sieve
7691
 
+       /sieve-common.h, src/lib-sieve/sieve-comparators.c, src/lib-sieve
7692
 
+       /sieve-comparators.h, src/lib-sieve/sieve-extensions.c, src/lib-
7693
 
+       sieve/tst-address.c, src/lib-sieve/tst-header.c, src/sieve-
7694
 
+       bin/Makefile.am:
7695
 
+       Implemented comparator-i;ascii-numeric extension and activated
7696
 
+       comparator extension support.
7697
 
+       [01386a471dc7]
7698
 
+
7699
 
+       * src/lib-sieve/sieve-extensions.c:
7700
 
+       Added dummy extensions for core comparators.
7701
 
+       [ae2e6fd6f94e]
7702
 
+
7703
 
+       * sieve/tests/extensions.sieve, src/lib-sieve/cmd-require.c, src/lib-
7704
 
+       sieve/sieve-address-parts.c:
7705
 
+       A few small cosmetic changes in addr-part code and generic extension
7706
 
+       support.
7707
 
+       [7b9f9e71030e]
7708
 
+
7709
 
+2007-11-16  Stephan Bosch  <stephan@rename-it.nl>
7710
 
+
7711
 
+       * src/lib-sieve/plugins/subaddress/ext-subaddress.c, src/lib-
7712
 
+       sieve/plugins/subaddress/subaddress.sieve, src/lib-sieve/sieve-
7713
 
+       address-parts.c, src/lib-sieve/sieve-common.h:
7714
 
+       Finished implementation of subaddress extension.
7715
 
+       [05c4031e501e]
7716
 
+
7717
 
+       * configure.in, src/lib-sieve/ext-envelope.c, src/lib-
7718
 
+       sieve/plugins/Makefile.am, src/lib-
7719
 
+       sieve/plugins/subaddress/Makefile.am, src/lib-
7720
 
+       sieve/plugins/subaddress/ext-subaddress.c, src/lib-
7721
 
+       sieve/plugins/subaddress/rfc3598.txt, src/lib-
7722
 
+       sieve/plugins/subaddress/subaddress.sieve, src/lib-
7723
 
+       sieve/plugins/vacation/ext-vacation.c, src/lib-sieve/sieve-address-
7724
 
+       parts.c, src/lib-sieve/sieve-address-parts.h, src/lib-sieve/sieve-
7725
 
+       ast.h, src/lib-sieve/sieve-binary.c, src/lib-sieve/sieve-binary.h,
7726
 
+       src/lib-sieve/sieve-commands.c, src/lib-sieve/sieve-commands.h, src
7727
 
+       /lib-sieve/sieve-comparators.c, src/lib-sieve/sieve-extensions.c,
7728
 
+       src/lib-sieve/sieve-extensions.h, src/lib-sieve/sieve-interpreter.c,
7729
 
+       src/lib-sieve/sieve-validator.c, src/lib-sieve/tst-address.c, src
7730
 
+       /lib-sieve/tst-size.c, src/sieve-bin/Makefile.am:
7731
 
+       Implemented support for the subaddress extension and fixed extension
7732
 
+       support to work properly.
7733
 
+       [4e9f385adc07]
7734
 
+
7735
 
+2007-11-14  Stephan Bosch  <stephan@rename-it.nl>
7736
 
+
7737
 
+       * sieve/tests/address-part.sieve, src/lib-sieve/sieve-address-parts.c,
7738
 
+       src/lib-sieve/sieve-address-parts.h, src/lib-sieve/tst-address.c:
7739
 
+       Implemented address part execution support.
7740
 
+       [af5ea3cdd396]
7741
 
+
7742
 
+2007-11-13  Stephan Bosch  <stephan@rename-it.nl>
7743
 
+
7744
 
+       * sieve/tests/address-part.sieve, src/lib-sieve/ext-envelope.c, src
7745
 
+       /lib-sieve/sieve-address-parts.c, src/lib-sieve/sieve-address-
7746
 
+       parts.h, src/lib-sieve/sieve-code.c, src/lib-sieve/sieve-code.h, src
7747
 
+       /lib-sieve/sieve-validator.c, src/lib-sieve/tst-address.c:
7748
 
+       Activated address-part code generation support.
7749
 
+       [60ab1abd0d01]
7750
 
+
7751
 
+       * src/lib-sieve/sieve-address-parts.c, src/lib-sieve/sieve-ast.h, src
7752
 
+       /lib-sieve/sieve-binary.c, src/lib-sieve/sieve-code.c, src/lib-sieve
7753
 
+       /sieve-code.h, src/lib-sieve/sieve-commands-private.h, src/lib-sieve
7754
 
+       /sieve-commands.c, src/lib-sieve/sieve-common.h, src/lib-sieve
7755
 
+       /sieve-comparators.c, src/lib-sieve/sieve-error.c, src/lib-sieve
7756
 
+       /sieve-error.h, src/lib-sieve/sieve-extensions.c, src/lib-sieve
7757
 
+       /sieve-generator.h, src/lib-sieve/sieve-interpreter.c, src/lib-sieve
7758
 
+       /sieve-interpreter.h, src/lib-sieve/sieve-lexer.c, src/lib-sieve
7759
 
+       /sieve-lexer.h, src/lib-sieve/sieve-parser.c, src/lib-sieve/sieve-
7760
 
+       parser.h, src/lib-sieve/sieve-validator.h:
7761
 
+       Lots of cosmetic changes
7762
 
+       [19366331bc99]
7763
 
+
7764
 
+       * INSTALL, README:
7765
 
+       Added a little documentation to the README file.
7766
 
+       [2fd76028ca9b]
7767
 
+
7768
 
+       * src/lib-sieve/sieve-validator.c:
7769
 
+       Removed unused static pre-declaration from validator.
7770
 
+       [f745b4988763]
7771
 
+
7772
 
+       * sieve/tests/comparator.sieve, src/lib-sieve/Makefile.am, src/lib-
7773
 
+       sieve/cmd-require.c, src/lib-sieve/ext-envelope.c, src/lib-sieve
7774
 
+       /ext-fileinto.c, src/lib-sieve/ext-reject.c, src/lib-
7775
 
+       sieve/plugins/vacation/ext-vacation.c, src/lib-sieve/sieve-address-
7776
 
+       parts.c, src/lib-sieve/sieve-address-parts.h, src/lib-sieve/sieve-
7777
 
+       binary.c, src/lib-sieve/sieve-binary.h, src/lib-sieve/sieve-code.c,
7778
 
+       src/lib-sieve/sieve-code.h, src/lib-sieve/sieve-comparators.c, src
7779
 
+       /lib-sieve/sieve-comparators.h, src/lib-sieve/sieve-extensions.c,
7780
 
+       src/lib-sieve/sieve-extensions.h, src/lib-sieve/sieve-generator.c,
7781
 
+       src/lib-sieve/sieve-generator.h, src/lib-sieve/sieve-interpreter.c,
7782
 
+       src/lib-sieve/sieve-interpreter.h, src/lib-sieve/sieve-validator.c,
7783
 
+       src/lib-sieve/sieve-validator.h, src/lib-sieve/sieve.c, src/lib-
7784
 
+       sieve/sieve.h, src/lib-sieve/tst-address.c, src/lib-sieve/tst-
7785
 
+       header.c, src/sieve-bin/sieve_test.c, src/sieve-bin/sievec.c:
7786
 
+       Rewrote large parts of the extension support and added partial
7787
 
+       address-part implementation.
7788
 
+       [bbbf416d458c]
7789
 
+
7790
 
+2007-11-11  Stephan Bosch  <stephan@rename-it.nl>
7791
 
+
7792
 
+       * src/sieve-bin/Makefile.am, src/sieve-bin/sieve_test.c:
7793
 
+       Upgraded sieve_test to 1.1.beta8
7794
 
+       [beaeb564662c]
7795
 
+
7796
 
+       * src/lib-sieve/sieve-commands.c, src/lib-sieve/sieve-common.h, src
7797
 
+       /lib-sieve/sieve-interpreter.c, src/lib-sieve/sieve-interpreter.h,
7798
 
+       src/lib-sieve/tst-address.c, src/lib-sieve/tst-header.c:
7799
 
+       Enabled comparator execution support.
7800
 
+       [5b4103b61afd]
7801
 
+
7802
 
+       * sieve/tests/comparator.sieve, src/lib-sieve/ext-envelope.c, src/lib-
7803
 
+       sieve/plugins/vacation/ext-vacation.c, src/lib-sieve/sieve-ast.c,
7804
 
+       src/lib-sieve/sieve-ast.h, src/lib-sieve/sieve-code.c, src/lib-sieve
7805
 
+       /sieve-code.h, src/lib-sieve/sieve-comparators.c, src/lib-sieve
7806
 
+       /sieve-comparators.h, src/lib-sieve/sieve-generator.c, src/lib-sieve
7807
 
+       /sieve-validator.c, src/lib-sieve/sieve-validator.h, src/lib-sieve
7808
 
+       /tst-address.c, src/lib-sieve/tst-header.c, src/lib-sieve/tst-
7809
 
+       size.c:
7810
 
+       Added support for optional operators to the byte code
7811
 
+       implementation.
7812
 
+       [9355ea520e77]
7813
 
+
7814
 
+2007-11-09  Stephan Bosch  <stephan@rename-it.nl>
7815
 
+
7816
 
+       * src/lib-sieve/ext-envelope.c, src/lib-sieve/ext-fileinto.c, src/lib-
7817
 
+       sieve/ext-reject.c, src/lib-sieve/plugins/vacation/ext-vacation.c,
7818
 
+       src/lib-sieve/sieve-binary.c, src/lib-sieve/sieve-binary.h, src/lib-
7819
 
+       sieve/sieve-code.c, src/lib-sieve/sieve-comparators.c, src/lib-sieve
7820
 
+       /sieve-comparators.h, src/lib-sieve/sieve-extensions.h, src/lib-
7821
 
+       sieve/sieve-interpreter.c, src/lib-sieve/sieve-interpreter.h:
7822
 
+       Started implementation of comparator execution support.
7823
 
+       [a3e2d0467235]
7824
 
+
7825
 
+2007-11-08  Stephan Bosch  <stephan@rename-it.nl>
7826
 
+
7827
 
+       * src/lib-sieve/sieve-code.c, src/lib-sieve/sieve-code.h:
7828
 
+       Changed string-list single-string handling for coded list.
7829
 
+       [494b84c7dab4]
7830
 
+
7831
 
+       * src/lib-sieve/cmd-if.c, src/lib-sieve/ext-envelope.c, src/lib-sieve
7832
 
+       /ext-fileinto.c, src/lib-sieve/ext-reject.c, src/lib-
7833
 
+       sieve/plugins/vacation/ext-vacation.c, src/lib-sieve/sieve-binary.c,
7834
 
+       src/lib-sieve/sieve-binary.h, src/lib-sieve/sieve-code.c, src/lib-
7835
 
+       sieve/sieve-code.h, src/lib-sieve/sieve-commands.c, src/lib-sieve
7836
 
+       /sieve-common.h, src/lib-sieve/sieve-comparators.c, src/lib-sieve
7837
 
+       /sieve-extensions.h, src/lib-sieve/sieve-generator.c, src/lib-sieve
7838
 
+       /sieve-generator.h, src/lib-sieve/sieve-interpreter.c, src/lib-sieve
7839
 
+       /sieve-interpreter.h, src/lib-sieve/tst-address.c, src/lib-sieve
7840
 
+       /tst-allof.c, src/lib-sieve/tst-anyof.c, src/lib-sieve/tst-exists.c,
7841
 
+       src/lib-sieve/tst-header.c, src/lib-sieve/tst-size.c:
7842
 
+       Properly implemented opcode and operand handing and moved code to
7843
 
+       more appropriate units.
7844
 
+       [6d30cd3270b4]
7845
 
+
7846
 
+2007-11-01  Stephan Bosch  <stephan@rename-it.nl>
7847
 
+
7848
 
+       * sieve/examples/sieve_examples.sieve, sieve/examples/stephan.sieve,
7849
 
+       sieve/examples/unparsed-elvey.sieve, src/lib-sieve/sieve-code.h:
7850
 
+       A few minor changes
7851
 
+       [8eb67ba19a03]
7852
 
+
7853
 
+       * sieve/examples/elvey.sieve, sieve/examples/jerry.sieve,
7854
 
+       sieve/examples/mjohnson.sieve, sieve/examples/mklose.sieve,
7855
 
+       sieve/examples/sanjay.sieve, sieve/examples/vivil.sieve:
7856
 
+       Added sieve example and documented the others with author and the
7857
 
+       url where I found them.
7858
 
+       [36b747fc5a42]
7859
 
+
7860
 
+2007-10-27  Stephan Bosch  <stephan@rename-it.nl>
7861
 
+
7862
 
+       * src/lib-sieve/sieve-binary.c, src/lib-sieve/sieve-binary.h, src/lib-
7863
 
+       sieve/sieve-comparators.c, src/lib-sieve/sieve-interpreter.c, src
7864
 
+       /lib-sieve/sieve-interpreter.h:
7865
 
+       Moved literall access functions from interpreter to binary.
7866
 
+       [df004c3d4967]
7867
 
+
7868
 
+       * src/lib-sieve/sieve-binary.c, src/lib-sieve/sieve-code.c, src/lib-
7869
 
+       sieve/sieve-comparators.c, src/lib-sieve/sieve-comparators.h, src
7870
 
+       /lib-sieve/sieve-generator.c, src/lib-sieve/sieve-generator.h:
7871
 
+       Implemented comparator support towards code generation,
7872
 
+       interpretation is not possible yet.
7873
 
+       [c4eb303c242c]
7874
 
+
7875
 
+       * src/lib-sieve/ext-envelope.c, src/lib-sieve/ext-fileinto.c, src/lib-
7876
 
+       sieve/ext-reject.c, src/lib-sieve/plugins/vacation/ext-vacation.c,
7877
 
+       src/lib-sieve/sieve-binary.h, src/lib-sieve/sieve-code.c, src/lib-
7878
 
+       sieve/sieve-code.h, src/lib-sieve/sieve-commands.c, src/lib-sieve
7879
 
+       /sieve-commands.h, src/lib-sieve/sieve-generator.c, src/lib-sieve
7880
 
+       /sieve-generator.h, src/lib-sieve/sieve-interpreter.c, src/lib-sieve
7881
 
+       /sieve-validator.c, src/lib-sieve/sieve-validator.h, src/lib-sieve
7882
 
+       /tst-address.c, src/lib-sieve/tst-exists.c, src/lib-sieve/tst-
7883
 
+       header.c, src/lib-sieve/tst-size.c:
7884
 
+       Changed argument to operand processing to be much more flexible.
7885
 
+       [b07f5129b239]
7886
 
+
7887
 
+2007-10-26  Stephan Bosch  <stephan@rename-it.nl>
7888
 
+
7889
 
+       * src/lib-sieve/sieve-binary.c, src/lib-sieve/sieve-binary.h, src/lib-
7890
 
+       sieve/sieve-generator.c, src/lib-sieve/sieve-generator.h:
7891
 
+       Moved literal emission functions from generator to binary source.
7892
 
+       [8d9c3aa76abf]
7893
 
+
7894
 
+       * sieve/tests/comparator.sieve, src/lib-sieve/Makefile.am, src/lib-
7895
 
+       sieve/plugins/vacation/ext-vacation.c, src/lib-sieve/sieve-ast.c,
7896
 
+       src/lib-sieve/sieve-ast.h, src/lib-sieve/sieve-code.c, src/lib-sieve
7897
 
+       /sieve-code.h, src/lib-sieve/sieve-commands.h, src/lib-sieve/sieve-
7898
 
+       common.h, src/lib-sieve/sieve-comparators.c, src/lib-sieve/sieve-
7899
 
+       comparators.h, src/lib-sieve/sieve-generator.c, src/lib-sieve/sieve-
7900
 
+       generator.h, src/lib-sieve/sieve-validator.c, src/lib-sieve/sieve-
7901
 
+       validator.h, src/lib-sieve/tst-size.c:
7902
 
+       First steps towards implementing code generation and interpretation
7903
 
+       for proper comperators.
7904
 
+       [8f8c18edbd39]
7905
 
+
7906
 
+       * src/lib-sieve/tst-exists.c:
7907
 
+       Extremely minor cosmetic change.
7908
 
+       [8b215ab7e80f]
7909
 
+
7910
 
+       * src/lib-sieve/plugins/Makefile, src/lib-sieve/plugins/Makefile.in:
7911
 
+       Removed files with intermittent compilation results from the
7912
 
+       repository (oops)
7913
 
+       [3c56353ce681]
7914
 
+
7915
 
+       * sieve/tests/basic.sieve, src/lib-sieve/sieve-generator.c, src/lib-
7916
 
+       sieve/tst-exists.c, src/lib-sieve/tst-header.c:
7917
 
+       Made header and exists tests executable.
7918
 
+       [38b4e757271d]
7919
 
+
7920
 
+2007-10-25  Stephan Bosch  <stephan@rename-it.nl>
7921
 
+
7922
 
+       * sieve/tests/basic.sieve, src/lib-sieve/sieve-binary.c, src/lib-sieve
7923
 
+       /sieve-code.c, src/lib-sieve/sieve-code.h, src/lib-sieve/sieve-
7924
 
+       interpreter.c, src/lib-sieve/sieve-interpreter.h, src/lib-sieve
7925
 
+       /sieve-lexer.c, src/lib-sieve/sieve.c, src/lib-sieve/sieve.h, src
7926
 
+       /lib-sieve/tst-address.c, src/lib-sieve/tst-size.c, src/sieve-
7927
 
+       bin/Makefile.am, src/sieve-bin/sieve_test.c, src/sieve-bin/sievec.c:
7928
 
+       Made address and size tests executable and fixed minor bug regarding
7929
 
+       the lexer.
7930
 
+       [931a0b442f19]
7931
 
+
7932
 
+       * .hgignore, src/lib-sieve/Makefile.am, src/lib-sieve/sieve-ast.c, src
7933
 
+       /lib-sieve/sieve-generator.c, src/lib-sieve/sieve-generator.h, src
7934
 
+       /lib-sieve/sieve-parser.c, src/lib-sieve/sieve-parser.h, src/lib-
7935
 
+       sieve/sieve-validator.c, src/lib-sieve/sieve-validator.h, src/lib-
7936
 
+       sieve/sieve.c, src/lib-sieve/sieve.h, src/sieve-bin/Makefile, src
7937
 
+       /sieve-bin/Makefile.am, src/sieve-bin/Makefile.in, src/sieve-
7938
 
+       bin/sieve_test.c, src/sieve-bin/sievec, src/sieve-bin/sievec.c, src
7939
 
+       /sieve-bin/sievec.o:
7940
 
+       Created libsieve interface and started the sieve_test binary.
7941
 
+       [8d922df3dd5c]
7942
 
+
7943
 
+2007-10-24  Stephan Bosch  <stephan@rename-it.nl>
7944
 
+
7945
 
+       * src/lib-sieve/cmd-if.c, src/lib-sieve/ext-fileinto.c, src/lib-sieve
7946
 
+       /ext-reject.c, src/lib-sieve/plugins/Makefile, src/lib-
7947
 
+       sieve/plugins/vacation/ext-vacation.c, src/lib-sieve/sieve-ast.c,
7948
 
+       src/lib-sieve/sieve-binary.c, src/lib-sieve/sieve-code.c, src/lib-
7949
 
+       sieve/sieve-commands.c, src/lib-sieve/sieve-generator.c, src/lib-
7950
 
+       sieve/sieve-generator.h, src/lib-sieve/sieve-interpreter.c, src/lib-
7951
 
+       sieve/sieve-lexer.c, src/lib-sieve/sieve-parser.c, src/lib-sieve
7952
 
+       /sieve-result.c, src/lib-sieve/sieve-validator.c, src/lib-sieve/tst-
7953
 
+       address.c, src/lib-sieve/tst-size.c, src/sieve-bin/Makefile, src
7954
 
+       /sieve-bin/Makefile.am, src/sieve-bin/Makefile.in, src/sieve-
7955
 
+       bin/sievec, src/sieve-bin/sievec.o:
7956
 
+       Upgraded from dovecot-1.0 to dovecot-1.1 (array changes and various
7957
 
+       _unref differences)
7958
 
+       [f36e62f9baf9]
7959
 
+
7960
 
+       * configure.in, sieve/errors/address-errors.sieve, sieve/errors
7961
 
+       /header-errors.sieve, sieve/errors/if-errors.sieve,
7962
 
+       sieve/errors/interesting.sieve, sieve/errors/keep-errors.sieve,
7963
 
+       sieve/errors/parse-errors.sieve, sieve/errors/require-errors.sieve,
7964
 
+       sieve/errors/size-errors.sieve, sieve/errors/stop-errors.sieve,
7965
 
+       sieve/errors/tag-errors.sieve, sieve/examples/elvey.sieve,
7966
 
+       sieve/examples/mjohnson.sieve, sieve/examples/mklose.sieve,
7967
 
+       sieve/examples/rfc3028.sieve, sieve/examples/sanjay.sieve,
7968
 
+       sieve/examples/sieve_examples.sieve, sieve/examples/stephan.sieve,
7969
 
+       sieve/examples/unparsed-elvey.sieve, sieve/examples/vacation.sieve,
7970
 
+       sieve/examples/vivil.sieve, sieve/tests/basic.sieve,
7971
 
+       sieve/tests/extensions.sieve, sieve/tests/if.sieve, src/Makefile.am,
7972
 
+       src/lib-sieve/Makefile.am, src/lib-sieve/scripts/errors/address-
7973
 
+       errors.sieve, src/lib-sieve/scripts/errors/header-errors.sieve, src
7974
 
+       /lib-sieve/scripts/errors/if-errors.sieve, src/lib-
7975
 
+       sieve/scripts/errors/interesting.sieve, src/lib-sieve/scripts/errors
7976
 
+       /keep-errors.sieve, src/lib-sieve/scripts/errors/parse-errors.sieve,
7977
 
+       src/lib-sieve/scripts/errors/require-errors.sieve, src/lib-
7978
 
+       sieve/scripts/errors/size-errors.sieve, src/lib-sieve/scripts/errors
7979
 
+       /stop-errors.sieve, src/lib-sieve/scripts/errors/tag-errors.sieve,
7980
 
+       src/lib-sieve/scripts/examples/elvey.sieve, src/lib-
7981
 
+       sieve/scripts/examples/mjohnson.sieve, src/lib-
7982
 
+       sieve/scripts/examples/mklose.sieve, src/lib-
7983
 
+       sieve/scripts/examples/rfc3028.sieve, src/lib-
7984
 
+       sieve/scripts/examples/sanjay.sieve, src/lib-
7985
 
+       sieve/scripts/examples/sieve_examples.sieve, src/lib-
7986
 
+       sieve/scripts/examples/stephan.sieve, src/lib-sieve/scripts/examples
7987
 
+       /unparsed-elvey.sieve, src/lib-
7988
 
+       sieve/scripts/examples/vacation.sieve, src/lib-
7989
 
+       sieve/scripts/examples/vivil.sieve, src/lib-
7990
 
+       sieve/scripts/tests/extensions.sieve, src/lib-
7991
 
+       sieve/scripts/tests/if.sieve, src/lib-sieve/sieve-code.c, src/lib-
7992
 
+       sieve/sieve-code.h, src/lib-sieve/sieve-interpreter.c, src/lib-sieve
7993
 
+       /sieve-interpreter.h, src/lib-sieve/sieve-result.c, src/lib-
7994
 
+       sieve/sievec.c, src/lib-sieve/tst-address.c, src/lib-sieve/tst-
7995
 
+       exists.c, src/lib-sieve/tst-header.c, src/lib-sieve/tst-size.c, src
7996
 
+       /sieve-bin/Makefile, src/sieve-bin/Makefile.am, src/sieve-
7997
 
+       bin/Makefile.in, src/sieve-bin/sievec, src/sieve-bin/sievec.c, src
7998
 
+       /sieve-bin/sievec.o:
7999
 
+       Exported sievec binary to separate directory called sieve-bin.
8000
 
+       [f3dd838d3893]
8001
 
+
8002
 
+2007-10-23  Stephan Bosch  <stephan@rename-it.nl>
8003
 
+
8004
 
+       * src/lib-sieve/Makefile.am, src/lib-sieve/cmd-if.c, src/lib-sieve
8005
 
+       /ext-envelope.c, src/lib-sieve/ext-fileinto.c, src/lib-sieve/ext-
8006
 
+       reject.c, src/lib-sieve/plugins/vacation/Makefile.am, src/lib-
8007
 
+       sieve/plugins/vacation/ext-vacation.c, src/lib-sieve/sieve-binary.c,
8008
 
+       src/lib-sieve/sieve-binary.h, src/lib-sieve/sieve-code.c, src/lib-
8009
 
+       sieve/sieve-code.h, src/lib-sieve/sieve-commands.c, src/lib-sieve
8010
 
+       /sieve-common.h, src/lib-sieve/sieve-extensions.h, src/lib-sieve
8011
 
+       /sieve-generator.c, src/lib-sieve/sieve-generator.h, src/lib-sieve
8012
 
+       /sieve-interpreter.c, src/lib-sieve/sieve-interpreter.h, src/lib-
8013
 
+       sieve/sieve-result.c, src/lib-sieve/sieve-result.h, src/lib-sieve
8014
 
+       /tst-address.c, src/lib-sieve/tst-allof.c, src/lib-sieve/tst-
8015
 
+       anyof.c, src/lib-sieve/tst-exists.c, src/lib-sieve/tst-header.c, src
8016
 
+       /lib-sieve/tst-size.c:
8017
 
+       Started first support for actual execution of sieve script.
8018
 
+       [7d3b717d834d]
8019
 
+
8020
 
+       * src/lib-sieve/Makefile.am, src/lib-sieve/ext-fileinto.c, src/lib-
8021
 
+       sieve/sieve-interpreter.h, src/plugins/Makefile.am, src/plugins/lda-
8022
 
+       sieve/Makefile.am, src/plugins/lda-sieve/lda-sieve-plugin.c,
8023
 
+       src/plugins/lda-sieve/lda-sieve-plugin.h:
8024
 
+       * Minor changes to the extension implementation
8025
 
+       * Started the lda plugin source
8026
 
+       [5252fd9fd951]
8027
 
+
8028
 
+2007-10-22  Stephan Bosch  <stephan@rename-it.nl>
8029
 
+
8030
 
+       * src/lib-sieve/sieve-address.c:
8031
 
+       Changed (currently unused) sieve-address.c to use dovecot rfc822
8032
 
+       parser.
8033
 
+       [d32cc88f0ecf]
8034
 
+
8035
 
+       * src/lib-sieve/plugins/vacation/draft-ietf-sieve-vacation-07.txt:
8036
 
+       Added draft RFC for vacation extension.
8037
 
+       [4f6590dd1d7e]
8038
 
+
8039
 
+       * configure.in, src/lib-sieve/Makefile.am, src/lib-sieve/ext-
8040
 
+       envelope.c, src/lib-sieve/ext-fileinto.c, src/lib-sieve/ext-
8041
 
+       reject.c, src/lib-sieve/plugins/Makefile, src/lib-
8042
 
+       sieve/plugins/Makefile.am, src/lib-sieve/plugins/Makefile.in, src
8043
 
+       /lib-sieve/plugins/comparator-i;ascii-numeric.c, src/lib-
8044
 
+       sieve/plugins/copy.c, src/lib-sieve/plugins/vacation/Makefile.am,
8045
 
+       src/lib-sieve/plugins/vacation/ext-vacation.c, src/lib-
8046
 
+       sieve/plugins/vacation/vacation.sieve, src/lib-
8047
 
+       sieve/scripts/tests/extensions.sieve, src/lib-sieve/sieve-
8048
 
+       extensions.c:
8049
 
+       * Further developed the extension support
8050
 
+       * Added plugins as static libraries (for now)
8051
 
+       [2b26d303f3d1]
8052
 
+
8053
 
+       * src/lib-sieve/scripts/tests/extensions.sieve, src/lib-
8054
 
+       sieve/scripts/tests/reject.sieve:
8055
 
+       Renamed reject.sieve to extensions.sieve for generic extensions
8056
 
+       testing.
8057
 
+       [3993600b2e1f]
8058
 
+
8059
 
+       * src/lib-sieve/cmd-require.c, src/lib-sieve/ext-fileinto.c:
8060
 
+       * Added generation support to the fileinto extension.
8061
 
+       * Fixed a bug in the require command generation.
8062
 
+       [4f38530232e6]
8063
 
+
8064
 
+       * .hgignore, src/lib-sieve/Makefile.am, src/lib-sieve/cmd-require.c,
8065
 
+       src/lib-sieve/ext-envelope.c, src/lib-sieve/ext-fileinto.c, src/lib-
8066
 
+       sieve/ext-reject.c, src/lib-sieve/scripts/tests/reject.sieve, src
8067
 
+       /lib-sieve/sieve-ast.h, src/lib-sieve/sieve-binary.c, src/lib-sieve
8068
 
+       /sieve-binary.h, src/lib-sieve/sieve-code.h, src/lib-sieve/sieve-
8069
 
+       extensions.c, src/lib-sieve/sieve-extensions.h, src/lib-sieve/sieve-
8070
 
+       generator.c, src/lib-sieve/sieve-generator.h, src/lib-sieve/sieve-
8071
 
+       interpreter.c, src/lib-sieve/sieve-interpreter.h, src/lib-sieve
8072
 
+       /sieve-validator.c, src/lib-sieve/sieve-validator.h, src/lib-
8073
 
+       sieve/sievec.c:
8074
 
+       Added basic extension support to generator and interpreter.
8075
 
+       [2f78fc8c9919]
8076
 
+
8077
 
+2007-10-21  Stephan Bosch  <stephan@rename-it.nl>
8078
 
+
8079
 
+       * src/lib-sieve/cmd-if.c, src/lib-sieve/ext-reject.c, src/lib-sieve
8080
 
+       /sieve-code.c, src/lib-sieve/sieve-code.h, src/lib-sieve/sieve-
8081
 
+       commands-private.h, src/lib-sieve/sieve-commands.c, src/lib-sieve
8082
 
+       /sieve-extensions.h, src/lib-sieve/sieve-generator.c, src/lib-sieve
8083
 
+       /sieve-generator.h, src/lib-sieve/sieve-interpreter.c, src/lib-sieve
8084
 
+       /tst-address.c, src/lib-sieve/tst-allof.c, src/lib-sieve/tst-
8085
 
+       anyof.c, src/lib-sieve/tst-exists.c, src/lib-sieve/tst-header.c, src
8086
 
+       /lib-sieve/tst-size.c:
8087
 
+       Initial commit didn't compile because it was comitted in the middle
8088
 
+       of a new feature.
8089
 
+       [b50c7ada434a]
8090
 
+
8091
 
+       * autogen.sh:
8092
 
+       Added autogen.sh from the dovecot project (removed doc/wiki code)
8093
 
+       [10ed2a377ea0]
8094
 
+
8095
 
+2007-10-21  stephan  <stephan@flappie>
8096
 
+
8097
 
+       * .hgignore, libsieve-config.h.in:
8098
 
+       Added -config files to the hgignore and removed them from the
8099
 
+       repository
8100
 
+       [ddac82bec3c3]
8101
 
+
8102
 
+       * .hgignore, AUTHORS, COPYING.LGPL, INSTALL, Makefile.am, NEWS,
8103
 
+       README, configure.in, libsieve-config.h.in, src/Makefile.am, src
8104
 
+       /lib-sieve/Makefile.am, src/lib-sieve/cmd-if.c, src/lib-sieve/cmd-
8105
 
+       redirect.c, src/lib-sieve/cmd-require.c, src/lib-sieve/ext-
8106
 
+       envelope.c, src/lib-sieve/ext-fileinto.c, src/lib-sieve/ext-
8107
 
+       reject.c, src/lib-sieve/plugins/comparator-i;ascii-numeric.c, src
8108
 
+       /lib-sieve/plugins/copy.c, src/lib-sieve/scripts/errors/address-
8109
 
+       errors.sieve, src/lib-sieve/scripts/errors/header-errors.sieve, src
8110
 
+       /lib-sieve/scripts/errors/if-errors.sieve, src/lib-
8111
 
+       sieve/scripts/errors/interesting.sieve, src/lib-sieve/scripts/errors
8112
 
+       /keep-errors.sieve, src/lib-sieve/scripts/errors/parse-errors.sieve,
8113
 
+       src/lib-sieve/scripts/errors/require-errors.sieve, src/lib-
8114
 
+       sieve/scripts/errors/size-errors.sieve, src/lib-sieve/scripts/errors
8115
 
+       /stop-errors.sieve, src/lib-sieve/scripts/errors/tag-errors.sieve,
8116
 
+       src/lib-sieve/scripts/examples/elvey.sieve, src/lib-
8117
 
+       sieve/scripts/examples/mjohnson.sieve, src/lib-
8118
 
+       sieve/scripts/examples/mklose.sieve, src/lib-
8119
 
+       sieve/scripts/examples/rfc3028.sieve, src/lib-
8120
 
+       sieve/scripts/examples/sanjay.sieve, src/lib-
8121
 
+       sieve/scripts/examples/sieve_examples.sieve, src/lib-
8122
 
+       sieve/scripts/examples/stephan.sieve, src/lib-sieve/scripts/examples
8123
 
+       /unparsed-elvey.sieve, src/lib-
8124
 
+       sieve/scripts/examples/vacation.sieve, src/lib-
8125
 
+       sieve/scripts/examples/vivil.sieve, src/lib-
8126
 
+       sieve/scripts/tests/if.sieve, src/lib-sieve/sieve-address.c, src
8127
 
+       /lib-sieve/sieve-ast.c, src/lib-sieve/sieve-ast.h, src/lib-sieve
8128
 
+       /sieve-code.c, src/lib-sieve/sieve-code.h, src/lib-sieve/sieve-
8129
 
+       commands-private.h, src/lib-sieve/sieve-commands.c, src/lib-sieve
8130
 
+       /sieve-commands.h, src/lib-sieve/sieve-common.h, src/lib-sieve
8131
 
+       /sieve-error.c, src/lib-sieve/sieve-error.h, src/lib-sieve/sieve-
8132
 
+       extensions.c, src/lib-sieve/sieve-extensions.h, src/lib-sieve/sieve-
8133
 
+       generator.c, src/lib-sieve/sieve-generator.h, src/lib-sieve/sieve-
8134
 
+       interpreter.c, src/lib-sieve/sieve-interpreter.h, src/lib-sieve
8135
 
+       /sieve-lexer.c, src/lib-sieve/sieve-lexer.h, src/lib-sieve/sieve-
8136
 
+       parser.c, src/lib-sieve/sieve-parser.h, src/lib-sieve/sieve-
8137
 
+       validator.c, src/lib-sieve/sieve-validator.h, src/lib-
8138
 
+       sieve/sievec.c, src/lib-sieve/tst-address.c, src/lib-sieve/tst-
8139
 
+       allof.c, src/lib-sieve/tst-anyof.c, src/lib-sieve/tst-exists.c, src
8140
 
+       /lib-sieve/tst-header.c, src/lib-sieve/tst-not.c, src/lib-sieve/tst-
8141
 
+       size.c, stamp.h.in:
8142
 
+       First entered libsieve into new Hg repository
8143
 
+       [d31c1c993bcf]
8144
 
+
8145
 
diff -urN dovecot-1.2.4/dovecot-libsieve/config.rpath dovecot-1.2.4.debian/dovecot-libsieve/config.rpath
8146
 
--- dovecot-1.2.4/dovecot-libsieve/config.rpath 1970-01-01 01:00:00.000000000 +0100
8147
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/config.rpath  2009-08-21 00:55:29.000000000 +0200
8148
 
@@ -0,0 +1,666 @@
8149
 
+#! /bin/sh
8150
 
+# Output a system dependent set of variables, describing how to set the
8151
 
+# run time search path of shared libraries in an executable.
8152
 
+#
8153
 
+#   Copyright 1996-2007 Free Software Foundation, Inc.
8154
 
+#   Taken from GNU libtool, 2001
8155
 
+#   Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
8156
 
+#
8157
 
+#   This file is free software; the Free Software Foundation gives
8158
 
+#   unlimited permission to copy and/or distribute it, with or without
8159
 
+#   modifications, as long as this notice is preserved.
8160
 
+#
8161
 
+# The first argument passed to this file is the canonical host specification,
8162
 
+#    CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
8163
 
+# or
8164
 
+#    CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
8165
 
+# The environment variables CC, GCC, LDFLAGS, LD, with_gnu_ld
8166
 
+# should be set by the caller.
8167
 
+#
8168
 
+# The set of defined variables is at the end of this script.
8169
 
+
8170
 
+# Known limitations:
8171
 
+# - On IRIX 6.5 with CC="cc", the run time search patch must not be longer
8172
 
+#   than 256 bytes, otherwise the compiler driver will dump core. The only
8173
 
+#   known workaround is to choose shorter directory names for the build
8174
 
+#   directory and/or the installation directory.
8175
 
+
8176
 
+# All known linkers require a `.a' archive for static linking (except MSVC,
8177
 
+# which needs '.lib').
8178
 
+libext=a
8179
 
+shrext=.so
8180
 
+
8181
 
+host="$1"
8182
 
+host_cpu=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
8183
 
+host_vendor=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
8184
 
+host_os=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
8185
 
+
8186
 
+# Code taken from libtool.m4's _LT_CC_BASENAME.
8187
 
+
8188
 
+for cc_temp in $CC""; do
8189
 
+  case $cc_temp in
8190
 
+    compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
8191
 
+    distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
8192
 
+    \-*) ;;
8193
 
+    *) break;;
8194
 
+  esac
8195
 
+done
8196
 
+cc_basename=`echo "$cc_temp" | sed -e 's%^.*/%%'`
8197
 
+
8198
 
+# Code taken from libtool.m4's AC_LIBTOOL_PROG_COMPILER_PIC.
8199
 
+
8200
 
+wl=
8201
 
+if test "$GCC" = yes; then
8202
 
+  wl='-Wl,'
8203
 
+else
8204
 
+  case "$host_os" in
8205
 
+    aix*)
8206
 
+      wl='-Wl,'
8207
 
+      ;;
8208
 
+    darwin*)
8209
 
+      case $cc_basename in
8210
 
+        xlc*)
8211
 
+          wl='-Wl,'
8212
 
+          ;;
8213
 
+      esac
8214
 
+      ;;
8215
 
+    mingw* | cygwin* | pw32* | os2*)
8216
 
+      ;;
8217
 
+    hpux9* | hpux10* | hpux11*)
8218
 
+      wl='-Wl,'
8219
 
+      ;;
8220
 
+    irix5* | irix6* | nonstopux*)
8221
 
+      wl='-Wl,'
8222
 
+      ;;
8223
 
+    newsos6)
8224
 
+      ;;
8225
 
+    linux* | k*bsd*-gnu)
8226
 
+      case $cc_basename in
8227
 
+        icc* | ecc*)
8228
 
+          wl='-Wl,'
8229
 
+          ;;
8230
 
+        pgcc | pgf77 | pgf90)
8231
 
+          wl='-Wl,'
8232
 
+          ;;
8233
 
+        ccc*)
8234
 
+          wl='-Wl,'
8235
 
+          ;;
8236
 
+        como)
8237
 
+          wl='-lopt='
8238
 
+          ;;
8239
 
+        *)
8240
 
+          case `$CC -V 2>&1 | sed 5q` in
8241
 
+            *Sun\ C*)
8242
 
+              wl='-Wl,'
8243
 
+              ;;
8244
 
+          esac
8245
 
+          ;;
8246
 
+      esac
8247
 
+      ;;
8248
 
+    osf3* | osf4* | osf5*)
8249
 
+      wl='-Wl,'
8250
 
+      ;;
8251
 
+    rdos*)
8252
 
+      ;;
8253
 
+    solaris*)
8254
 
+      wl='-Wl,'
8255
 
+      ;;
8256
 
+    sunos4*)
8257
 
+      wl='-Qoption ld '
8258
 
+      ;;
8259
 
+    sysv4 | sysv4.2uw2* | sysv4.3*)
8260
 
+      wl='-Wl,'
8261
 
+      ;;
8262
 
+    sysv4*MP*)
8263
 
+      ;;
8264
 
+    sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
8265
 
+      wl='-Wl,'
8266
 
+      ;;
8267
 
+    unicos*)
8268
 
+      wl='-Wl,'
8269
 
+      ;;
8270
 
+    uts4*)
8271
 
+      ;;
8272
 
+  esac
8273
 
+fi
8274
 
+
8275
 
+# Code taken from libtool.m4's AC_LIBTOOL_PROG_LD_SHLIBS.
8276
 
+
8277
 
+hardcode_libdir_flag_spec=
8278
 
+hardcode_libdir_separator=
8279
 
+hardcode_direct=no
8280
 
+hardcode_minus_L=no
8281
 
+
8282
 
+case "$host_os" in
8283
 
+  cygwin* | mingw* | pw32*)
8284
 
+    # FIXME: the MSVC++ port hasn't been tested in a loooong time
8285
 
+    # When not using gcc, we currently assume that we are using
8286
 
+    # Microsoft Visual C++.
8287
 
+    if test "$GCC" != yes; then
8288
 
+      with_gnu_ld=no
8289
 
+    fi
8290
 
+    ;;
8291
 
+  interix*)
8292
 
+    # we just hope/assume this is gcc and not c89 (= MSVC++)
8293
 
+    with_gnu_ld=yes
8294
 
+    ;;
8295
 
+  openbsd*)
8296
 
+    with_gnu_ld=no
8297
 
+    ;;
8298
 
+esac
8299
 
+
8300
 
+ld_shlibs=yes
8301
 
+if test "$with_gnu_ld" = yes; then
8302
 
+  # Set some defaults for GNU ld with shared library support. These
8303
 
+  # are reset later if shared libraries are not supported. Putting them
8304
 
+  # here allows them to be overridden if necessary.
8305
 
+  # Unlike libtool, we use -rpath here, not --rpath, since the documented
8306
 
+  # option of GNU ld is called -rpath, not --rpath.
8307
 
+  hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
8308
 
+  case "$host_os" in
8309
 
+    aix3* | aix4* | aix5*)
8310
 
+      # On AIX/PPC, the GNU linker is very broken
8311
 
+      if test "$host_cpu" != ia64; then
8312
 
+        ld_shlibs=no
8313
 
+      fi
8314
 
+      ;;
8315
 
+    amigaos*)
8316
 
+      hardcode_libdir_flag_spec='-L$libdir'
8317
 
+      hardcode_minus_L=yes
8318
 
+      # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports
8319
 
+      # that the semantics of dynamic libraries on AmigaOS, at least up
8320
 
+      # to version 4, is to share data among multiple programs linked
8321
 
+      # with the same dynamic library.  Since this doesn't match the
8322
 
+      # behavior of shared libraries on other platforms, we cannot use
8323
 
+      # them.
8324
 
+      ld_shlibs=no
8325
 
+      ;;
8326
 
+    beos*)
8327
 
+      if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
8328
 
+        :
8329
 
+      else
8330
 
+        ld_shlibs=no
8331
 
+      fi
8332
 
+      ;;
8333
 
+    cygwin* | mingw* | pw32*)
8334
 
+      # hardcode_libdir_flag_spec is actually meaningless, as there is
8335
 
+      # no search path for DLLs.
8336
 
+      hardcode_libdir_flag_spec='-L$libdir'
8337
 
+      if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
8338
 
+        :
8339
 
+      else
8340
 
+        ld_shlibs=no
8341
 
+      fi
8342
 
+      ;;
8343
 
+    interix[3-9]*)
8344
 
+      hardcode_direct=no
8345
 
+      hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
8346
 
+      ;;
8347
 
+    gnu* | linux* | k*bsd*-gnu)
8348
 
+      if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
8349
 
+        :
8350
 
+      else
8351
 
+        ld_shlibs=no
8352
 
+      fi
8353
 
+      ;;
8354
 
+    netbsd*)
8355
 
+      ;;
8356
 
+    solaris*)
8357
 
+      if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then
8358
 
+        ld_shlibs=no
8359
 
+      elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
8360
 
+        :
8361
 
+      else
8362
 
+        ld_shlibs=no
8363
 
+      fi
8364
 
+      ;;
8365
 
+    sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
8366
 
+      case `$LD -v 2>&1` in
8367
 
+        *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
8368
 
+          ld_shlibs=no
8369
 
+          ;;
8370
 
+        *)
8371
 
+          if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
8372
 
+            hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`'
8373
 
+          else
8374
 
+            ld_shlibs=no
8375
 
+          fi
8376
 
+          ;;
8377
 
+      esac
8378
 
+      ;;
8379
 
+    sunos4*)
8380
 
+      hardcode_direct=yes
8381
 
+      ;;
8382
 
+    *)
8383
 
+      if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
8384
 
+        :
8385
 
+      else
8386
 
+        ld_shlibs=no
8387
 
+      fi
8388
 
+      ;;
8389
 
+  esac
8390
 
+  if test "$ld_shlibs" = no; then
8391
 
+    hardcode_libdir_flag_spec=
8392
 
+  fi
8393
 
+else
8394
 
+  case "$host_os" in
8395
 
+    aix3*)
8396
 
+      # Note: this linker hardcodes the directories in LIBPATH if there
8397
 
+      # are no directories specified by -L.
8398
 
+      hardcode_minus_L=yes
8399
 
+      if test "$GCC" = yes; then
8400
 
+        # Neither direct hardcoding nor static linking is supported with a
8401
 
+        # broken collect2.
8402
 
+        hardcode_direct=unsupported
8403
 
+      fi
8404
 
+      ;;
8405
 
+    aix4* | aix5*)
8406
 
+      if test "$host_cpu" = ia64; then
8407
 
+        # On IA64, the linker does run time linking by default, so we don't
8408
 
+        # have to do anything special.
8409
 
+        aix_use_runtimelinking=no
8410
 
+      else
8411
 
+        aix_use_runtimelinking=no
8412
 
+        # Test if we are trying to use run time linking or normal
8413
 
+        # AIX style linking. If -brtl is somewhere in LDFLAGS, we
8414
 
+        # need to do runtime linking.
8415
 
+        case $host_os in aix4.[23]|aix4.[23].*|aix5*)
8416
 
+          for ld_flag in $LDFLAGS; do
8417
 
+            if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
8418
 
+              aix_use_runtimelinking=yes
8419
 
+              break
8420
 
+            fi
8421
 
+          done
8422
 
+          ;;
8423
 
+        esac
8424
 
+      fi
8425
 
+      hardcode_direct=yes
8426
 
+      hardcode_libdir_separator=':'
8427
 
+      if test "$GCC" = yes; then
8428
 
+        case $host_os in aix4.[012]|aix4.[012].*)
8429
 
+          collect2name=`${CC} -print-prog-name=collect2`
8430
 
+          if test -f "$collect2name" && \
8431
 
+            strings "$collect2name" | grep resolve_lib_name >/dev/null
8432
 
+          then
8433
 
+            # We have reworked collect2
8434
 
+            :
8435
 
+          else
8436
 
+            # We have old collect2
8437
 
+            hardcode_direct=unsupported
8438
 
+            hardcode_minus_L=yes
8439
 
+            hardcode_libdir_flag_spec='-L$libdir'
8440
 
+            hardcode_libdir_separator=
8441
 
+          fi
8442
 
+          ;;
8443
 
+        esac
8444
 
+      fi
8445
 
+      # Begin _LT_AC_SYS_LIBPATH_AIX.
8446
 
+      echo 'int main () { return 0; }' > conftest.c
8447
 
+      ${CC} ${LDFLAGS} conftest.c -o conftest
8448
 
+      aix_libpath=`dump -H conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
8449
 
+}'`
8450
 
+      if test -z "$aix_libpath"; then
8451
 
+        aix_libpath=`dump -HX64 conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
8452
 
+}'`
8453
 
+      fi
8454
 
+      if test -z "$aix_libpath"; then
8455
 
+        aix_libpath="/usr/lib:/lib"
8456
 
+      fi
8457
 
+      rm -f conftest.c conftest
8458
 
+      # End _LT_AC_SYS_LIBPATH_AIX.
8459
 
+      if test "$aix_use_runtimelinking" = yes; then
8460
 
+        hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
8461
 
+      else
8462
 
+        if test "$host_cpu" = ia64; then
8463
 
+          hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
8464
 
+        else
8465
 
+          hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
8466
 
+        fi
8467
 
+      fi
8468
 
+      ;;
8469
 
+    amigaos*)
8470
 
+      hardcode_libdir_flag_spec='-L$libdir'
8471
 
+      hardcode_minus_L=yes
8472
 
+      # see comment about different semantics on the GNU ld section
8473
 
+      ld_shlibs=no
8474
 
+      ;;
8475
 
+    bsdi[45]*)
8476
 
+      ;;
8477
 
+    cygwin* | mingw* | pw32*)
8478
 
+      # When not using gcc, we currently assume that we are using
8479
 
+      # Microsoft Visual C++.
8480
 
+      # hardcode_libdir_flag_spec is actually meaningless, as there is
8481
 
+      # no search path for DLLs.
8482
 
+      hardcode_libdir_flag_spec=' '
8483
 
+      libext=lib
8484
 
+      ;;
8485
 
+    darwin* | rhapsody*)
8486
 
+      hardcode_direct=no
8487
 
+      if test "$GCC" = yes ; then
8488
 
+        :
8489
 
+      else
8490
 
+        case $cc_basename in
8491
 
+          xlc*)
8492
 
+            ;;
8493
 
+          *)
8494
 
+            ld_shlibs=no
8495
 
+            ;;
8496
 
+        esac
8497
 
+      fi
8498
 
+      ;;
8499
 
+    dgux*)
8500
 
+      hardcode_libdir_flag_spec='-L$libdir'
8501
 
+      ;;
8502
 
+    freebsd1*)
8503
 
+      ld_shlibs=no
8504
 
+      ;;
8505
 
+    freebsd2.2*)
8506
 
+      hardcode_libdir_flag_spec='-R$libdir'
8507
 
+      hardcode_direct=yes
8508
 
+      ;;
8509
 
+    freebsd2*)
8510
 
+      hardcode_direct=yes
8511
 
+      hardcode_minus_L=yes
8512
 
+      ;;
8513
 
+    freebsd* | dragonfly*)
8514
 
+      hardcode_libdir_flag_spec='-R$libdir'
8515
 
+      hardcode_direct=yes
8516
 
+      ;;
8517
 
+    hpux9*)
8518
 
+      hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
8519
 
+      hardcode_libdir_separator=:
8520
 
+      hardcode_direct=yes
8521
 
+      # hardcode_minus_L: Not really in the search PATH,
8522
 
+      # but as the default location of the library.
8523
 
+      hardcode_minus_L=yes
8524
 
+      ;;
8525
 
+    hpux10*)
8526
 
+      if test "$with_gnu_ld" = no; then
8527
 
+        hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
8528
 
+        hardcode_libdir_separator=:
8529
 
+        hardcode_direct=yes
8530
 
+        # hardcode_minus_L: Not really in the search PATH,
8531
 
+        # but as the default location of the library.
8532
 
+        hardcode_minus_L=yes
8533
 
+      fi
8534
 
+      ;;
8535
 
+    hpux11*)
8536
 
+      if test "$with_gnu_ld" = no; then
8537
 
+        hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
8538
 
+        hardcode_libdir_separator=:
8539
 
+        case $host_cpu in
8540
 
+          hppa*64*|ia64*)
8541
 
+            hardcode_direct=no
8542
 
+            ;;
8543
 
+          *)
8544
 
+            hardcode_direct=yes
8545
 
+            # hardcode_minus_L: Not really in the search PATH,
8546
 
+            # but as the default location of the library.
8547
 
+            hardcode_minus_L=yes
8548
 
+            ;;
8549
 
+        esac
8550
 
+      fi
8551
 
+      ;;
8552
 
+    irix5* | irix6* | nonstopux*)
8553
 
+      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
8554
 
+      hardcode_libdir_separator=:
8555
 
+      ;;
8556
 
+    netbsd*)
8557
 
+      hardcode_libdir_flag_spec='-R$libdir'
8558
 
+      hardcode_direct=yes
8559
 
+      ;;
8560
 
+    newsos6)
8561
 
+      hardcode_direct=yes
8562
 
+      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
8563
 
+      hardcode_libdir_separator=:
8564
 
+      ;;
8565
 
+    openbsd*)
8566
 
+      if test -f /usr/libexec/ld.so; then
8567
 
+        hardcode_direct=yes
8568
 
+        if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
8569
 
+          hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
8570
 
+        else
8571
 
+          case "$host_os" in
8572
 
+            openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
8573
 
+              hardcode_libdir_flag_spec='-R$libdir'
8574
 
+              ;;
8575
 
+            *)
8576
 
+              hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
8577
 
+              ;;
8578
 
+          esac
8579
 
+        fi
8580
 
+      else
8581
 
+        ld_shlibs=no
8582
 
+      fi
8583
 
+      ;;
8584
 
+    os2*)
8585
 
+      hardcode_libdir_flag_spec='-L$libdir'
8586
 
+      hardcode_minus_L=yes
8587
 
+      ;;
8588
 
+    osf3*)
8589
 
+      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
8590
 
+      hardcode_libdir_separator=:
8591
 
+      ;;
8592
 
+    osf4* | osf5*)
8593
 
+      if test "$GCC" = yes; then
8594
 
+        hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
8595
 
+      else
8596
 
+        # Both cc and cxx compiler support -rpath directly
8597
 
+        hardcode_libdir_flag_spec='-rpath $libdir'
8598
 
+      fi
8599
 
+      hardcode_libdir_separator=:
8600
 
+      ;;
8601
 
+    solaris*)
8602
 
+      hardcode_libdir_flag_spec='-R$libdir'
8603
 
+      ;;
8604
 
+    sunos4*)
8605
 
+      hardcode_libdir_flag_spec='-L$libdir'
8606
 
+      hardcode_direct=yes
8607
 
+      hardcode_minus_L=yes
8608
 
+      ;;
8609
 
+    sysv4)
8610
 
+      case $host_vendor in
8611
 
+        sni)
8612
 
+          hardcode_direct=yes # is this really true???
8613
 
+          ;;
8614
 
+        siemens)
8615
 
+          hardcode_direct=no
8616
 
+          ;;
8617
 
+        motorola)
8618
 
+          hardcode_direct=no #Motorola manual says yes, but my tests say they lie
8619
 
+          ;;
8620
 
+      esac
8621
 
+      ;;
8622
 
+    sysv4.3*)
8623
 
+      ;;
8624
 
+    sysv4*MP*)
8625
 
+      if test -d /usr/nec; then
8626
 
+        ld_shlibs=yes
8627
 
+      fi
8628
 
+      ;;
8629
 
+    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
8630
 
+      ;;
8631
 
+    sysv5* | sco3.2v5* | sco5v6*)
8632
 
+      hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`'
8633
 
+      hardcode_libdir_separator=':'
8634
 
+      ;;
8635
 
+    uts4*)
8636
 
+      hardcode_libdir_flag_spec='-L$libdir'
8637
 
+      ;;
8638
 
+    *)
8639
 
+      ld_shlibs=no
8640
 
+      ;;
8641
 
+  esac
8642
 
+fi
8643
 
+
8644
 
+# Check dynamic linker characteristics
8645
 
+# Code taken from libtool.m4's AC_LIBTOOL_SYS_DYNAMIC_LINKER.
8646
 
+# Unlike libtool.m4, here we don't care about _all_ names of the library, but
8647
 
+# only about the one the linker finds when passed -lNAME. This is the last
8648
 
+# element of library_names_spec in libtool.m4, or possibly two of them if the
8649
 
+# linker has special search rules.
8650
 
+library_names_spec=      # the last element of library_names_spec in libtool.m4
8651
 
+libname_spec='lib$name'
8652
 
+case "$host_os" in
8653
 
+  aix3*)
8654
 
+    library_names_spec='$libname.a'
8655
 
+    ;;
8656
 
+  aix4* | aix5*)
8657
 
+    library_names_spec='$libname$shrext'
8658
 
+    ;;
8659
 
+  amigaos*)
8660
 
+    library_names_spec='$libname.a'
8661
 
+    ;;
8662
 
+  beos*)
8663
 
+    library_names_spec='$libname$shrext'
8664
 
+    ;;
8665
 
+  bsdi[45]*)
8666
 
+    library_names_spec='$libname$shrext'
8667
 
+    ;;
8668
 
+  cygwin* | mingw* | pw32*)
8669
 
+    shrext=.dll
8670
 
+    library_names_spec='$libname.dll.a $libname.lib'
8671
 
+    ;;
8672
 
+  darwin* | rhapsody*)
8673
 
+    shrext=.dylib
8674
 
+    library_names_spec='$libname$shrext'
8675
 
+    ;;
8676
 
+  dgux*)
8677
 
+    library_names_spec='$libname$shrext'
8678
 
+    ;;
8679
 
+  freebsd1*)
8680
 
+    ;;
8681
 
+  freebsd* | dragonfly*)
8682
 
+    case "$host_os" in
8683
 
+      freebsd[123]*)
8684
 
+        library_names_spec='$libname$shrext$versuffix' ;;
8685
 
+      *)
8686
 
+        library_names_spec='$libname$shrext' ;;
8687
 
+    esac
8688
 
+    ;;
8689
 
+  gnu*)
8690
 
+    library_names_spec='$libname$shrext'
8691
 
+    ;;
8692
 
+  hpux9* | hpux10* | hpux11*)
8693
 
+    case $host_cpu in
8694
 
+      ia64*)
8695
 
+        shrext=.so
8696
 
+        ;;
8697
 
+      hppa*64*)
8698
 
+        shrext=.sl
8699
 
+        ;;
8700
 
+      *)
8701
 
+        shrext=.sl
8702
 
+        ;;
8703
 
+    esac
8704
 
+    library_names_spec='$libname$shrext'
8705
 
+    ;;
8706
 
+  interix[3-9]*)
8707
 
+    library_names_spec='$libname$shrext'
8708
 
+    ;;
8709
 
+  irix5* | irix6* | nonstopux*)
8710
 
+    library_names_spec='$libname$shrext'
8711
 
+    case "$host_os" in
8712
 
+      irix5* | nonstopux*)
8713
 
+        libsuff= shlibsuff=
8714
 
+        ;;
8715
 
+      *)
8716
 
+        case $LD in
8717
 
+          *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= ;;
8718
 
+          *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 ;;
8719
 
+          *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 ;;
8720
 
+          *) libsuff= shlibsuff= ;;
8721
 
+        esac
8722
 
+        ;;
8723
 
+    esac
8724
 
+    ;;
8725
 
+  linux*oldld* | linux*aout* | linux*coff*)
8726
 
+    ;;
8727
 
+  linux* | k*bsd*-gnu)
8728
 
+    library_names_spec='$libname$shrext'
8729
 
+    ;;
8730
 
+  knetbsd*-gnu)
8731
 
+    library_names_spec='$libname$shrext'
8732
 
+    ;;
8733
 
+  netbsd*)
8734
 
+    library_names_spec='$libname$shrext'
8735
 
+    ;;
8736
 
+  newsos6)
8737
 
+    library_names_spec='$libname$shrext'
8738
 
+    ;;
8739
 
+  nto-qnx*)
8740
 
+    library_names_spec='$libname$shrext'
8741
 
+    ;;
8742
 
+  openbsd*)
8743
 
+    library_names_spec='$libname$shrext$versuffix'
8744
 
+    ;;
8745
 
+  os2*)
8746
 
+    libname_spec='$name'
8747
 
+    shrext=.dll
8748
 
+    library_names_spec='$libname.a'
8749
 
+    ;;
8750
 
+  osf3* | osf4* | osf5*)
8751
 
+    library_names_spec='$libname$shrext'
8752
 
+    ;;
8753
 
+  rdos*)
8754
 
+    ;;
8755
 
+  solaris*)
8756
 
+    library_names_spec='$libname$shrext'
8757
 
+    ;;
8758
 
+  sunos4*)
8759
 
+    library_names_spec='$libname$shrext$versuffix'
8760
 
+    ;;
8761
 
+  sysv4 | sysv4.3*)
8762
 
+    library_names_spec='$libname$shrext'
8763
 
+    ;;
8764
 
+  sysv4*MP*)
8765
 
+    library_names_spec='$libname$shrext'
8766
 
+    ;;
8767
 
+  sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
8768
 
+    library_names_spec='$libname$shrext'
8769
 
+    ;;
8770
 
+  uts4*)
8771
 
+    library_names_spec='$libname$shrext'
8772
 
+    ;;
8773
 
+esac
8774
 
+
8775
 
+sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
8776
 
+escaped_wl=`echo "X$wl" | sed -e 's/^X//' -e "$sed_quote_subst"`
8777
 
+shlibext=`echo "$shrext" | sed -e 's,^\.,,'`
8778
 
+escaped_libname_spec=`echo "X$libname_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
8779
 
+escaped_library_names_spec=`echo "X$library_names_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
8780
 
+escaped_hardcode_libdir_flag_spec=`echo "X$hardcode_libdir_flag_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
8781
 
+
8782
 
+LC_ALL=C sed -e 's/^\([a-zA-Z0-9_]*\)=/acl_cv_\1=/' <<EOF
8783
 
+
8784
 
+# How to pass a linker flag through the compiler.
8785
 
+wl="$escaped_wl"
8786
 
+
8787
 
+# Static library suffix (normally "a").
8788
 
+libext="$libext"
8789
 
+
8790
 
+# Shared library suffix (normally "so").
8791
 
+shlibext="$shlibext"
8792
 
+
8793
 
+# Format of library name prefix.
8794
 
+libname_spec="$escaped_libname_spec"
8795
 
+
8796
 
+# Library names that the linker finds when passed -lNAME.
8797
 
+library_names_spec="$escaped_library_names_spec"
8798
 
+
8799
 
+# Flag to hardcode \$libdir into a binary during linking.
8800
 
+# This must work even if \$libdir does not exist.
8801
 
+hardcode_libdir_flag_spec="$escaped_hardcode_libdir_flag_spec"
8802
 
+
8803
 
+# Whether we need a single -rpath flag with a separated argument.
8804
 
+hardcode_libdir_separator="$hardcode_libdir_separator"
8805
 
+
8806
 
+# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the
8807
 
+# resulting binary.
8808
 
+hardcode_direct="$hardcode_direct"
8809
 
+
8810
 
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
8811
 
+# resulting binary.
8812
 
+hardcode_minus_L="$hardcode_minus_L"
8813
 
+
8814
 
+EOF
8815
 
diff -urN dovecot-1.2.4/dovecot-libsieve/configure.in dovecot-1.2.4.debian/dovecot-libsieve/configure.in
8816
 
--- dovecot-1.2.4/dovecot-libsieve/configure.in 1970-01-01 01:00:00.000000000 +0100
8817
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/configure.in  2009-08-21 00:55:05.000000000 +0200
8818
 
@@ -0,0 +1,128 @@
8819
 
+AC_INIT([Dovecot Sieve], [0.1.12], [dovecot@dovecot.org], [dovecot-1.2-sieve])
8820
 
+AC_CONFIG_SRCDIR([src])
8821
 
+
8822
 
+# Autoheader is not needed and does more harm than good for this package. However, it is 
8823
 
+# tightly integrated in autoconf/automake and therefore it is difficult not to use it. As 
8824
 
+# a workaround we give autoheader a dummy config header to chew on and we handle the 
8825
 
+# real config header ourselves.
8826
 
+AC_CONFIG_HEADERS([dummy-config.h dsieve-config.h])
8827
 
+
8828
 
+AC_DEFINE_UNQUOTED(SIEVE_NAME, "$PACKAGE_NAME", 
8829
 
+       [Define to the full name of this Sieve implementation.])
8830
 
+AC_DEFINE_UNQUOTED(SIEVE_VERSION, "$PACKAGE_VERSION", 
8831
 
+       [Define to the version of this Sieve implementation.])
8832
 
+
8833
 
+AM_INIT_AUTOMAKE([no-define foreign])
8834
 
+
8835
 
+AM_MAINTAINER_MODE
8836
 
+
8837
 
+AC_PROG_CC
8838
 
+AC_PROG_CPP
8839
 
+AC_PROG_LIBTOOL
8840
 
+
8841
 
+AC_ARG_WITH(dovecot,
8842
 
+[AC_HELP_STRING([--with-dovecot=DIR], [Dovecot base directory [../dovecot]])],
8843
 
+       dovecotdir="$withval",
8844
 
+       dovecotdir=../dovecot
8845
 
+)
8846
 
+old=`pwd`
8847
 
+cd $dovecotdir
8848
 
+dovecotdir=`pwd`
8849
 
+cd $old
8850
 
+AC_SUBST(dovecotdir)
8851
 
+
8852
 
+if ! test -f "$dovecotdir/dovecot-config"; then
8853
 
+  echo
8854
 
+  echo "dovecot-config not found from $dovecotdir, use --with-dovecot=PATH"
8855
 
+  echo "to give path to compiled Dovecot sources or to a directory with the"
8856
 
+  echo "installed dovecot-config file."
8857
 
+  AC_MSG_ERROR([dovecot-config not found])
8858
 
+fi
8859
 
+
8860
 
+if test -d "$dovecotdir/src"; then
8861
 
+  # compiling against sources
8862
 
+  have_dovecot_libs=yes
8863
 
+else
8864
 
+  # compiling against installed headers
8865
 
+  echo "WARNING: Cannot build Sieve commandline tools without the compiled"
8866
 
+  echo "         Dovecot sources. Compiling against headers will only build"
8867
 
+  echo "         the Sieve plugin." 
8868
 
+  have_dovecot_libs=no
8869
 
+fi
8870
 
+AM_CONDITIONAL(HAVE_DOVECOT_LIBS, test "$have_dovecot_libs" = "yes")
8871
 
+
8872
 
+# Extensions under development
8873
 
+#
8874
 
+
8875
 
+AC_ARG_WITH(unfinished-features,
8876
 
+[AC_HELP_STRING([--with-unfinished-features], 
8877
 
+       [Build unfinished new features/extensions [default=no]])],
8878
 
+        if test x$withval = xno || test x$withval = xauto; then
8879
 
+                want_unfinished_features=$withval
8880
 
+        else
8881
 
+                want_unfinished_features=yes
8882
 
+        fi,
8883
 
+        want_unfinished_features=no)
8884
 
+AM_CONDITIONAL(BUILD_UNFINISHED, test "$want_unfinished_features" = "yes")
8885
 
+
8886
 
+if test "$want_unfinished_features" = "yes"; then
8887
 
+       AC_DEFINE(HAVE_SIEVE_UNFINISHED,,
8888
 
+               [Define to build Sieve unfinished features/extensions.])
8889
 
+fi
8890
 
+
8891
 
+#
8892
 
+#
8893
 
+
8894
 
+AC_ARG_ENABLE(valgrind,
8895
 
+[AC_HELP_STRING([--enable-valgrind], [Enable Valgrind memory leak checks in testsuite [default=no]])],
8896
 
+    if test x$enableval = xno || test x$enableval = xauto; then
8897
 
+        want_valgrind=$enableval
8898
 
+    else
8899
 
+        want_valgrind=yes
8900
 
+    fi,
8901
 
+    want_valgrind=no)
8902
 
+AM_CONDITIONAL(TESTSUITE_VALGRIND, test "$want_valgrind" = "yes")
8903
 
+
8904
 
+dnl replace relative ../ paths in the file with full paths
8905
 
+eval `cat $dovecotdir/dovecot-config|sed 's,\$(top_builddir)/,$dovecotdir/,g'`
8906
 
+
8907
 
+if test $have_dovecot_libs = yes; then
8908
 
+  dovecot_incdir="$dovecotdir"
8909
 
+fi
8910
 
+
8911
 
+AC_SUBST(STORAGE_LIBS)
8912
 
+AC_SUBST(LIBICONV)
8913
 
+AC_SUBST(RAND_LIBS)
8914
 
+AC_SUBST(MODULE_LIBS)
8915
 
+AC_SUBST(dovecot_incdir)
8916
 
+AC_SUBST(moduledir)
8917
 
+
8918
 
+AC_CONFIG_FILES([
8919
 
+Makefile
8920
 
+src/Makefile
8921
 
+src/lib-sieve/Makefile
8922
 
+src/lib-sieve/plugins/Makefile
8923
 
+src/lib-sieve/plugins/vacation/Makefile
8924
 
+src/lib-sieve/plugins/subaddress/Makefile
8925
 
+src/lib-sieve/plugins/comparator-i-ascii-numeric/Makefile
8926
 
+src/lib-sieve/plugins/relational/Makefile
8927
 
+src/lib-sieve/plugins/regex/Makefile
8928
 
+src/lib-sieve/plugins/imap4flags/Makefile
8929
 
+src/lib-sieve/plugins/copy/Makefile
8930
 
+src/lib-sieve/plugins/include/Makefile
8931
 
+src/lib-sieve/plugins/body/Makefile
8932
 
+src/lib-sieve/plugins/variables/Makefile
8933
 
+src/lib-sieve/plugins/enotify/Makefile
8934
 
+src/lib-sieve/plugins/notify/Makefile
8935
 
+src/lib-sieve/plugins/environment/Makefile
8936
 
+src/lib-sieve/plugins/mailbox/Makefile
8937
 
+src/lib-sieve/plugins/date/Makefile
8938
 
+src/lib-sieve-tool/Makefile
8939
 
+src/plugins/Makefile
8940
 
+src/plugins/lda-sieve/Makefile
8941
 
+src/sieve-tools/Makefile
8942
 
+src/sieve-tools/debug/Makefile
8943
 
+src/testsuite/Makefile
8944
 
+stamp.h])
8945
 
+
8946
 
+AC_OUTPUT
8947
 
diff -urN dovecot-1.2.4/dovecot-libsieve/COPYING dovecot-1.2.4.debian/dovecot-libsieve/COPYING
8948
 
--- dovecot-1.2.4/dovecot-libsieve/COPYING      1970-01-01 01:00:00.000000000 +0100
8949
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/COPYING       2008-07-18 12:11:28.000000000 +0200
8950
 
@@ -0,0 +1,4 @@
8951
 
+See AUTHORS file for list of copyright holders.
8952
 
+
8953
 
+Everything is licenced under LGPLv2.1 (see COPYING.LGPL) unless otherwise 
8954
 
+mentioned at the beginning of the file.
8955
 
diff -urN dovecot-1.2.4/dovecot-libsieve/COPYING.LGPL dovecot-1.2.4.debian/dovecot-libsieve/COPYING.LGPL
8956
 
--- dovecot-1.2.4/dovecot-libsieve/COPYING.LGPL 1970-01-01 01:00:00.000000000 +0100
8957
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/COPYING.LGPL  2008-07-18 12:11:28.000000000 +0200
8958
 
@@ -0,0 +1,510 @@
8959
 
+
8960
 
+                  GNU LESSER GENERAL PUBLIC LICENSE
8961
 
+                       Version 2.1, February 1999
8962
 
+
8963
 
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
8964
 
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
8965
 
+ Everyone is permitted to copy and distribute verbatim copies
8966
 
+ of this license document, but changing it is not allowed.
8967
 
+
8968
 
+[This is the first released version of the Lesser GPL.  It also counts
8969
 
+ as the successor of the GNU Library Public License, version 2, hence
8970
 
+ the version number 2.1.]
8971
 
+
8972
 
+                            Preamble
8973
 
+
8974
 
+  The licenses for most software are designed to take away your
8975
 
+freedom to share and change it.  By contrast, the GNU General Public
8976
 
+Licenses are intended to guarantee your freedom to share and change
8977
 
+free software--to make sure the software is free for all its users.
8978
 
+
8979
 
+  This license, the Lesser General Public License, applies to some
8980
 
+specially designated software packages--typically libraries--of the
8981
 
+Free Software Foundation and other authors who decide to use it.  You
8982
 
+can use it too, but we suggest you first think carefully about whether
8983
 
+this license or the ordinary General Public License is the better
8984
 
+strategy to use in any particular case, based on the explanations
8985
 
+below.
8986
 
+
8987
 
+  When we speak of free software, we are referring to freedom of use,
8988
 
+not price.  Our General Public Licenses are designed to make sure that
8989
 
+you have the freedom to distribute copies of free software (and charge
8990
 
+for this service if you wish); that you receive source code or can get
8991
 
+it if you want it; that you can change the software and use pieces of
8992
 
+it in new free programs; and that you are informed that you can do
8993
 
+these things.
8994
 
+
8995
 
+  To protect your rights, we need to make restrictions that forbid
8996
 
+distributors to deny you these rights or to ask you to surrender these
8997
 
+rights.  These restrictions translate to certain responsibilities for
8998
 
+you if you distribute copies of the library or if you modify it.
8999
 
+
9000
 
+  For example, if you distribute copies of the library, whether gratis
9001
 
+or for a fee, you must give the recipients all the rights that we gave
9002
 
+you.  You must make sure that they, too, receive or can get the source
9003
 
+code.  If you link other code with the library, you must provide
9004
 
+complete object files to the recipients, so that they can relink them
9005
 
+with the library after making changes to the library and recompiling
9006
 
+it.  And you must show them these terms so they know their rights.
9007
 
+
9008
 
+  We protect your rights with a two-step method: (1) we copyright the
9009
 
+library, and (2) we offer you this license, which gives you legal
9010
 
+permission to copy, distribute and/or modify the library.
9011
 
+
9012
 
+  To protect each distributor, we want to make it very clear that
9013
 
+there is no warranty for the free library.  Also, if the library is
9014
 
+modified by someone else and passed on, the recipients should know
9015
 
+that what they have is not the original version, so that the original
9016
 
+author's reputation will not be affected by problems that might be
9017
 
+introduced by others.
9018
 
+^L
9019
 
+  Finally, software patents pose a constant threat to the existence of
9020
 
+any free program.  We wish to make sure that a company cannot
9021
 
+effectively restrict the users of a free program by obtaining a
9022
 
+restrictive license from a patent holder.  Therefore, we insist that
9023
 
+any patent license obtained for a version of the library must be
9024
 
+consistent with the full freedom of use specified in this license.
9025
 
+
9026
 
+  Most GNU software, including some libraries, is covered by the
9027
 
+ordinary GNU General Public License.  This license, the GNU Lesser
9028
 
+General Public License, applies to certain designated libraries, and
9029
 
+is quite different from the ordinary General Public License.  We use
9030
 
+this license for certain libraries in order to permit linking those
9031
 
+libraries into non-free programs.
9032
 
+
9033
 
+  When a program is linked with a library, whether statically or using
9034
 
+a shared library, the combination of the two is legally speaking a
9035
 
+combined work, a derivative of the original library.  The ordinary
9036
 
+General Public License therefore permits such linking only if the
9037
 
+entire combination fits its criteria of freedom.  The Lesser General
9038
 
+Public License permits more lax criteria for linking other code with
9039
 
+the library.
9040
 
+
9041
 
+  We call this license the "Lesser" General Public License because it
9042
 
+does Less to protect the user's freedom than the ordinary General
9043
 
+Public License.  It also provides other free software developers Less
9044
 
+of an advantage over competing non-free programs.  These disadvantages
9045
 
+are the reason we use the ordinary General Public License for many
9046
 
+libraries.  However, the Lesser license provides advantages in certain
9047
 
+special circumstances.
9048
 
+
9049
 
+  For example, on rare occasions, there may be a special need to
9050
 
+encourage the widest possible use of a certain library, so that it
9051
 
+becomes a de-facto standard.  To achieve this, non-free programs must
9052
 
+be allowed to use the library.  A more frequent case is that a free
9053
 
+library does the same job as widely used non-free libraries.  In this
9054
 
+case, there is little to gain by limiting the free library to free
9055
 
+software only, so we use the Lesser General Public License.
9056
 
+
9057
 
+  In other cases, permission to use a particular library in non-free
9058
 
+programs enables a greater number of people to use a large body of
9059
 
+free software.  For example, permission to use the GNU C Library in
9060
 
+non-free programs enables many more people to use the whole GNU
9061
 
+operating system, as well as its variant, the GNU/Linux operating
9062
 
+system.
9063
 
+
9064
 
+  Although the Lesser General Public License is Less protective of the
9065
 
+users' freedom, it does ensure that the user of a program that is
9066
 
+linked with the Library has the freedom and the wherewithal to run
9067
 
+that program using a modified version of the Library.
9068
 
+
9069
 
+  The precise terms and conditions for copying, distribution and
9070
 
+modification follow.  Pay close attention to the difference between a
9071
 
+"work based on the library" and a "work that uses the library".  The
9072
 
+former contains code derived from the library, whereas the latter must
9073
 
+be combined with the library in order to run.
9074
 
+^L
9075
 
+                  GNU LESSER GENERAL PUBLIC LICENSE
9076
 
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
9077
 
+
9078
 
+  0. This License Agreement applies to any software library or other
9079
 
+program which contains a notice placed by the copyright holder or
9080
 
+other authorized party saying it may be distributed under the terms of
9081
 
+this Lesser General Public License (also called "this License").
9082
 
+Each licensee is addressed as "you".
9083
 
+
9084
 
+  A "library" means a collection of software functions and/or data
9085
 
+prepared so as to be conveniently linked with application programs
9086
 
+(which use some of those functions and data) to form executables.
9087
 
+
9088
 
+  The "Library", below, refers to any such software library or work
9089
 
+which has been distributed under these terms.  A "work based on the
9090
 
+Library" means either the Library or any derivative work under
9091
 
+copyright law: that is to say, a work containing the Library or a
9092
 
+portion of it, either verbatim or with modifications and/or translated
9093
 
+straightforwardly into another language.  (Hereinafter, translation is
9094
 
+included without limitation in the term "modification".)
9095
 
+
9096
 
+  "Source code" for a work means the preferred form of the work for
9097
 
+making modifications to it.  For a library, complete source code means
9098
 
+all the source code for all modules it contains, plus any associated
9099
 
+interface definition files, plus the scripts used to control
9100
 
+compilation and installation of the library.
9101
 
+
9102
 
+  Activities other than copying, distribution and modification are not
9103
 
+covered by this License; they are outside its scope.  The act of
9104
 
+running a program using the Library is not restricted, and output from
9105
 
+such a program is covered only if its contents constitute a work based
9106
 
+on the Library (independent of the use of the Library in a tool for
9107
 
+writing it).  Whether that is true depends on what the Library does
9108
 
+and what the program that uses the Library does.
9109
 
+
9110
 
+  1. You may copy and distribute verbatim copies of the Library's
9111
 
+complete source code as you receive it, in any medium, provided that
9112
 
+you conspicuously and appropriately publish on each copy an
9113
 
+appropriate copyright notice and disclaimer of warranty; keep intact
9114
 
+all the notices that refer to this License and to the absence of any
9115
 
+warranty; and distribute a copy of this License along with the
9116
 
+Library.
9117
 
+
9118
 
+  You may charge a fee for the physical act of transferring a copy,
9119
 
+and you may at your option offer warranty protection in exchange for a
9120
 
+fee.
9121
 
+
9122
 
+  2. You may modify your copy or copies of the Library or any portion
9123
 
+of it, thus forming a work based on the Library, and copy and
9124
 
+distribute such modifications or work under the terms of Section 1
9125
 
+above, provided that you also meet all of these conditions:
9126
 
+
9127
 
+    a) The modified work must itself be a software library.
9128
 
+
9129
 
+    b) You must cause the files modified to carry prominent notices
9130
 
+    stating that you changed the files and the date of any change.
9131
 
+
9132
 
+    c) You must cause the whole of the work to be licensed at no
9133
 
+    charge to all third parties under the terms of this License.
9134
 
+
9135
 
+    d) If a facility in the modified Library refers to a function or a
9136
 
+    table of data to be supplied by an application program that uses
9137
 
+    the facility, other than as an argument passed when the facility
9138
 
+    is invoked, then you must make a good faith effort to ensure that,
9139
 
+    in the event an application does not supply such function or
9140
 
+    table, the facility still operates, and performs whatever part of
9141
 
+    its purpose remains meaningful.
9142
 
+
9143
 
+    (For example, a function in a library to compute square roots has
9144
 
+    a purpose that is entirely well-defined independent of the
9145
 
+    application.  Therefore, Subsection 2d requires that any
9146
 
+    application-supplied function or table used by this function must
9147
 
+    be optional: if the application does not supply it, the square
9148
 
+    root function must still compute square roots.)
9149
 
+
9150
 
+These requirements apply to the modified work as a whole.  If
9151
 
+identifiable sections of that work are not derived from the Library,
9152
 
+and can be reasonably considered independent and separate works in
9153
 
+themselves, then this License, and its terms, do not apply to those
9154
 
+sections when you distribute them as separate works.  But when you
9155
 
+distribute the same sections as part of a whole which is a work based
9156
 
+on the Library, the distribution of the whole must be on the terms of
9157
 
+this License, whose permissions for other licensees extend to the
9158
 
+entire whole, and thus to each and every part regardless of who wrote
9159
 
+it.
9160
 
+
9161
 
+Thus, it is not the intent of this section to claim rights or contest
9162
 
+your rights to work written entirely by you; rather, the intent is to
9163
 
+exercise the right to control the distribution of derivative or
9164
 
+collective works based on the Library.
9165
 
+
9166
 
+In addition, mere aggregation of another work not based on the Library
9167
 
+with the Library (or with a work based on the Library) on a volume of
9168
 
+a storage or distribution medium does not bring the other work under
9169
 
+the scope of this License.
9170
 
+
9171
 
+  3. You may opt to apply the terms of the ordinary GNU General Public
9172
 
+License instead of this License to a given copy of the Library.  To do
9173
 
+this, you must alter all the notices that refer to this License, so
9174
 
+that they refer to the ordinary GNU General Public License, version 2,
9175
 
+instead of to this License.  (If a newer version than version 2 of the
9176
 
+ordinary GNU General Public License has appeared, then you can specify
9177
 
+that version instead if you wish.)  Do not make any other change in
9178
 
+these notices.
9179
 
+^L
9180
 
+  Once this change is made in a given copy, it is irreversible for
9181
 
+that copy, so the ordinary GNU General Public License applies to all
9182
 
+subsequent copies and derivative works made from that copy.
9183
 
+
9184
 
+  This option is useful when you wish to copy part of the code of
9185
 
+the Library into a program that is not a library.
9186
 
+
9187
 
+  4. You may copy and distribute the Library (or a portion or
9188
 
+derivative of it, under Section 2) in object code or executable form
9189
 
+under the terms of Sections 1 and 2 above provided that you accompany
9190
 
+it with the complete corresponding machine-readable source code, which
9191
 
+must be distributed under the terms of Sections 1 and 2 above on a
9192
 
+medium customarily used for software interchange.
9193
 
+
9194
 
+  If distribution of object code is made by offering access to copy
9195
 
+from a designated place, then offering equivalent access to copy the
9196
 
+source code from the same place satisfies the requirement to
9197
 
+distribute the source code, even though third parties are not
9198
 
+compelled to copy the source along with the object code.
9199
 
+
9200
 
+  5. A program that contains no derivative of any portion of the
9201
 
+Library, but is designed to work with the Library by being compiled or
9202
 
+linked with it, is called a "work that uses the Library".  Such a
9203
 
+work, in isolation, is not a derivative work of the Library, and
9204
 
+therefore falls outside the scope of this License.
9205
 
+
9206
 
+  However, linking a "work that uses the Library" with the Library
9207
 
+creates an executable that is a derivative of the Library (because it
9208
 
+contains portions of the Library), rather than a "work that uses the
9209
 
+library".  The executable is therefore covered by this License.
9210
 
+Section 6 states terms for distribution of such executables.
9211
 
+
9212
 
+  When a "work that uses the Library" uses material from a header file
9213
 
+that is part of the Library, the object code for the work may be a
9214
 
+derivative work of the Library even though the source code is not.
9215
 
+Whether this is true is especially significant if the work can be
9216
 
+linked without the Library, or if the work is itself a library.  The
9217
 
+threshold for this to be true is not precisely defined by law.
9218
 
+
9219
 
+  If such an object file uses only numerical parameters, data
9220
 
+structure layouts and accessors, and small macros and small inline
9221
 
+functions (ten lines or less in length), then the use of the object
9222
 
+file is unrestricted, regardless of whether it is legally a derivative
9223
 
+work.  (Executables containing this object code plus portions of the
9224
 
+Library will still fall under Section 6.)
9225
 
+
9226
 
+  Otherwise, if the work is a derivative of the Library, you may
9227
 
+distribute the object code for the work under the terms of Section 6.
9228
 
+Any executables containing that work also fall under Section 6,
9229
 
+whether or not they are linked directly with the Library itself.
9230
 
+^L
9231
 
+  6. As an exception to the Sections above, you may also combine or
9232
 
+link a "work that uses the Library" with the Library to produce a
9233
 
+work containing portions of the Library, and distribute that work
9234
 
+under terms of your choice, provided that the terms permit
9235
 
+modification of the work for the customer's own use and reverse
9236
 
+engineering for debugging such modifications.
9237
 
+
9238
 
+  You must give prominent notice with each copy of the work that the
9239
 
+Library is used in it and that the Library and its use are covered by
9240
 
+this License.  You must supply a copy of this License.  If the work
9241
 
+during execution displays copyright notices, you must include the
9242
 
+copyright notice for the Library among them, as well as a reference
9243
 
+directing the user to the copy of this License.  Also, you must do one
9244
 
+of these things:
9245
 
+
9246
 
+    a) Accompany the work with the complete corresponding
9247
 
+    machine-readable source code for the Library including whatever
9248
 
+    changes were used in the work (which must be distributed under
9249
 
+    Sections 1 and 2 above); and, if the work is an executable linked
9250
 
+    with the Library, with the complete machine-readable "work that
9251
 
+    uses the Library", as object code and/or source code, so that the
9252
 
+    user can modify the Library and then relink to produce a modified
9253
 
+    executable containing the modified Library.  (It is understood
9254
 
+    that the user who changes the contents of definitions files in the
9255
 
+    Library will not necessarily be able to recompile the application
9256
 
+    to use the modified definitions.)
9257
 
+
9258
 
+    b) Use a suitable shared library mechanism for linking with the
9259
 
+    Library.  A suitable mechanism is one that (1) uses at run time a
9260
 
+    copy of the library already present on the user's computer system,
9261
 
+    rather than copying library functions into the executable, and (2)
9262
 
+    will operate properly with a modified version of the library, if
9263
 
+    the user installs one, as long as the modified version is
9264
 
+    interface-compatible with the version that the work was made with.
9265
 
+
9266
 
+    c) Accompany the work with a written offer, valid for at least
9267
 
+    three years, to give the same user the materials specified in
9268
 
+    Subsection 6a, above, for a charge no more than the cost of
9269
 
+    performing this distribution.
9270
 
+
9271
 
+    d) If distribution of the work is made by offering access to copy
9272
 
+    from a designated place, offer equivalent access to copy the above
9273
 
+    specified materials from the same place.
9274
 
+
9275
 
+    e) Verify that the user has already received a copy of these
9276
 
+    materials or that you have already sent this user a copy.
9277
 
+
9278
 
+  For an executable, the required form of the "work that uses the
9279
 
+Library" must include any data and utility programs needed for
9280
 
+reproducing the executable from it.  However, as a special exception,
9281
 
+the materials to be distributed need not include anything that is
9282
 
+normally distributed (in either source or binary form) with the major
9283
 
+components (compiler, kernel, and so on) of the operating system on
9284
 
+which the executable runs, unless that component itself accompanies
9285
 
+the executable.
9286
 
+
9287
 
+  It may happen that this requirement contradicts the license
9288
 
+restrictions of other proprietary libraries that do not normally
9289
 
+accompany the operating system.  Such a contradiction means you cannot
9290
 
+use both them and the Library together in an executable that you
9291
 
+distribute.
9292
 
+^L
9293
 
+  7. You may place library facilities that are a work based on the
9294
 
+Library side-by-side in a single library together with other library
9295
 
+facilities not covered by this License, and distribute such a combined
9296
 
+library, provided that the separate distribution of the work based on
9297
 
+the Library and of the other library facilities is otherwise
9298
 
+permitted, and provided that you do these two things:
9299
 
+
9300
 
+    a) Accompany the combined library with a copy of the same work
9301
 
+    based on the Library, uncombined with any other library
9302
 
+    facilities.  This must be distributed under the terms of the
9303
 
+    Sections above.
9304
 
+
9305
 
+    b) Give prominent notice with the combined library of the fact
9306
 
+    that part of it is a work based on the Library, and explaining
9307
 
+    where to find the accompanying uncombined form of the same work.
9308
 
+
9309
 
+  8. You may not copy, modify, sublicense, link with, or distribute
9310
 
+the Library except as expressly provided under this License.  Any
9311
 
+attempt otherwise to copy, modify, sublicense, link with, or
9312
 
+distribute the Library is void, and will automatically terminate your
9313
 
+rights under this License.  However, parties who have received copies,
9314
 
+or rights, from you under this License will not have their licenses
9315
 
+terminated so long as such parties remain in full compliance.
9316
 
+
9317
 
+  9. You are not required to accept this License, since you have not
9318
 
+signed it.  However, nothing else grants you permission to modify or
9319
 
+distribute the Library or its derivative works.  These actions are
9320
 
+prohibited by law if you do not accept this License.  Therefore, by
9321
 
+modifying or distributing the Library (or any work based on the
9322
 
+Library), you indicate your acceptance of this License to do so, and
9323
 
+all its terms and conditions for copying, distributing or modifying
9324
 
+the Library or works based on it.
9325
 
+
9326
 
+  10. Each time you redistribute the Library (or any work based on the
9327
 
+Library), the recipient automatically receives a license from the
9328
 
+original licensor to copy, distribute, link with or modify the Library
9329
 
+subject to these terms and conditions.  You may not impose any further
9330
 
+restrictions on the recipients' exercise of the rights granted herein.
9331
 
+You are not responsible for enforcing compliance by third parties with
9332
 
+this License.
9333
 
+^L
9334
 
+  11. If, as a consequence of a court judgment or allegation of patent
9335
 
+infringement or for any other reason (not limited to patent issues),
9336
 
+conditions are imposed on you (whether by court order, agreement or
9337
 
+otherwise) that contradict the conditions of this License, they do not
9338
 
+excuse you from the conditions of this License.  If you cannot
9339
 
+distribute so as to satisfy simultaneously your obligations under this
9340
 
+License and any other pertinent obligations, then as a consequence you
9341
 
+may not distribute the Library at all.  For example, if a patent
9342
 
+license would not permit royalty-free redistribution of the Library by
9343
 
+all those who receive copies directly or indirectly through you, then
9344
 
+the only way you could satisfy both it and this License would be to
9345
 
+refrain entirely from distribution of the Library.
9346
 
+
9347
 
+If any portion of this section is held invalid or unenforceable under
9348
 
+any particular circumstance, the balance of the section is intended to
9349
 
+apply, and the section as a whole is intended to apply in other
9350
 
+circumstances.
9351
 
+
9352
 
+It is not the purpose of this section to induce you to infringe any
9353
 
+patents or other property right claims or to contest validity of any
9354
 
+such claims; this section has the sole purpose of protecting the
9355
 
+integrity of the free software distribution system which is
9356
 
+implemented by public license practices.  Many people have made
9357
 
+generous contributions to the wide range of software distributed
9358
 
+through that system in reliance on consistent application of that
9359
 
+system; it is up to the author/donor to decide if he or she is willing
9360
 
+to distribute software through any other system and a licensee cannot
9361
 
+impose that choice.
9362
 
+
9363
 
+This section is intended to make thoroughly clear what is believed to
9364
 
+be a consequence of the rest of this License.
9365
 
+
9366
 
+  12. If the distribution and/or use of the Library is restricted in
9367
 
+certain countries either by patents or by copyrighted interfaces, the
9368
 
+original copyright holder who places the Library under this License
9369
 
+may add an explicit geographical distribution limitation excluding those
9370
 
+countries, so that distribution is permitted only in or among
9371
 
+countries not thus excluded.  In such case, this License incorporates
9372
 
+the limitation as if written in the body of this License.
9373
 
+
9374
 
+  13. The Free Software Foundation may publish revised and/or new
9375
 
+versions of the Lesser General Public License from time to time.
9376
 
+Such new versions will be similar in spirit to the present version,
9377
 
+but may differ in detail to address new problems or concerns.
9378
 
+
9379
 
+Each version is given a distinguishing version number.  If the Library
9380
 
+specifies a version number of this License which applies to it and
9381
 
+"any later version", you have the option of following the terms and
9382
 
+conditions either of that version or of any later version published by
9383
 
+the Free Software Foundation.  If the Library does not specify a
9384
 
+license version number, you may choose any version ever published by
9385
 
+the Free Software Foundation.
9386
 
+^L
9387
 
+  14. If you wish to incorporate parts of the Library into other free
9388
 
+programs whose distribution conditions are incompatible with these,
9389
 
+write to the author to ask for permission.  For software which is
9390
 
+copyrighted by the Free Software Foundation, write to the Free
9391
 
+Software Foundation; we sometimes make exceptions for this.  Our
9392
 
+decision will be guided by the two goals of preserving the free status
9393
 
+of all derivatives of our free software and of promoting the sharing
9394
 
+and reuse of software generally.
9395
 
+
9396
 
+                            NO WARRANTY
9397
 
+
9398
 
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
9399
 
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
9400
 
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
9401
 
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
9402
 
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
9403
 
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
9404
 
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
9405
 
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
9406
 
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
9407
 
+
9408
 
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
9409
 
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
9410
 
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
9411
 
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
9412
 
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
9413
 
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
9414
 
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
9415
 
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
9416
 
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
9417
 
+DAMAGES.
9418
 
+
9419
 
+                     END OF TERMS AND CONDITIONS
9420
 
+^L
9421
 
+           How to Apply These Terms to Your New Libraries
9422
 
+
9423
 
+  If you develop a new library, and you want it to be of the greatest
9424
 
+possible use to the public, we recommend making it free software that
9425
 
+everyone can redistribute and change.  You can do so by permitting
9426
 
+redistribution under these terms (or, alternatively, under the terms
9427
 
+of the ordinary General Public License).
9428
 
+
9429
 
+  To apply these terms, attach the following notices to the library.
9430
 
+It is safest to attach them to the start of each source file to most
9431
 
+effectively convey the exclusion of warranty; and each file should
9432
 
+have at least the "copyright" line and a pointer to where the full
9433
 
+notice is found.
9434
 
+
9435
 
+
9436
 
+    <one line to give the library's name and a brief idea of what it does.>
9437
 
+    Copyright (C) <year>  <name of author>
9438
 
+
9439
 
+    This library is free software; you can redistribute it and/or
9440
 
+    modify it under the terms of the GNU Lesser General Public
9441
 
+    License as published by the Free Software Foundation; either
9442
 
+    version 2.1 of the License, or (at your option) any later version.
9443
 
+
9444
 
+    This library is distributed in the hope that it will be useful,
9445
 
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
9446
 
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
9447
 
+    Lesser General Public License for more details.
9448
 
+
9449
 
+    You should have received a copy of the GNU Lesser General Public
9450
 
+    License along with this library; if not, write to the Free Software
9451
 
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
9452
 
+
9453
 
+Also add information on how to contact you by electronic and paper mail.
9454
 
+
9455
 
+You should also get your employer (if you work as a programmer) or
9456
 
+your school, if any, to sign a "copyright disclaimer" for the library,
9457
 
+if necessary.  Here is a sample; alter the names:
9458
 
+
9459
 
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
9460
 
+  library `Frob' (a library for tweaking knobs) written by James
9461
 
+  Random Hacker.
9462
 
+
9463
 
+  <signature of Ty Coon>, 1 April 1990
9464
 
+  Ty Coon, President of Vice
9465
 
+
9466
 
+That's all there is to it!
9467
 
+
9468
 
+
9469
 
diff -urN dovecot-1.2.4/dovecot-libsieve/depcomp dovecot-1.2.4.debian/dovecot-libsieve/depcomp
9470
 
--- dovecot-1.2.4/dovecot-libsieve/depcomp      1970-01-01 01:00:00.000000000 +0100
9471
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/depcomp       2008-07-18 12:31:10.000000000 +0200
9472
 
@@ -0,0 +1,589 @@
9473
 
+#! /bin/sh
9474
 
+# depcomp - compile a program generating dependencies as side-effects
9475
 
+
9476
 
+scriptversion=2007-03-29.01
9477
 
+
9478
 
+# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007 Free Software
9479
 
+# Foundation, Inc.
9480
 
+
9481
 
+# This program is free software; you can redistribute it and/or modify
9482
 
+# it under the terms of the GNU General Public License as published by
9483
 
+# the Free Software Foundation; either version 2, or (at your option)
9484
 
+# any later version.
9485
 
+
9486
 
+# This program is distributed in the hope that it will be useful,
9487
 
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
9488
 
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9489
 
+# GNU General Public License for more details.
9490
 
+
9491
 
+# You should have received a copy of the GNU General Public License
9492
 
+# along with this program; if not, write to the Free Software
9493
 
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
9494
 
+# 02110-1301, USA.
9495
 
+
9496
 
+# As a special exception to the GNU General Public License, if you
9497
 
+# distribute this file as part of a program that contains a
9498
 
+# configuration script generated by Autoconf, you may include it under
9499
 
+# the same distribution terms that you use for the rest of that program.
9500
 
+
9501
 
+# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
9502
 
+
9503
 
+case $1 in
9504
 
+  '')
9505
 
+     echo "$0: No command.  Try \`$0 --help' for more information." 1>&2
9506
 
+     exit 1;
9507
 
+     ;;
9508
 
+  -h | --h*)
9509
 
+    cat <<\EOF
9510
 
+Usage: depcomp [--help] [--version] PROGRAM [ARGS]
9511
 
+
9512
 
+Run PROGRAMS ARGS to compile a file, generating dependencies
9513
 
+as side-effects.
9514
 
+
9515
 
+Environment variables:
9516
 
+  depmode     Dependency tracking mode.
9517
 
+  source      Source file read by `PROGRAMS ARGS'.
9518
 
+  object      Object file output by `PROGRAMS ARGS'.
9519
 
+  DEPDIR      directory where to store dependencies.
9520
 
+  depfile     Dependency file to output.
9521
 
+  tmpdepfile  Temporary file to use when outputing dependencies.
9522
 
+  libtool     Whether libtool is used (yes/no).
9523
 
+
9524
 
+Report bugs to <bug-automake@gnu.org>.
9525
 
+EOF
9526
 
+    exit $?
9527
 
+    ;;
9528
 
+  -v | --v*)
9529
 
+    echo "depcomp $scriptversion"
9530
 
+    exit $?
9531
 
+    ;;
9532
 
+esac
9533
 
+
9534
 
+if test -z "$depmode" || test -z "$source" || test -z "$object"; then
9535
 
+  echo "depcomp: Variables source, object and depmode must be set" 1>&2
9536
 
+  exit 1
9537
 
+fi
9538
 
+
9539
 
+# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
9540
 
+depfile=${depfile-`echo "$object" |
9541
 
+  sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
9542
 
+tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
9543
 
+
9544
 
+rm -f "$tmpdepfile"
9545
 
+
9546
 
+# Some modes work just like other modes, but use different flags.  We
9547
 
+# parameterize here, but still list the modes in the big case below,
9548
 
+# to make depend.m4 easier to write.  Note that we *cannot* use a case
9549
 
+# here, because this file can only contain one case statement.
9550
 
+if test "$depmode" = hp; then
9551
 
+  # HP compiler uses -M and no extra arg.
9552
 
+  gccflag=-M
9553
 
+  depmode=gcc
9554
 
+fi
9555
 
+
9556
 
+if test "$depmode" = dashXmstdout; then
9557
 
+   # This is just like dashmstdout with a different argument.
9558
 
+   dashmflag=-xM
9559
 
+   depmode=dashmstdout
9560
 
+fi
9561
 
+
9562
 
+case "$depmode" in
9563
 
+gcc3)
9564
 
+## gcc 3 implements dependency tracking that does exactly what
9565
 
+## we want.  Yay!  Note: for some reason libtool 1.4 doesn't like
9566
 
+## it if -MD -MP comes after the -MF stuff.  Hmm.
9567
 
+## Unfortunately, FreeBSD c89 acceptance of flags depends upon
9568
 
+## the command line argument order; so add the flags where they
9569
 
+## appear in depend2.am.  Note that the slowdown incurred here
9570
 
+## affects only configure: in makefiles, %FASTDEP% shortcuts this.
9571
 
+  for arg
9572
 
+  do
9573
 
+    case $arg in
9574
 
+    -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
9575
 
+    *)  set fnord "$@" "$arg" ;;
9576
 
+    esac
9577
 
+    shift # fnord
9578
 
+    shift # $arg
9579
 
+  done
9580
 
+  "$@"
9581
 
+  stat=$?
9582
 
+  if test $stat -eq 0; then :
9583
 
+  else
9584
 
+    rm -f "$tmpdepfile"
9585
 
+    exit $stat
9586
 
+  fi
9587
 
+  mv "$tmpdepfile" "$depfile"
9588
 
+  ;;
9589
 
+
9590
 
+gcc)
9591
 
+## There are various ways to get dependency output from gcc.  Here's
9592
 
+## why we pick this rather obscure method:
9593
 
+## - Don't want to use -MD because we'd like the dependencies to end
9594
 
+##   up in a subdir.  Having to rename by hand is ugly.
9595
 
+##   (We might end up doing this anyway to support other compilers.)
9596
 
+## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
9597
 
+##   -MM, not -M (despite what the docs say).
9598
 
+## - Using -M directly means running the compiler twice (even worse
9599
 
+##   than renaming).
9600
 
+  if test -z "$gccflag"; then
9601
 
+    gccflag=-MD,
9602
 
+  fi
9603
 
+  "$@" -Wp,"$gccflag$tmpdepfile"
9604
 
+  stat=$?
9605
 
+  if test $stat -eq 0; then :
9606
 
+  else
9607
 
+    rm -f "$tmpdepfile"
9608
 
+    exit $stat
9609
 
+  fi
9610
 
+  rm -f "$depfile"
9611
 
+  echo "$object : \\" > "$depfile"
9612
 
+  alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
9613
 
+## The second -e expression handles DOS-style file names with drive letters.
9614
 
+  sed -e 's/^[^:]*: / /' \
9615
 
+      -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
9616
 
+## This next piece of magic avoids the `deleted header file' problem.
9617
 
+## The problem is that when a header file which appears in a .P file
9618
 
+## is deleted, the dependency causes make to die (because there is
9619
 
+## typically no way to rebuild the header).  We avoid this by adding
9620
 
+## dummy dependencies for each header file.  Too bad gcc doesn't do
9621
 
+## this for us directly.
9622
 
+  tr ' ' '
9623
 
+' < "$tmpdepfile" |
9624
 
+## Some versions of gcc put a space before the `:'.  On the theory
9625
 
+## that the space means something, we add a space to the output as
9626
 
+## well.
9627
 
+## Some versions of the HPUX 10.20 sed can't process this invocation
9628
 
+## correctly.  Breaking it into two sed invocations is a workaround.
9629
 
+    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
9630
 
+  rm -f "$tmpdepfile"
9631
 
+  ;;
9632
 
+
9633
 
+hp)
9634
 
+  # This case exists only to let depend.m4 do its work.  It works by
9635
 
+  # looking at the text of this script.  This case will never be run,
9636
 
+  # since it is checked for above.
9637
 
+  exit 1
9638
 
+  ;;
9639
 
+
9640
 
+sgi)
9641
 
+  if test "$libtool" = yes; then
9642
 
+    "$@" "-Wp,-MDupdate,$tmpdepfile"
9643
 
+  else
9644
 
+    "$@" -MDupdate "$tmpdepfile"
9645
 
+  fi
9646
 
+  stat=$?
9647
 
+  if test $stat -eq 0; then :
9648
 
+  else
9649
 
+    rm -f "$tmpdepfile"
9650
 
+    exit $stat
9651
 
+  fi
9652
 
+  rm -f "$depfile"
9653
 
+
9654
 
+  if test -f "$tmpdepfile"; then  # yes, the sourcefile depend on other files
9655
 
+    echo "$object : \\" > "$depfile"
9656
 
+
9657
 
+    # Clip off the initial element (the dependent).  Don't try to be
9658
 
+    # clever and replace this with sed code, as IRIX sed won't handle
9659
 
+    # lines with more than a fixed number of characters (4096 in
9660
 
+    # IRIX 6.2 sed, 8192 in IRIX 6.5).  We also remove comment lines;
9661
 
+    # the IRIX cc adds comments like `#:fec' to the end of the
9662
 
+    # dependency line.
9663
 
+    tr ' ' '
9664
 
+' < "$tmpdepfile" \
9665
 
+    | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
9666
 
+    tr '
9667
 
+' ' ' >> $depfile
9668
 
+    echo >> $depfile
9669
 
+
9670
 
+    # The second pass generates a dummy entry for each header file.
9671
 
+    tr ' ' '
9672
 
+' < "$tmpdepfile" \
9673
 
+   | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
9674
 
+   >> $depfile
9675
 
+  else
9676
 
+    # The sourcefile does not contain any dependencies, so just
9677
 
+    # store a dummy comment line, to avoid errors with the Makefile
9678
 
+    # "include basename.Plo" scheme.
9679
 
+    echo "#dummy" > "$depfile"
9680
 
+  fi
9681
 
+  rm -f "$tmpdepfile"
9682
 
+  ;;
9683
 
+
9684
 
+aix)
9685
 
+  # The C for AIX Compiler uses -M and outputs the dependencies
9686
 
+  # in a .u file.  In older versions, this file always lives in the
9687
 
+  # current directory.  Also, the AIX compiler puts `$object:' at the
9688
 
+  # start of each line; $object doesn't have directory information.
9689
 
+  # Version 6 uses the directory in both cases.
9690
 
+  dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
9691
 
+  test "x$dir" = "x$object" && dir=
9692
 
+  base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
9693
 
+  if test "$libtool" = yes; then
9694
 
+    tmpdepfile1=$dir$base.u
9695
 
+    tmpdepfile2=$base.u
9696
 
+    tmpdepfile3=$dir.libs/$base.u
9697
 
+    "$@" -Wc,-M
9698
 
+  else
9699
 
+    tmpdepfile1=$dir$base.u
9700
 
+    tmpdepfile2=$dir$base.u
9701
 
+    tmpdepfile3=$dir$base.u
9702
 
+    "$@" -M
9703
 
+  fi
9704
 
+  stat=$?
9705
 
+
9706
 
+  if test $stat -eq 0; then :
9707
 
+  else
9708
 
+    rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
9709
 
+    exit $stat
9710
 
+  fi
9711
 
+
9712
 
+  for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
9713
 
+  do
9714
 
+    test -f "$tmpdepfile" && break
9715
 
+  done
9716
 
+  if test -f "$tmpdepfile"; then
9717
 
+    # Each line is of the form `foo.o: dependent.h'.
9718
 
+    # Do two passes, one to just change these to
9719
 
+    # `$object: dependent.h' and one to simply `dependent.h:'.
9720
 
+    sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
9721
 
+    # That's a tab and a space in the [].
9722
 
+    sed -e 's,^.*\.[a-z]*:[     ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
9723
 
+  else
9724
 
+    # The sourcefile does not contain any dependencies, so just
9725
 
+    # store a dummy comment line, to avoid errors with the Makefile
9726
 
+    # "include basename.Plo" scheme.
9727
 
+    echo "#dummy" > "$depfile"
9728
 
+  fi
9729
 
+  rm -f "$tmpdepfile"
9730
 
+  ;;
9731
 
+
9732
 
+icc)
9733
 
+  # Intel's C compiler understands `-MD -MF file'.  However on
9734
 
+  #    icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
9735
 
+  # ICC 7.0 will fill foo.d with something like
9736
 
+  #    foo.o: sub/foo.c
9737
 
+  #    foo.o: sub/foo.h
9738
 
+  # which is wrong.  We want:
9739
 
+  #    sub/foo.o: sub/foo.c
9740
 
+  #    sub/foo.o: sub/foo.h
9741
 
+  #    sub/foo.c:
9742
 
+  #    sub/foo.h:
9743
 
+  # ICC 7.1 will output
9744
 
+  #    foo.o: sub/foo.c sub/foo.h
9745
 
+  # and will wrap long lines using \ :
9746
 
+  #    foo.o: sub/foo.c ... \
9747
 
+  #     sub/foo.h ... \
9748
 
+  #     ...
9749
 
+
9750
 
+  "$@" -MD -MF "$tmpdepfile"
9751
 
+  stat=$?
9752
 
+  if test $stat -eq 0; then :
9753
 
+  else
9754
 
+    rm -f "$tmpdepfile"
9755
 
+    exit $stat
9756
 
+  fi
9757
 
+  rm -f "$depfile"
9758
 
+  # Each line is of the form `foo.o: dependent.h',
9759
 
+  # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
9760
 
+  # Do two passes, one to just change these to
9761
 
+  # `$object: dependent.h' and one to simply `dependent.h:'.
9762
 
+  sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
9763
 
+  # Some versions of the HPUX 10.20 sed can't process this invocation
9764
 
+  # correctly.  Breaking it into two sed invocations is a workaround.
9765
 
+  sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" |
9766
 
+    sed -e 's/$/ :/' >> "$depfile"
9767
 
+  rm -f "$tmpdepfile"
9768
 
+  ;;
9769
 
+
9770
 
+hp2)
9771
 
+  # The "hp" stanza above does not work with aCC (C++) and HP's ia64
9772
 
+  # compilers, which have integrated preprocessors.  The correct option
9773
 
+  # to use with these is +Maked; it writes dependencies to a file named
9774
 
+  # 'foo.d', which lands next to the object file, wherever that
9775
 
+  # happens to be.
9776
 
+  # Much of this is similar to the tru64 case; see comments there.
9777
 
+  dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
9778
 
+  test "x$dir" = "x$object" && dir=
9779
 
+  base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
9780
 
+  if test "$libtool" = yes; then
9781
 
+    tmpdepfile1=$dir$base.d
9782
 
+    tmpdepfile2=$dir.libs/$base.d
9783
 
+    "$@" -Wc,+Maked
9784
 
+  else
9785
 
+    tmpdepfile1=$dir$base.d
9786
 
+    tmpdepfile2=$dir$base.d
9787
 
+    "$@" +Maked
9788
 
+  fi
9789
 
+  stat=$?
9790
 
+  if test $stat -eq 0; then :
9791
 
+  else
9792
 
+     rm -f "$tmpdepfile1" "$tmpdepfile2"
9793
 
+     exit $stat
9794
 
+  fi
9795
 
+
9796
 
+  for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
9797
 
+  do
9798
 
+    test -f "$tmpdepfile" && break
9799
 
+  done
9800
 
+  if test -f "$tmpdepfile"; then
9801
 
+    sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile"
9802
 
+    # Add `dependent.h:' lines.
9803
 
+    sed -ne '2,${; s/^ *//; s/ \\*$//; s/$/:/; p;}' "$tmpdepfile" >> "$depfile"
9804
 
+  else
9805
 
+    echo "#dummy" > "$depfile"
9806
 
+  fi
9807
 
+  rm -f "$tmpdepfile" "$tmpdepfile2"
9808
 
+  ;;
9809
 
+
9810
 
+tru64)
9811
 
+   # The Tru64 compiler uses -MD to generate dependencies as a side
9812
 
+   # effect.  `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
9813
 
+   # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
9814
 
+   # dependencies in `foo.d' instead, so we check for that too.
9815
 
+   # Subdirectories are respected.
9816
 
+   dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
9817
 
+   test "x$dir" = "x$object" && dir=
9818
 
+   base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
9819
 
+
9820
 
+   if test "$libtool" = yes; then
9821
 
+      # With Tru64 cc, shared objects can also be used to make a
9822
 
+      # static library.  This mechanism is used in libtool 1.4 series to
9823
 
+      # handle both shared and static libraries in a single compilation.
9824
 
+      # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d.
9825
 
+      #
9826
 
+      # With libtool 1.5 this exception was removed, and libtool now
9827
 
+      # generates 2 separate objects for the 2 libraries.  These two
9828
 
+      # compilations output dependencies in $dir.libs/$base.o.d and
9829
 
+      # in $dir$base.o.d.  We have to check for both files, because
9830
 
+      # one of the two compilations can be disabled.  We should prefer
9831
 
+      # $dir$base.o.d over $dir.libs/$base.o.d because the latter is
9832
 
+      # automatically cleaned when .libs/ is deleted, while ignoring
9833
 
+      # the former would cause a distcleancheck panic.
9834
 
+      tmpdepfile1=$dir.libs/$base.lo.d   # libtool 1.4
9835
 
+      tmpdepfile2=$dir$base.o.d          # libtool 1.5
9836
 
+      tmpdepfile3=$dir.libs/$base.o.d    # libtool 1.5
9837
 
+      tmpdepfile4=$dir.libs/$base.d      # Compaq CCC V6.2-504
9838
 
+      "$@" -Wc,-MD
9839
 
+   else
9840
 
+      tmpdepfile1=$dir$base.o.d
9841
 
+      tmpdepfile2=$dir$base.d
9842
 
+      tmpdepfile3=$dir$base.d
9843
 
+      tmpdepfile4=$dir$base.d
9844
 
+      "$@" -MD
9845
 
+   fi
9846
 
+
9847
 
+   stat=$?
9848
 
+   if test $stat -eq 0; then :
9849
 
+   else
9850
 
+      rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
9851
 
+      exit $stat
9852
 
+   fi
9853
 
+
9854
 
+   for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
9855
 
+   do
9856
 
+     test -f "$tmpdepfile" && break
9857
 
+   done
9858
 
+   if test -f "$tmpdepfile"; then
9859
 
+      sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
9860
 
+      # That's a tab and a space in the [].
9861
 
+      sed -e 's,^.*\.[a-z]*:[   ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
9862
 
+   else
9863
 
+      echo "#dummy" > "$depfile"
9864
 
+   fi
9865
 
+   rm -f "$tmpdepfile"
9866
 
+   ;;
9867
 
+
9868
 
+#nosideeffect)
9869
 
+  # This comment above is used by automake to tell side-effect
9870
 
+  # dependency tracking mechanisms from slower ones.
9871
 
+
9872
 
+dashmstdout)
9873
 
+  # Important note: in order to support this mode, a compiler *must*
9874
 
+  # always write the preprocessed file to stdout, regardless of -o.
9875
 
+  "$@" || exit $?
9876
 
+
9877
 
+  # Remove the call to Libtool.
9878
 
+  if test "$libtool" = yes; then
9879
 
+    while test $1 != '--mode=compile'; do
9880
 
+      shift
9881
 
+    done
9882
 
+    shift
9883
 
+  fi
9884
 
+
9885
 
+  # Remove `-o $object'.
9886
 
+  IFS=" "
9887
 
+  for arg
9888
 
+  do
9889
 
+    case $arg in
9890
 
+    -o)
9891
 
+      shift
9892
 
+      ;;
9893
 
+    $object)
9894
 
+      shift
9895
 
+      ;;
9896
 
+    *)
9897
 
+      set fnord "$@" "$arg"
9898
 
+      shift # fnord
9899
 
+      shift # $arg
9900
 
+      ;;
9901
 
+    esac
9902
 
+  done
9903
 
+
9904
 
+  test -z "$dashmflag" && dashmflag=-M
9905
 
+  # Require at least two characters before searching for `:'
9906
 
+  # in the target name.  This is to cope with DOS-style filenames:
9907
 
+  # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
9908
 
+  "$@" $dashmflag |
9909
 
+    sed 's:^[  ]*[^: ][^:][^:]*\:[    ]*:'"$object"'\: :' > "$tmpdepfile"
9910
 
+  rm -f "$depfile"
9911
 
+  cat < "$tmpdepfile" > "$depfile"
9912
 
+  tr ' ' '
9913
 
+' < "$tmpdepfile" | \
9914
 
+## Some versions of the HPUX 10.20 sed can't process this invocation
9915
 
+## correctly.  Breaking it into two sed invocations is a workaround.
9916
 
+    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
9917
 
+  rm -f "$tmpdepfile"
9918
 
+  ;;
9919
 
+
9920
 
+dashXmstdout)
9921
 
+  # This case only exists to satisfy depend.m4.  It is never actually
9922
 
+  # run, as this mode is specially recognized in the preamble.
9923
 
+  exit 1
9924
 
+  ;;
9925
 
+
9926
 
+makedepend)
9927
 
+  "$@" || exit $?
9928
 
+  # Remove any Libtool call
9929
 
+  if test "$libtool" = yes; then
9930
 
+    while test $1 != '--mode=compile'; do
9931
 
+      shift
9932
 
+    done
9933
 
+    shift
9934
 
+  fi
9935
 
+  # X makedepend
9936
 
+  shift
9937
 
+  cleared=no
9938
 
+  for arg in "$@"; do
9939
 
+    case $cleared in
9940
 
+    no)
9941
 
+      set ""; shift
9942
 
+      cleared=yes ;;
9943
 
+    esac
9944
 
+    case "$arg" in
9945
 
+    -D*|-I*)
9946
 
+      set fnord "$@" "$arg"; shift ;;
9947
 
+    # Strip any option that makedepend may not understand.  Remove
9948
 
+    # the object too, otherwise makedepend will parse it as a source file.
9949
 
+    -*|$object)
9950
 
+      ;;
9951
 
+    *)
9952
 
+      set fnord "$@" "$arg"; shift ;;
9953
 
+    esac
9954
 
+  done
9955
 
+  obj_suffix="`echo $object | sed 's/^.*\././'`"
9956
 
+  touch "$tmpdepfile"
9957
 
+  ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
9958
 
+  rm -f "$depfile"
9959
 
+  cat < "$tmpdepfile" > "$depfile"
9960
 
+  sed '1,2d' "$tmpdepfile" | tr ' ' '
9961
 
+' | \
9962
 
+## Some versions of the HPUX 10.20 sed can't process this invocation
9963
 
+## correctly.  Breaking it into two sed invocations is a workaround.
9964
 
+    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
9965
 
+  rm -f "$tmpdepfile" "$tmpdepfile".bak
9966
 
+  ;;
9967
 
+
9968
 
+cpp)
9969
 
+  # Important note: in order to support this mode, a compiler *must*
9970
 
+  # always write the preprocessed file to stdout.
9971
 
+  "$@" || exit $?
9972
 
+
9973
 
+  # Remove the call to Libtool.
9974
 
+  if test "$libtool" = yes; then
9975
 
+    while test $1 != '--mode=compile'; do
9976
 
+      shift
9977
 
+    done
9978
 
+    shift
9979
 
+  fi
9980
 
+
9981
 
+  # Remove `-o $object'.
9982
 
+  IFS=" "
9983
 
+  for arg
9984
 
+  do
9985
 
+    case $arg in
9986
 
+    -o)
9987
 
+      shift
9988
 
+      ;;
9989
 
+    $object)
9990
 
+      shift
9991
 
+      ;;
9992
 
+    *)
9993
 
+      set fnord "$@" "$arg"
9994
 
+      shift # fnord
9995
 
+      shift # $arg
9996
 
+      ;;
9997
 
+    esac
9998
 
+  done
9999
 
+
10000
 
+  "$@" -E |
10001
 
+    sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
10002
 
+       -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
10003
 
+    sed '$ s: \\$::' > "$tmpdepfile"
10004
 
+  rm -f "$depfile"
10005
 
+  echo "$object : \\" > "$depfile"
10006
 
+  cat < "$tmpdepfile" >> "$depfile"
10007
 
+  sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
10008
 
+  rm -f "$tmpdepfile"
10009
 
+  ;;
10010
 
+
10011
 
+msvisualcpp)
10012
 
+  # Important note: in order to support this mode, a compiler *must*
10013
 
+  # always write the preprocessed file to stdout, regardless of -o,
10014
 
+  # because we must use -o when running libtool.
10015
 
+  "$@" || exit $?
10016
 
+  IFS=" "
10017
 
+  for arg
10018
 
+  do
10019
 
+    case "$arg" in
10020
 
+    "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
10021
 
+       set fnord "$@"
10022
 
+       shift
10023
 
+       shift
10024
 
+       ;;
10025
 
+    *)
10026
 
+       set fnord "$@" "$arg"
10027
 
+       shift
10028
 
+       shift
10029
 
+       ;;
10030
 
+    esac
10031
 
+  done
10032
 
+  "$@" -E |
10033
 
+  sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile"
10034
 
+  rm -f "$depfile"
10035
 
+  echo "$object : \\" > "$depfile"
10036
 
+  . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::   \1 \\:p' >> "$depfile"
10037
 
+  echo "       " >> "$depfile"
10038
 
+  . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile"
10039
 
+  rm -f "$tmpdepfile"
10040
 
+  ;;
10041
 
+
10042
 
+none)
10043
 
+  exec "$@"
10044
 
+  ;;
10045
 
+
10046
 
+*)
10047
 
+  echo "Unknown depmode $depmode" 1>&2
10048
 
+  exit 1
10049
 
+  ;;
10050
 
+esac
10051
 
+
10052
 
+exit 0
10053
 
+
10054
 
+# Local Variables:
10055
 
+# mode: shell-script
10056
 
+# sh-indentation: 2
10057
 
+# eval: (add-hook 'write-file-hooks 'time-stamp)
10058
 
+# time-stamp-start: "scriptversion="
10059
 
+# time-stamp-format: "%:y-%02m-%02d.%02H"
10060
 
+# time-stamp-end: "$"
10061
 
+# End:
10062
 
diff -urN dovecot-1.2.4/dovecot-libsieve/doc/devel/DESIGN dovecot-1.2.4.debian/dovecot-libsieve/doc/devel/DESIGN
10063
 
--- dovecot-1.2.4/dovecot-libsieve/doc/devel/DESIGN     1970-01-01 01:00:00.000000000 +0100
10064
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/doc/devel/DESIGN      2008-10-04 10:41:25.000000000 +0200
10065
 
@@ -0,0 +1,45 @@
10066
 
+The compiler consists of the following stages:
10067
 
+
10068
 
+PARSER: sieve-parser.c, sieve-lexer.c
10069
 
+  Parses the scriptfile and produces an abstract syntax tree for it 
10070
 
+  (sieve-ast.c). 
10071
 
+
10072
 
+VALIDATOR: sieve-validator.c
10073
 
+  Performs contextual analysis on the ast produced by the parser. This checks 
10074
 
+  for the validity of commands, tests and arguments. Also, the ast is decorated 
10075
 
+  with any context data acquired during the process. This context is used by the 
10076
 
+  last compiler stage. 
10077
 
+
10078
 
+GENERATOR: sieve-generator.c
10079
 
+  This last compiler stage uses a visitor pattern to wander through the ast and 
10080
 
+  produces sieve byte code (sieve-binary.c).
10081
 
+
10082
 
+The resulting (in-memory) binary can be fed to the interpreter for execution:
10083
 
+
10084
 
+INTERPRETER: sieve-interpreter.c 
10085
 
+  The interpreter executes the byte code and produces a sieve_result object. 
10086
 
+  This result is no more than just a collection of actions to be performed. 
10087
 
+  During execution, action commands add actions to the result. Duplates and 
10088
 
+  conflicts between actions are handled in this execution phase.
10089
 
+
10090
 
+RESULT: sieve-result.c sieve-actions.c
10091
 
+  When the result is to be executed, it needs no further checking, as the 
10092
 
+  validity of the result was verified during interpretation already. The 
10093
 
+  result's actions are executed in a transaction-like atomic manner. If one of 
10094
 
+  the actions fails, the whole transaction is rolled back meaning that either 
10095
 
+  everything succeeds or everything fails. This is only possible to some extent:
10096
 
+  transmitted responses can of course not be rolled back. However, these are 
10097
 
+  executed in the commit phase, meaning that they will only be performed if all
10098
 
+  other actions were successful.
10099
 
+  
10100
 
+Debugging:
10101
 
+
10102
 
+BINARY-DUMPER: sieve-code-dumper.c sieve-binary-dumper.c
10103
 
+  A loaded binary can be dumped to a stream in human-readable form using the 
10104
 
+  binary-dumper. The binary-dumper displays information on all the blocks that
10105
 
+  the binary consists off. Program code blocks are dumped using the code-dumper.
10106
 
+  It's implementation is similar to the interpreter, with the exception that it 
10107
 
+  performs no actions and just sequentially wanders through the byte code 
10108
 
+  printing instructions along the way. The term human-readable is a bit optimistic 
10109
 
+  though; currently, the presented data looks like an assembly language. 
10110
 
+
10111
 
diff -urN dovecot-1.2.4/dovecot-libsieve/doc/man/sievec.1 dovecot-1.2.4.debian/dovecot-libsieve/doc/man/sievec.1
10112
 
--- dovecot-1.2.4/dovecot-libsieve/doc/man/sievec.1     1970-01-01 01:00:00.000000000 +0100
10113
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/doc/man/sievec.1      2009-08-01 13:28:30.000000000 +0200
10114
 
@@ -0,0 +1,72 @@
10115
 
+.TH "SIEVEC" "1" "4 July 2009"
10116
 
+.SH NAME
10117
 
+sievec \- Sieve script compiler for the Dovecot secure IMAP server
10118
 
+.SH SYNOPSIS
10119
 
+sievec [\fB-d\fR] [\fB-x\fR "\fIextension extension ...\fR"] \fIscript-file\fR [\fIout-file\fR]
10120
 
+.SH DESCRIPTION
10121
 
+.PP
10122
 
+The \fBsievec\fP command is part of the Sieve implementation for the Dovecot secure 
10123
 
+IMAP server. Sieve (RFC 5228) is a simple and highly extensible language for filtering 
10124
 
+e-mail messages. It can be implemented for any type of mail access protocol, mail 
10125
 
+architecture and operating system. The language cannot execute external programs and in 
10126
 
+its basic form it does not provide the means to cause infinite loops, making it suitable 
10127
 
+for running securely on mail servers where mail users have no permission run arbitrary programs.
10128
 
+.PP
10129
 
+Using the \fBsievec\fP command, Sieve scripts can be compiled into a binary representation. 
10130
 
+The resulting binary can be used directly to process e-mail messages during the delivery process. 
10131
 
+The delivery of mail messages and therefore also the execution of Sieve scripts is  
10132
 
+performed by Dovecot's local delivery agent (LDA) called \fBdeliver\fP. Usually, it is not 
10133
 
+necessary to compile the Sieve script manually using \fBsievec\fP, because \fBdeliver\fP will do 
10134
 
+this automatically if the binary is missing. However, in some cases \fBdeliver\fP does not have 
10135
 
+permission to write the compiled binary to disk, forcing it to recompile the script every time it 
10136
 
+is executed. Using the \fBsievec\fP tool, this can be performed manually by an authorized user to 
10137
 
+increase performance.
10138
 
+.PP
10139
 
+The \fBsievec\fP command accepts two arguments: the \fIscript-file\fP argument specifies the 
10140
 
+script to be compiled and the \fIout-file\fR argument specifies where the (binary) output is to
10141
 
+be written. This Sieve implementation reconizes files with a \fB.sieve\fP extension as Sieve 
10142
 
+scripts and corresponding files with a \fB.svbin\fP extension as the associated compiled binary. 
10143
 
+This means for example that Dovecot's deliver process will look for a binary file 'dovecot.svbin' 
10144
 
+when it needs to execute 'dovecot.sieve'. Such filename is chosen automatically for the binary output
10145
 
+when the out-file argument is missing.
10146
 
+.PP
10147
 
+If the \fIscript-file\fP  argument is a directory, all files in that directory with a \fI.sieve\fP 
10148
 
+extension are compiled into a corresponding \fI.svbin\fP binary file. The compilation is not halted 
10149
 
+upon errors; it attempts to compile as many scripts in the directory as possible. Note that the 
10150
 
+\fB-d\fP option and the \fIout-file\fP argument are not allowed when the \fIscript-file\fP argument 
10151
 
+is a directory.
10152
 
+.PP
10153
 
+The \fBsievec\fP command is also useful to verify Sieve scripts before using. Additionally, with 
10154
 
+the \fB-d\fP option it can output a textual (and thus human-readable) dump of the generated Sieve
10155
 
+code to the specified file. The output is then identical to what the \fBsieved\fP(1) command produces
10156
 
+for a stored binary file. This output is mainly useful to find bugs in the compiler that yield corrupt 
10157
 
+binaries.
10158
 
+.SH OPTIONS
10159
 
+.TP 
10160
 
+\fB-d\fP 
10161
 
+Don't write the binary to \fIout-file\fP, but write a textual dump of the binary in 
10162
 
+stead. In this context, the \fIout-file\fP value '-' has special meaning: it causes the the textual 
10163
 
+dump to be written to \fBstdout\fP. The \fIout-file\fP argument may also be omitted, which has 
10164
 
+the same effect as '-'. The output is identical to what the \fBsieved\fP(1) command produces for 
10165
 
+a compiled Sieve binary file. Note that this option is not allowed when the \fIout-file\fP argument
10166
 
+is a directory.
10167
 
+.TP
10168
 
+\fB-x\fP "\fIextension extension ...\fP"
10169
 
+Set the available extensions. The parameter is a space-separated list of the active extensions. By
10170
 
+prepending the extension identifiers with \fB+\fP or \fB-\fP, extensions can be included or excluded 
10171
 
+relative to the default set of extensions. If no extensions have a \fB+\fP or \fB-\fP prefix, only 
10172
 
+those extensions that are explicitly listed will be enabled. Unknown extensions are ignored 
10173
 
+and a warning is produced. By default, all supported extensions are available, except for deprecated 
10174
 
+extensions or those that are still under development. 
10175
 
+
10176
 
+For example \fB-x\fP "+imapflags -enotify" will enable the deprecated imapflags extension along with all 
10177
 
+extensions that are available by default, except for the enotify extension. 
10178
 
+.SH AUTHOR
10179
 
+.PP
10180
 
+The Sieve implementation for Dovecot was written by Stephan Bosch <stephan@rename-it.nl>.
10181
 
+.PP
10182
 
+Dovecot was written by Timo Sirainen <tss@iki.fi>.
10183
 
+.SH "SEE ALSO"
10184
 
+.BR sieved (1),
10185
 
+.BR sieve-test (1)
10186
 
+
10187
 
diff -urN dovecot-1.2.4/dovecot-libsieve/doc/man/sieved.1 dovecot-1.2.4.debian/dovecot-libsieve/doc/man/sieved.1
10188
 
--- dovecot-1.2.4/dovecot-libsieve/doc/man/sieved.1     1970-01-01 01:00:00.000000000 +0100
10189
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/doc/man/sieved.1      2009-08-01 13:28:47.000000000 +0200
10190
 
@@ -0,0 +1,55 @@
10191
 
+.TH "SIEVED" "1" "4 July 2009"
10192
 
+.SH NAME
10193
 
+sieved \- Sieve script binary dump tool for the Dovecot secure IMAP server
10194
 
+.SH SYNOPSIS
10195
 
+sieved [\fB-x\fR "\fIextension extension ...\fR"] \fIsieve-binary\fR [\fIout-file\fR]
10196
 
+.br
10197
 
+.SH DESCRIPTION
10198
 
+.PP
10199
 
+The \fBsieved\fP command is part of the Sieve implementation for the Dovecot secure 
10200
 
+IMAP server. Sieve (RFC 5228) is a simple and highly extensible language for filtering 
10201
 
+e-mail messages. It can be implemented for any type of mail access protocol, mail 
10202
 
+architecture and operating system. The language cannot execute external programs and in 
10203
 
+its basic form it does not provide the means to cause infinite loops, making it suitable 
10204
 
+for running securely on mail servers where mail users have no permission run arbitrary programs.
10205
 
+.PP
10206
 
+Using the \fBsieved\fP command, Sieve binaries, which are produced for instance by
10207
 
+\fBsievec\fP(1), can be transformed into a human-readable textual representation. This can 
10208
 
+provide valuable insight in how the Sieve script is executed. This is also particularly useful 
10209
 
+to view corrupt binaries that can result from bugs in the Sieve implementation. This tool is 
10210
 
+intended mainly for development purposes, so normally system administrators and users will not 
10211
 
+need to use this tool.
10212
 
+.PP
10213
 
+The \fIsieve-binary\fR argument specifies the Sieve binary file that needs to be dumped. The
10214
 
+optional \fIout-file\fR argument specifies where the output must be written. If omitted, the
10215
 
+output is written to \fBstdout\fR.
10216
 
+.PP
10217
 
+The format of the output is not explained here in detail, but it should be relatively easy
10218
 
+to understand. The Sieve binaries comprise a set of data blocks, each of which can contain
10219
 
+arbitrary data. For the base language implementation two blocks are used: the first containing
10220
 
+a specification of all required language extensions and the second containing the main Sieve
10221
 
+program. Compiled Sieve programs are represented as flat byte code and therefore the dump of
10222
 
+the main program is a disassembly listing of the interpreter operations. Extensions can define 
10223
 
+new operations and use additional blocks. Therefore, the output of \fBsieved\fP depends greatly
10224
 
+on the language extensions used when compiling the binary. 
10225
 
+.SH OPTIONS
10226
 
+.TP
10227
 
+\fB-x\fP "\fIextension extension ...\fP"
10228
 
+Set the available extensions. The parameter is a space-separated list of the active extensions. By
10229
 
+prepending the extension identifiers with \fB+\fP or \fB-\fP, extensions can be included or excluded
10230
 
+relative to the default set of extensions. If no extensions have a \fB+\fP or \fB-\fP prefix, only 
10231
 
+those extensions that are explicitly listed will be enabled. Unknown extensions are ignored and a 
10232
 
+warning is produced. By default, all supported extensions are available, except for deprecated
10233
 
+extensions or those that are still under development.
10234
 
+
10235
 
+For example \fB-x\fP "+imapflags -enotify" will enable the deprecated imapflags extension along with all
10236
 
+extensions that are available by default, except for the enotify extension.
10237
 
+.SH AUTHOR
10238
 
+.PP
10239
 
+The Sieve implementation for Dovecot was written by Stephan Bosch <stephan@rename-it.nl>.
10240
 
+.PP
10241
 
+Dovecot was written by Timo Sirainen <tss@iki.fi>.
10242
 
+.SH "SEE ALSO"
10243
 
+.BR sievec (1),
10244
 
+.BR sieve-test (1)
10245
 
+
10246
 
diff -urN dovecot-1.2.4/dovecot-libsieve/doc/man/sieve-filter.1 dovecot-1.2.4.debian/dovecot-libsieve/doc/man/sieve-filter.1
10247
 
--- dovecot-1.2.4/dovecot-libsieve/doc/man/sieve-filter.1       1970-01-01 01:00:00.000000000 +0100
10248
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/doc/man/sieve-filter.1        2009-08-08 14:57:37.000000000 +0200
10249
 
@@ -0,0 +1,151 @@
10250
 
+.TH "SIEVE-FILTER" "1" "5 August 2009"
10251
 
+.SH NAME
10252
 
+sieve-filter \- Sieve mailbox filter tool for the Dovecot secure IMAP server
10253
 
+.PP
10254
 
+\fBWARNING: \fRThis tool is not finished and should \fB*NOT*\fR be used, unless you feel like testing newly developed
10255
 
+features! The behavior described in this manual page represents the design and not necessarily what the tool currently implements.
10256
 
+
10257
 
+.SH SYNOPSIS
10258
 
+sieve-filter [\fIoptions\fR] \fIscript-file\fR \fIsource-location\fR \fIsource-mailbox\fR [\fIinbox-namespace\fR [\fInamespace\fR ...]]
10259
 
+.TP
10260
 
+\fInamepace\fR = [prefix=]location[;option=value,option=value,...]
10261
 
+.TP
10262
 
+[FIXME: what would be the easiest way to specify a filter operation without always needing to
10263
 
+delve into the complexity of namespaces]
10264
 
+
10265
 
+.SH DESCRIPTION
10266
 
+.PP
10267
 
+The \fBsieve-filter\fP command is part of the Sieve implementation for the Dovecot secure 
10268
 
+IMAP server. Sieve (RFC 5228) is a simple and highly extensible language for filtering 
10269
 
+e-mail messages. It can be implemented for any type of mail access protocol, mail 
10270
 
+architecture and operating system. The language cannot execute external programs and in 
10271
 
+its basic form it does not provide the means to cause infinite loops, making it suitable 
10272
 
+for running securely on mail servers where mail users have no permission run arbitrary programs.
10273
 
+.PP
10274
 
+The Sieve language was originally meant for filtering messages upon delivery. However, there are
10275
 
+occasions when it is desirable to filter messages that are already stored in a mailbox, for
10276
 
+instance when a bug in a Sieve script caused many messages to be delivered incorrectly.
10277
 
+Using the sieve-filter tool it is possible to apply a Sieve script on all messages in a particular
10278
 
+mailbox, making it possible to delete messages, to store them in a different folder and to change
10279
 
+the assigned IMAP flags and keywords. Attempts to send messages to the outside world are ignored by default
10280
 
+for obvious reasons, but, using the proper command line options, it is possible to capture outgoing
10281
 
+mail as well. 
10282
 
+.PP
10283
 
+The command has three mandatory arguments: the \fIscript-file\fP argument, which specifies the path of the
10284
 
+Sieve script, the \fIsource-location\fP argument, which specifies the mail storage of the source mailbox 
10285
 
+(e.g. `maildir:~/Maildir'), and the \fIsource-mailbox\fP argument, which specifies the name of the source 
10286
 
+mailbox within the specified mail storage (e.g. `INBOX.Spam'). 
10287
 
+.PP
10288
 
+This tool does not (yet) use Dovecot's configuration file to obtain information on namespaces and the
10289
 
+location of mailboxes. Therefore, any used namespaces need to be specified on the command line. These
10290
 
+specifications directly follow the \fIsource-mailbox\fP parameter. The first specified namespace will
10291
 
+be the INBOX namespace.
10292
 
+.PP
10293
 
+If no namespaces are defined on the commandline, the source-location is used as the default mail store
10294
 
+where the INBOX is located. This means that the keep action could operate on the folder the message
10295
 
+originates from. In this case the message remains untouched and it is not duplicated, but IMAP flags and
10296
 
+keywords can be evaluated and changed with the imap4flags extension . If namespaces are defined explicitly, 
10297
 
+the source location is available as a namespace with prefix `#src/'. 
10298
 
+.PP
10299
 
+If no options are specified, the sieve-filter command runs in a simulation mode in which it only 
10300
 
+prints what would be performed, without actually doing anything. Use the \fB-e\fP option to activate
10301
 
+true script execution. Also, the source mailbox is opened read-only by default, so that the source mailbox
10302
 
+remains unchanged. Use the \fB-W\fP to allow changes in the source mailbox. 
10303
 
+
10304
 
+.SH CAUTION
10305
 
+Although this is a very useful tool, it can also be very destructive when used improperly. A small 
10306
 
+bug in your Sieve script in combination with the wrong command line options could cause it to 
10307
 
+discard (many) more e-mails than it was supposed to. Therefore, users are advised to read this manual
10308
 
+carefully and to use the simulation mode first to check what the script will do. 
10309
 
+.PP
10310
 
+\fBMAKING A BACKUP IS IMPERATIVE FOR ANY IMPORTANT MAIL!\fP
10311
 
+.PP
10312
 
+By default, it will open the source mailbox in a read-only mode, such that it will not delete any of your
10313
 
+e-mails. However, it can still litter other mailboxes with spurious copies of your e-mails if your
10314
 
+Sieve script decides to do so.
10315
 
+
10316
 
+.SH OPTIONS
10317
 
+.TP 
10318
 
+\fB-D\fP \fIsource-action\fP
10319
 
+By default, the sieve-filter command does not delete the messages from the source mailbox. This means that
10320
 
+a copy operation is executed by default and the source mailbox is not altered. The \fIsource-action\fP
10321
 
+parameter of the \fB-D\fP option can take four different values:
10322
 
+.RS 7
10323
 
+.TP 
10324
 
+\fBkeep\fP (default)
10325
 
+Keep messages in source folder. If \fB-W\fR is specified and the source mailbox is the destination of
10326
 
+a keep or fileinto action, flags can be changed by the Sieve script. Messages are never duplicated in the
10327
 
+source mailbox.
10328
 
+.TP 
10329
 
+\fBflag\fP
10330
 
+Flag messages as \\DELETED.
10331
 
+.TP 
10332
 
+\fBmove\fP [\fIfolder\fP]
10333
 
+Move messages to the indicated \fIfolder\fP.
10334
 
+.TP 
10335
 
+\fBexpunge\fP
10336
 
+Expunge messages, meaning that these are removed irreversibly when the tool finishes filtering.
10337
 
+.PP
10338
 
+Note that values other than `keep' have no effect, unless the \fB-W\fP option is specified as well.
10339
 
+.RE
10340
 
+.TP
10341
 
+\fB-e\fP
10342
 
+Turns on execution mode. By default, the sieve-filter command runs in simulation mode in which it 
10343
 
+changes nothing, meaning that no mailbox is altered in any way and no actions are performed. It only
10344
 
+prints what would be done. Using this option the sieve-filter command becomes active and performs the 
10345
 
+requested actions.
10346
 
+.TP
10347
 
+\fB-f\fP \fIenvelope-sender\fP
10348
 
+The envelope sender or return path. This is what Sieve's envelope test will compare to when the 
10349
 
+"from" envelope part is requested. Also, this is where response messages are sent to. 
10350
 
+.TP
10351
 
+\fB-m\fP \fIdefault-mailbox\fP
10352
 
+The mailbox within the default namespace where the keep action stores the message. This is "INBOX"
10353
 
+by default.
10354
 
+.TP
10355
 
+\fB-Q\fP \fImail-command\fP
10356
 
+Send outgoing e-mail through the specified program. By default, the sieve-filter command ignores 
10357
 
+Sieve actions such as redirect, reject, vacation and notify, but using this option outgoing messages
10358
 
+can be fed to the \fBstdin\fP of an external shell command. This option has no effect in simulation
10359
 
+mode, Unless you really know what you are doing, \fBDO NOT USE THIS TO FEED MAIL TO SENDMAIL!\f.
10360
 
+.TP
10361
 
+\fB-r\fP \fIrecipient-address\fP
10362
 
+The envelope recipient address. This is what Sieve's envelope test will compare to when the "to"
10363
 
+envelope part is requested. Some tests and actions will also use this as the owner's e-mail address.
10364
 
+.TP
10365
 
+\fB-S\fP \fIscript-file\fP
10366
 
+Specify additional scripts to be executed before the main script. Multiple \fB-s\fP arguments are
10367
 
+allowed and the specified scripts are executed sequentially in the order specified at the command
10368
 
+line.
10369
 
+.TP
10370
 
+\fB-W\fP
10371
 
+Enables write access to the source mailbox. This allows deleting the messages from the source mailbox
10372
 
+and changing the assigned IMAP flags and keywords. 
10373
 
+.TP
10374
 
+\fB-x\fP "\fIextension extension ...\fP"
10375
 
+Set the available extensions. The parameter is a space-separated list of the active extensions. By
10376
 
+prepending the extension identifiers with \fB+\fP or \fB-\fP, extensions can be included or excluded
10377
 
+relative to the default set of extensions. If no extensions have a \fB+\fP or \fB-\fP prefix, only 
10378
 
+those extensions that are explicitly listed will be enabled. Unknown extensions are ignored and a 
10379
 
+warning is produced. By default, all supported extensions are available, except for deprecated extensions 
10380
 
+or those that are still under development.
10381
 
+
10382
 
+For example \fB-x\fP "+imapflags -enotify" will enable the deprecated imapflags extension along with all
10383
 
+extensions that are available by default, except for the enotify extension.
10384
 
+
10385
 
+.SH EXAMPLES
10386
 
+
10387
 
+.TP
10388
 
+[...]
10389
 
+
10390
 
+.SH AUTHOR
10391
 
+.PP
10392
 
+The Sieve implementation for Dovecot was written by Stephan Bosch <stephan@rename-it.nl>.
10393
 
+.PP
10394
 
+Dovecot was written by Timo Sirainen <tss@iki.fi>.
10395
 
+
10396
 
+.SH "SEE ALSO"
10397
 
+.BR sievec (1),
10398
 
+.BR sieved (1),
10399
 
+.BR sieve-test (1)
10400
 
+
10401
 
diff -urN dovecot-1.2.4/dovecot-libsieve/doc/man/sieve-test.1 dovecot-1.2.4.debian/dovecot-libsieve/doc/man/sieve-test.1
10402
 
--- dovecot-1.2.4/dovecot-libsieve/doc/man/sieve-test.1 1970-01-01 01:00:00.000000000 +0100
10403
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/doc/man/sieve-test.1  2009-08-01 13:31:49.000000000 +0200
10404
 
@@ -0,0 +1,130 @@
10405
 
+.TH "SIEVE-TEST" "1" "4 July 2009"
10406
 
+.SH NAME
10407
 
+sieve-test \- Sieve script tester for the Dovecot secure IMAP server
10408
 
+.SH SYNOPSIS
10409
 
+sieve-test
10410
 
+[\fB-c\fR] 
10411
 
+[\fB-d\fR \fIdump-file\fR]
10412
 
+[\fB-e\fR]
10413
 
+[\fB-f\fR \fIenvelope-sender\fR]
10414
 
+[\fB-l\fR \fImail-location\fR]
10415
 
+[\fB-m\fR \fIdefault-mailbox\fR]
10416
 
+[\fB-r\fR \fIrecipient-address\fR]
10417
 
+[\fB-s\fR \fIscript-file\fR]
10418
 
+[\fB-t\fR]
10419
 
+[\fB-x\fR "\fIextension extension ...\fR"]
10420
 
+\fIscript-file\fR \fImail-file\fR
10421
 
+.SH DESCRIPTION
10422
 
+.PP
10423
 
+The \fBsieve-test\fP command is part of the Sieve implementation for the Dovecot secure 
10424
 
+IMAP server. Sieve (RFC 5228) is a simple and highly extensible language for filtering 
10425
 
+e-mail messages. It can be implemented for any type of mail access protocol, mail 
10426
 
+architecture and operating system. The language cannot execute external programs and in 
10427
 
+its basic form it does not provide the means to cause infinite loops, making it suitable 
10428
 
+for running securely on mail servers where mail users have no permission run arbitrary programs.
10429
 
+.PP
10430
 
+Using the \fBsieve-test\fP command, the execution of Sieve scripts can be tested. This evaluates
10431
 
+the script for the provided message, yielding a set of Sieve actions. Unless the \fB-e\fP option is 
10432
 
+specified, it does not actually execute these actions, meaning that it does not store or forward the 
10433
 
+message anywere. In stead, it prints a detailed list of what actions would normally take place. 
10434
 
+Note that, even when \fB-e\fP is specified, no messages are ever transmitted to remote SMTP 
10435
 
+recipients. The outgoing messages are printed to \fBstdout\fP in stead. 
10436
 
+.PP
10437
 
+This is a very useful tool to debug the execution of Sieve scripts. It can be used to verify
10438
 
+newly installed scripts for the intended behaviour and it can provide more detailed information
10439
 
+about script execution problems that are reported by the Sieve plugin.
10440
 
+.PP
10441
 
+The command has two mandatory arguments: the \fIscript-file\fP argument, which specifies the
10442
 
+script to (compile and) execute, and the \fImail-file\fP argument, which specifies the file 
10443
 
+containing the e-mail message to filter. 
10444
 
+
10445
 
+Note that this tool looks for a pre-compiled binary file with a \fI.svbin\fP extension and 
10446
 
+with basename and path identical to the specified script. Use the \fB-c\fP option to disable this
10447
 
+behavior by forcing the script to be compiled into a new binary.  
10448
 
+.SH OPTIONS
10449
 
+.TP 
10450
 
+\fB-c\fP
10451
 
+Force compilation. By default, the compiled binary is stored on disk. When this binary is found
10452
 
+during the next execution of \fBsieve-test\fP and its modification time is more recent than the
10453
 
+script file, it is used and the script is not compiled again. This option forces the script to be
10454
 
+compiled, thus ignoring any present binary. Refer to \fBsievec\fP(1) for more information about 
10455
 
+Sieve compilation.
10456
 
+.TP
10457
 
+\fB-d\fP \fIdump-file\fP
10458
 
+Causes a dump of the generated code to be written to the specified file. This is identical to the
10459
 
+dump produced by \fBsieved\fR(1). Using '-' as filename causes the dump to be written to \fBstdout\fP.
10460
 
+.TP
10461
 
+\fB-e\fP
10462
 
+Turns on true execution of the set of actions that results from running the script. In combination
10463
 
+with the \fB-l\fP parameter, the actual delivery of messages can be tested. Note that this will
10464
 
+not transmit any messages to remote SMTP recipients. Such actions only print the outgoing message
10465
 
+to \fBstdout\fP.
10466
 
+.TP
10467
 
+\fB-f\fP \fIenvelope-sender\fP
10468
 
+The envelope sender or return path. This is what Sieve's envelope test will compare to when the 
10469
 
+"from" envelope part is requested. Also, this is where response messages are sent to. 
10470
 
+.TP
10471
 
+\fB-l\fP \fImail-location\fP
10472
 
+The location of the user's mail store. The syntax of this option's \fImail-location\fP parameter 
10473
 
+is identical to what is used for the mail_location setting in the Dovecot config file. This 
10474
 
+parameter is typically used in combination with \fB-e\fP to test the actual delivery of messages. 
10475
 
+If \fB-l\fP is omitted when \fB-e\fP is specified, mail store actions like fileinto and keep are 
10476
 
+skipped.
10477
 
+.TP
10478
 
+\fB-m\fP \fIdefault-mailbox\fP
10479
 
+The mailbox where the keep action stores the message. This is "INBOX" by default.
10480
 
+.TP
10481
 
+\fB-r\fP \fIrecipient-address\fP
10482
 
+The envelope recipient address. This is what Sieve's envelope test will compare to when the "to"
10483
 
+envelope part is requested. Some tests and actions will also use this as the owner's e-mail address.
10484
 
+.TP
10485
 
+\fB-s\fP \fIscript-file\fP
10486
 
+Specify additional scripts to be executed before the main script. Multiple \fB-s\fP arguments are
10487
 
+allowed and the specified scripts are executed sequentially in the order specified at the command
10488
 
+line.
10489
 
+.TP
10490
 
+\fB-t\fP
10491
 
+Enable simple trace debugging; prints all encountered byte code instructions to \fBstdout\fP. This is
10492
 
+currently only intelligible for developers.
10493
 
+.TP
10494
 
+\fB-x\fP "\fIextension extension ...\fP"
10495
 
+Set the available extensions. The parameter is a space-separated list of the active extensions. By
10496
 
+prepending the extension identifiers with \fB+\fP or \fB-\fP, extensions can be included or excluded
10497
 
+relative to the default set of extensions. If no extensions have a \fB+\fP or \fB-\fP prefix, only 
10498
 
+those extensions that are explicitly listed will be enabled. Unknown extensions are ignored and a 
10499
 
+warning is produced. By default, all supported extensions are available, except for deprecated extensions 
10500
 
+or those that are still under development.
10501
 
+
10502
 
+For example \fB-x\fP "+imapflags -enotify" will enable the deprecated imapflags extension along with all
10503
 
+extensions that are available by default, except for the enotify extension.
10504
 
+.SH DEBUG SUPPORT
10505
 
+.PP
10506
 
+To improve script debugging, the Sieve command line tools such as \fBsieve-test\fP support a custom
10507
 
+Sieve language extension called 'vnd.dovecot.debug'. It adds the \fBdebug_print\fP command that allows
10508
 
+printing debug messages to \fBstdout\fP. 
10509
 
+.PP
10510
 
+Example:
10511
 
+.PP
10512
 
+require "vnd.dovecot.debug";
10513
 
+.PP
10514
 
+if header :contains "subject" "hello" {
10515
 
+.PP
10516
 
+  debug_print "Subject header contains hello!";
10517
 
+.PP
10518
 
+}
10519
 
+.PP
10520
 
+Other tools like \fBsievec\fP and \fBsieved\fP also recognize the vnd.dovecot.debug extension. In contrast,
10521
 
+the actual Sieve plugin for the Dovecot LDA does not allow the use of the debug extension. So, keep in mind that 
10522
 
+scripts and compiled binaries that refer to de debug extension will fail to be run by the Sieve plugin itself.
10523
 
+.PP
10524
 
+Note that it is not necessary to enable nor possible to disable the availability of the debug extension with 
10525
 
+the \fB-x\fP option.
10526
 
+.SH AUTHOR
10527
 
+.PP
10528
 
+The Sieve implementation for Dovecot was written by Stephan Bosch <stephan@rename-it.nl>.
10529
 
+.PP
10530
 
+Dovecot was written by Timo Sirainen <tss@iki.fi>.
10531
 
+.SH "SEE ALSO"
10532
 
+.BR sievec (1),
10533
 
+.BR sieved (1)
10534
 
+
10535
 
diff -urN dovecot-1.2.4/dovecot-libsieve/doc/rfc/body.rfc5173.txt dovecot-1.2.4.debian/dovecot-libsieve/doc/rfc/body.rfc5173.txt
10536
 
--- dovecot-1.2.4/dovecot-libsieve/doc/rfc/body.rfc5173.txt     1970-01-01 01:00:00.000000000 +0100
10537
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/doc/rfc/body.rfc5173.txt      2008-08-10 20:30:25.000000000 +0200
10538
 
@@ -0,0 +1,563 @@
10539
 
+
10540
 
+
10541
 
+
10542
 
+
10543
 
+
10544
 
+
10545
 
+Network Working Group                                         J. Degener
10546
 
+Request for Comments: 5173                                   P. Guenther
10547
 
+Updates: 5229                                             Sendmail, Inc.
10548
 
+Category: Standards Track                                     April 2008
10549
 
+
10550
 
+
10551
 
+
10552
 
+                 Sieve Email Filtering: Body Extension
10553
 
+
10554
 
+Status of This Memo
10555
 
+
10556
 
+   This document specifies an Internet standards track protocol for the
10557
 
+   Internet community, and requests discussion and suggestions for
10558
 
+   improvements.  Please refer to the current edition of the "Internet
10559
 
+   Official Protocol Standards" (STD 1) for the standardization state
10560
 
+   and status of this protocol.  Distribution of this memo is unlimited.
10561
 
+
10562
 
+Abstract
10563
 
+
10564
 
+   This document defines a new command for the "Sieve" email filtering
10565
 
+   language that tests for the occurrence of one or more strings in the
10566
 
+   body of an email message.
10567
 
+
10568
 
+
10569
 
+
10570
 
+
10571
 
+
10572
 
+
10573
 
+
10574
 
+
10575
 
+
10576
 
+
10577
 
+
10578
 
+
10579
 
+
10580
 
+
10581
 
+
10582
 
+
10583
 
+
10584
 
+
10585
 
+
10586
 
+
10587
 
+
10588
 
+
10589
 
+
10590
 
+
10591
 
+
10592
 
+
10593
 
+
10594
 
+
10595
 
+
10596
 
+Degener & Guenther          Standards Track                     [Page 1]
10597
 
+
10598
 
+RFC 5173         Sieve Email Filtering: Body Extension        April 2008
10599
 
+
10600
 
+
10601
 
+1.  Introduction
10602
 
+
10603
 
+   The "body" test checks for the occurrence of one or more strings in
10604
 
+   the body of an email message.  Such a test was initially discussed
10605
 
+   for the [SIEVE] base document, but was subsequently removed because
10606
 
+   it was thought to be too costly to implement.
10607
 
+
10608
 
+   Nevertheless, several server vendors have implemented some form of
10609
 
+   the "body" test.
10610
 
+
10611
 
+   This document reintroduces the "body" test as an extension, and
10612
 
+   specifies its syntax and semantics.
10613
 
+
10614
 
+2.  Conventions Used in This Document
10615
 
+
10616
 
+   The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
10617
 
+   "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
10618
 
+   document are to be interpreted as described in [KEYWORDS].
10619
 
+
10620
 
+   Conventions for notations are as in [SIEVE] Section 1.1, including
10621
 
+   the use of the "Usage:" label for the definition of text and tagged
10622
 
+   argument syntax.
10623
 
+
10624
 
+   The rules for interpreting the grammar are defined in [SIEVE] and
10625
 
+   inherited by this specification.  In particular, readers of this
10626
 
+   document are reminded that according to [SIEVE] Sections 2.6.2 and
10627
 
+   2.6.3, optional arguments such as COMPARATOR and MATCH-TYPE can
10628
 
+   appear in any order.
10629
 
+
10630
 
+3.  Capability Identifier
10631
 
+
10632
 
+   The capability string associated with the extension defined in this
10633
 
+   document is "body".
10634
 
+
10635
 
+4.  Test body
10636
 
+
10637
 
+   Usage: "body" [COMPARATOR] [MATCH-TYPE] [BODY-TRANSFORM]
10638
 
+                <key-list: string-list>
10639
 
+
10640
 
+   The body test matches content in the body of an email message, that
10641
 
+   is, anything following the first empty line after the header.  (The
10642
 
+   empty line itself, if present, is not considered to be part of the
10643
 
+   body.)
10644
 
+
10645
 
+   The COMPARATOR and MATCH-TYPE keyword parameters are defined in
10646
 
+   [SIEVE].  As specified in Sections 2.7.1 and 2.7.3 of [SIEVE], the
10647
 
+   default COMPARATOR is "i;ascii-casemap" and the default MATCH-TYPE is
10648
 
+   ":is".
10649
 
+
10650
 
+
10651
 
+
10652
 
+Degener & Guenther          Standards Track                     [Page 2]
10653
 
+
10654
 
+RFC 5173         Sieve Email Filtering: Body Extension        April 2008
10655
 
+
10656
 
+
10657
 
+   The BODY-TRANSFORM is a keyword parameter that governs how a set of
10658
 
+   strings to be matched against are extracted from the body of the
10659
 
+   message.  If a message consists of a header only, not followed by an
10660
 
+   empty line, then that set is empty and all "body" tests return false,
10661
 
+   including those that test for an empty string.  (This is similar to
10662
 
+   how the "header" test always fails when the named header fields
10663
 
+   aren't present.)  Otherwise, the transform must be followed as
10664
 
+   defined below in Section 5.
10665
 
+
10666
 
+   Note that the transformations defined here do *not* match against
10667
 
+   each line of the message independently, so the strings will usually
10668
 
+   contain CRLFs.  How these can be matched is governed by the
10669
 
+   comparator and match-type.  For example, with the default comparator
10670
 
+   of "i;ascii-casemap", they can be included literally in the key
10671
 
+   strings, or be matched with the "*" or "?" wildcards of the :matches
10672
 
+   match-type, or be skipped with :contains.
10673
 
+
10674
 
+5.  Body Transform
10675
 
+
10676
 
+   Prior to matching content in a message body, "transformations" can be
10677
 
+   applied that filter and decode certain parts of the body.  These
10678
 
+   transformations are selected by a "BODY-TRANSFORM" keyword parameter.
10679
 
+
10680
 
+   Usage: ":raw"
10681
 
+        / ":content" <content-types: string-list>
10682
 
+        / ":text"
10683
 
+
10684
 
+   The default transformation is :text.
10685
 
+
10686
 
+5.1.  Body Transform ":raw"
10687
 
+
10688
 
+   The ":raw" transform matches against the entire undecoded body of a
10689
 
+   message as a single item.
10690
 
+
10691
 
+   If the specified body-transform is ":raw", the [MIME] structure of
10692
 
+   the body is irrelevant.  The implementation MUST NOT remove any
10693
 
+   transfer encoding from the message, MUST NOT refuse to filter
10694
 
+   messages with syntactic errors (unless the environment it is part of
10695
 
+   rejects them outright), and MUST treat multipart boundaries or the
10696
 
+   MIME headers of enclosed body parts as part of the content being
10697
 
+   matched against, instead of MIME structures to interpret.
10698
 
+
10699
 
+
10700
 
+
10701
 
+
10702
 
+
10703
 
+
10704
 
+
10705
 
+
10706
 
+
10707
 
+
10708
 
+Degener & Guenther          Standards Track                     [Page 3]
10709
 
+
10710
 
+RFC 5173         Sieve Email Filtering: Body Extension        April 2008
10711
 
+
10712
 
+
10713
 
+   Example:
10714
 
+
10715
 
+        require "body";
10716
 
+
10717
 
+        # This will match a message containing the literal text
10718
 
+        # "MAKE MONEY FAST" in body parts (ignoring any
10719
 
+        # content-transfer-encodings) or MIME headers other than
10720
 
+        # the outermost RFC 2822 header.
10721
 
+
10722
 
+        if body :raw :contains "MAKE MONEY FAST" {
10723
 
+                discard;
10724
 
+        }
10725
 
+
10726
 
+5.2.  Body Transform ":content"
10727
 
+
10728
 
+   If the body transform is ":content", the MIME parts that have the
10729
 
+   specified content types are matched against independently.
10730
 
+
10731
 
+   If an individual content type begins or ends with a '/' (slash) or
10732
 
+   contains multiple slashes, then it matches no content types.
10733
 
+   Otherwise, if it contains a slash, then it specifies a full
10734
 
+   <type>/<subtype> pair, and matches only that specific content type.
10735
 
+   If it is the empty string, all MIME content types are matched.
10736
 
+   Otherwise, it specifies a <type> only, and any subtype of that type
10737
 
+   matches it.
10738
 
+
10739
 
+   The search for MIME parts matching the :content specification is
10740
 
+   recursive and automatically descends into multipart and
10741
 
+   message/rfc822 MIME parts.  All MIME parts with matching types are
10742
 
+   searched for the key strings.  The test returns true if any
10743
 
+   combination of a searched MIME part and key-list argument match.
10744
 
+
10745
 
+   If the :content specification matches a multipart MIME part, only the
10746
 
+   prologue and epilogue sections of the part will be searched for the
10747
 
+   key strings, treating the entire prologue and the entire epilogue as
10748
 
+   separate strings; the contents of nested parts are only searched if
10749
 
+   their respective types match the :content specification.
10750
 
+
10751
 
+   If the :content specification matches a message/rfc822 MIME part,
10752
 
+   only the header of the nested message will be searched for the key
10753
 
+   strings, treating the header as a single string; the contents of the
10754
 
+   nested message body parts are only searched if their content type
10755
 
+   matches the :content specification.
10756
 
+
10757
 
+   For other MIME types, the entire part will be searched as a single
10758
 
+   string.
10759
 
+
10760
 
+
10761
 
+
10762
 
+
10763
 
+
10764
 
+Degener & Guenther          Standards Track                     [Page 4]
10765
 
+
10766
 
+RFC 5173         Sieve Email Filtering: Body Extension        April 2008
10767
 
+
10768
 
+
10769
 
+   (Matches against container types with an empty match string can be
10770
 
+   useful as tests for the existence of such parts.)
10771
 
+
10772
 
+   Example:
10773
 
+
10774
 
+        From: Whomever
10775
 
+        To: Someone
10776
 
+        Date: Whenever
10777
 
+        Subject: whatever
10778
 
+        Content-Type: multipart/mixed; boundary=outer
10779
 
+
10780
 
+     &  This is a multi-part message in MIME format.
10781
 
+     &
10782
 
+        --outer
10783
 
+        Content-Type: multipart/alternative; boundary=inner
10784
 
+
10785
 
+     &  This is a nested multi-part message in MIME format.
10786
 
+     &
10787
 
+        --inner
10788
 
+        Content-Type: text/plain; charset="us-ascii"
10789
 
+
10790
 
+     $  Hello
10791
 
+     $
10792
 
+        --inner
10793
 
+        Content-Type: text/html; charset="us-ascii"
10794
 
+
10795
 
+     %  <html><body>Hello</body></html>
10796
 
+     %
10797
 
+        --inner--
10798
 
+     &
10799
 
+     &  This is the end of the inner MIME multipart.
10800
 
+     &
10801
 
+        --outer
10802
 
+        Content-Type: message/rfc822
10803
 
+
10804
 
+     !  From: Someone Else
10805
 
+     !  Subject: hello request
10806
 
+
10807
 
+     $  Please say Hello
10808
 
+     $
10809
 
+        --outer--
10810
 
+     &
10811
 
+     &  This is the end of the outer MIME multipart.
10812
 
+
10813
 
+
10814
 
+
10815
 
+
10816
 
+
10817
 
+
10818
 
+
10819
 
+
10820
 
+Degener & Guenther          Standards Track                     [Page 5]
10821
 
+
10822
 
+RFC 5173         Sieve Email Filtering: Body Extension        April 2008
10823
 
+
10824
 
+
10825
 
+   In the above example, the '&', '$', '%', and '!' characters at the
10826
 
+   start of a line are used to illustrate what portions of the example
10827
 
+   message are used in tests:
10828
 
+
10829
 
+   - the lines starting with '&' are the ones that are tested when a
10830
 
+     'body :content "multipart" :contains "MIME"' test is executed.
10831
 
+
10832
 
+   - the lines starting with '$' are the ones that are tested when a
10833
 
+     'body :content "text/plain" :contains "Hello"' test is executed.
10834
 
+
10835
 
+   - the lines starting with '%' are the ones that are tested when a
10836
 
+     'body :content "text/html" :contains "Hello"' test is executed.
10837
 
+
10838
 
+   - the lines starting with '$' or '%' are the ones that are tested
10839
 
+     when a 'body :content "text" :contains "Hello"' test is executed.
10840
 
+
10841
 
+   - the lines starting with '!' are the ones that are tested when a
10842
 
+     'body :content "message/rfc822" :contains "Hello"' test is
10843
 
+     executed.
10844
 
+
10845
 
+   Comparisons are performed on octets.  Implementations decode the
10846
 
+   content-transfer-encoding and convert text to [UTF-8] as input to the
10847
 
+   comparator.  MIME parts that cannot be decoded and converted MAY be
10848
 
+   treated as plain US-ASCII, omitted, or processed according to local
10849
 
+   conventions.  A NUL octet (character zero) SHOULD NOT cause early
10850
 
+   termination of the content being compared against.  Implementations
10851
 
+   MUST support the "quoted-printable", "base64", "7bit", "8bit", and
10852
 
+   "binary" content transfer encodings.  Implementations MUST be capable
10853
 
+   of converting to UTF-8 the US-ASCII, ISO-8859-1, and the US-ASCII
10854
 
+   subset of ISO-8859-* character sets.
10855
 
+
10856
 
+   Each matched part is matched against independently: search
10857
 
+   expressions MUST NOT match across MIME part boundaries.  MIME headers
10858
 
+   of the containing part MUST NOT be included in the data.
10859
 
+
10860
 
+
10861
 
+
10862
 
+
10863
 
+
10864
 
+
10865
 
+
10866
 
+
10867
 
+
10868
 
+
10869
 
+
10870
 
+
10871
 
+
10872
 
+
10873
 
+
10874
 
+
10875
 
+
10876
 
+Degener & Guenther          Standards Track                     [Page 6]
10877
 
+
10878
 
+RFC 5173         Sieve Email Filtering: Body Extension        April 2008
10879
 
+
10880
 
+
10881
 
+   Example:
10882
 
+
10883
 
+        require ["body", "fileinto"];
10884
 
+
10885
 
+        # Save any message with any text MIME part that contains the
10886
 
+        # words "missile" or "coordinates" in the "secrets" folder.
10887
 
+
10888
 
+        if body :content "text" :contains ["missile", "coordinates"] {
10889
 
+                fileinto "secrets";
10890
 
+        }
10891
 
+
10892
 
+        # Save any message with an audio/mp3 MIME part in
10893
 
+        # the "jukebox" folder.
10894
 
+
10895
 
+        if body :content "audio/mp3" :contains "" {
10896
 
+                fileinto "jukebox";
10897
 
+        }
10898
 
+
10899
 
+5.3.  Body Transform ":text"
10900
 
+
10901
 
+   The ":text" body transform matches against the results of an
10902
 
+   implementation's best effort at extracting UTF-8 encoded text from a
10903
 
+   message.
10904
 
+
10905
 
+   It is unspecified whether this transformation results in a single
10906
 
+   string or multiple strings being matched against.  All the text
10907
 
+   extracted from a given non-container MIME part MUST be in the same
10908
 
+   string.
10909
 
+
10910
 
+   In simple implementations, :text MAY be treated the same as :content
10911
 
+   "text".
10912
 
+
10913
 
+   Sophisticated implementations MAY strip mark-up from the text prior
10914
 
+   to matching, and MAY convert media types other than text to text
10915
 
+   prior to matching.
10916
 
+
10917
 
+   (For example, they may be able to convert proprietary text editor
10918
 
+   formats to text or apply optical character recognition algorithms to
10919
 
+   image data.)
10920
 
+
10921
 
+   Example:
10922
 
+        require ["body", "fileinto"];
10923
 
+
10924
 
+        # Save messages mentioning the project schedule in the
10925
 
+        # project/schedule folder.
10926
 
+        if body :text :contains "project schedule" {
10927
 
+                fileinto "project/schedule";
10928
 
+        }
10929
 
+
10930
 
+
10931
 
+
10932
 
+Degener & Guenther          Standards Track                     [Page 7]
10933
 
+
10934
 
+RFC 5173         Sieve Email Filtering: Body Extension        April 2008
10935
 
+
10936
 
+
10937
 
+6.  Interaction with Other Sieve Extensions
10938
 
+
10939
 
+   Any extension that extends the grammar for the COMPARATOR or MATCH-
10940
 
+   TYPE nonterminals will also affect the implementation of "body".
10941
 
+
10942
 
+   Wildcard expressions used with "body" are exempt from the side
10943
 
+   effects described in [VARIABLES].  That is, they MUST NOT set match
10944
 
+   variables (${1}, ${2}...) to the input values corresponding to
10945
 
+   wildcard sequences in the matched pattern.  However, if the extension
10946
 
+   is present, variable references in the key strings or content type
10947
 
+   strings are evaluated as described in this document.
10948
 
+
10949
 
+7.  IANA Considerations
10950
 
+
10951
 
+   The following template specifies the IANA registration of the Sieve
10952
 
+   extension specified in this document:
10953
 
+
10954
 
+   To: iana@iana.org
10955
 
+   Subject: Registration of new Sieve extension
10956
 
+
10957
 
+   Capability name: body
10958
 
+   Description:     Provides a test for matching against the
10959
 
+                    body of the message being processed
10960
 
+   RFC number:      RFC 5173
10961
 
+   Contact Address: The Sieve discussion list
10962
 
+                    <ietf-mta-filters@imc.org>
10963
 
+
10964
 
+8.  Security Considerations
10965
 
+
10966
 
+   The system MUST be sized and restricted in such a manner that even
10967
 
+   malicious use of body matching does not deny service to other users
10968
 
+   of the host system.
10969
 
+
10970
 
+   Filters relying on string matches in the raw body of an email message
10971
 
+   may be more general than intended.  Text matches are no replacement
10972
 
+   for a spam, virus, or other security related filtering system.
10973
 
+
10974
 
+9.  Acknowledgments
10975
 
+
10976
 
+   This document has been revised in part based on comments and
10977
 
+   discussions that took place on and off the SIEVE mailing list.
10978
 
+   Thanks to Cyrus Daboo, Ned Freed, Bob Johannessen, Simon Josefsson,
10979
 
+   Mark E. Mallett, Chris Markle, Alexey Melnikov, Ken Murchison, Greg
10980
 
+   Shapiro, Tim Showalter, Nigel Swinson, Dowson Tong, and Christian
10981
 
+   Vogt for reviews and suggestions.
10982
 
+
10983
 
+
10984
 
+
10985
 
+
10986
 
+
10987
 
+
10988
 
+Degener & Guenther          Standards Track                     [Page 8]
10989
 
+
10990
 
+RFC 5173         Sieve Email Filtering: Body Extension        April 2008
10991
 
+
10992
 
+
10993
 
+10.  References
10994
 
+
10995
 
+10.1.  Normative References
10996
 
+
10997
 
+   [KEYWORDS]   Bradner, S., "Key words for use in RFCs to Indicate
10998
 
+                Requirement Levels", BCP 14, RFC 2119, March 1997.
10999
 
+
11000
 
+   [MIME]       Freed, N. and N. Borenstein, "Multipurpose Internet Mail
11001
 
+                Extensions (MIME) Part One: Format of Internet Message
11002
 
+                Bodies", RFC 2045, November 1996.
11003
 
+
11004
 
+   [SIEVE]      Guenther, P., Ed., and T. Showalter, Ed., "Sieve: An
11005
 
+                Email Filtering Language", RFC 5228, January 2008.
11006
 
+
11007
 
+   [UTF-8]      Yergeau, F., "UTF-8, a transformation format of ISO
11008
 
+                10646", STD 63, RFC 3629, November 2003.
11009
 
+
11010
 
+10.2.  Informative References
11011
 
+
11012
 
+   [VARIABLES]  Homme, K., "Sieve Email Filtering: Variables Extension",
11013
 
+                RFC 5229, January 2008.
11014
 
+
11015
 
+Authors' Addresses
11016
 
+
11017
 
+   Jutta Degener
11018
 
+   5245 College Ave, Suite #127
11019
 
+   Oakland, CA 94618
11020
 
+
11021
 
+   EMail: jutta@pobox.com
11022
 
+
11023
 
+
11024
 
+   Philip Guenther
11025
 
+   Sendmail, Inc.
11026
 
+   6425 Christie Ave, 4th Floor
11027
 
+   Emeryville, CA 94608
11028
 
+
11029
 
+   EMail: guenther@sendmail.com
11030
 
+
11031
 
+
11032
 
+
11033
 
+
11034
 
+
11035
 
+
11036
 
+
11037
 
+
11038
 
+
11039
 
+
11040
 
+
11041
 
+
11042
 
+
11043
 
+
11044
 
+Degener & Guenther          Standards Track                     [Page 9]
11045
 
+
11046
 
+RFC 5173         Sieve Email Filtering: Body Extension        April 2008
11047
 
+
11048
 
+
11049
 
+Full Copyright Statement
11050
 
+
11051
 
+   Copyright (C) The IETF Trust (2008).
11052
 
+
11053
 
+   This document is subject to the rights, licenses and restrictions
11054
 
+   contained in BCP 78, and except as set forth therein, the authors
11055
 
+   retain all their rights.
11056
 
+
11057
 
+   This document and the information contained herein are provided on an
11058
 
+   "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS
11059
 
+   OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY, THE IETF TRUST AND
11060
 
+   THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS
11061
 
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF
11062
 
+   THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
11063
 
+   WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
11064
 
+
11065
 
+Intellectual Property
11066
 
+
11067
 
+   The IETF takes no position regarding the validity or scope of any
11068
 
+   Intellectual Property Rights or other rights that might be claimed to
11069
 
+   pertain to the implementation or use of the technology described in
11070
 
+   this document or the extent to which any license under such rights
11071
 
+   might or might not be available; nor does it represent that it has
11072
 
+   made any independent effort to identify any such rights.  Information
11073
 
+   on the procedures with respect to rights in RFC documents can be
11074
 
+   found in BCP 78 and BCP 79.
11075
 
+
11076
 
+   Copies of IPR disclosures made to the IETF Secretariat and any
11077
 
+   assurances of licenses to be made available, or the result of an
11078
 
+   attempt made to obtain a general license or permission for the use of
11079
 
+   such proprietary rights by implementers or users of this
11080
 
+   specification can be obtained from the IETF on-line IPR repository at
11081
 
+   http://www.ietf.org/ipr.
11082
 
+
11083
 
+   The IETF invites any interested party to bring to its attention any
11084
 
+   copyrights, patents or patent applications, or other proprietary
11085
 
+   rights that may cover technology that may be required to implement
11086
 
+   this standard.  Please address the information to the IETF at
11087
 
+   ietf-ipr@ietf.org.
11088
 
+
11089
 
+
11090
 
+
11091
 
+
11092
 
+
11093
 
+
11094
 
+
11095
 
+
11096
 
+
11097
 
+
11098
 
+
11099
 
+
11100
 
+Degener & Guenther          Standards Track                    [Page 10]
11101
 
+
11102
 
diff -urN dovecot-1.2.4/dovecot-libsieve/doc/rfc/collation.rfc4790.txt dovecot-1.2.4.debian/dovecot-libsieve/doc/rfc/collation.rfc4790.txt
11103
 
--- dovecot-1.2.4/dovecot-libsieve/doc/rfc/collation.rfc4790.txt        1970-01-01 01:00:00.000000000 +0100
11104
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/doc/rfc/collation.rfc4790.txt 2007-03-13 18:00:27.000000000 +0100
11105
 
@@ -0,0 +1,1459 @@
11106
 
+
11107
 
+
11108
 
+
11109
 
+
11110
 
+
11111
 
+
11112
 
+Network Working Group                                          C. Newman
11113
 
+Request for Comments: 4790                              Sun Microsystems
11114
 
+Category: Standards Track                                      M. Duerst
11115
 
+                                                Aoyama Gakuin University
11116
 
+                                                          A. Gulbrandsen
11117
 
+                                                                    Oryx
11118
 
+                                                              March 2007
11119
 
+
11120
 
+
11121
 
+            Internet Application Protocol Collation Registry
11122
 
+
11123
 
+Status of This Memo
11124
 
+
11125
 
+   This document specifies an Internet standards track protocol for the
11126
 
+   Internet community, and requests discussion and suggestions for
11127
 
+   improvements.  Please refer to the current edition of the "Internet
11128
 
+   Official Protocol Standards" (STD 1) for the standardization state
11129
 
+   and status of this protocol.  Distribution of this memo is unlimited.
11130
 
+
11131
 
+Copyright Notice
11132
 
+
11133
 
+   Copyright (C) The IETF Trust (2007).
11134
 
+
11135
 
+Abstract
11136
 
+
11137
 
+   Many Internet application protocols include string-based lookup,
11138
 
+   searching, or sorting operations.  However, the problem space for
11139
 
+   searching and sorting international strings is large, not fully
11140
 
+   explored, and is outside the area of expertise for the Internet
11141
 
+   Engineering Task Force (IETF).  Rather than attempt to solve such a
11142
 
+   large problem, this specification creates an abstraction framework so
11143
 
+   that application protocols can precisely identify a comparison
11144
 
+   function, and the repertoire of comparison functions can be extended
11145
 
+   in the future.
11146
 
+
11147
 
+
11148
 
+
11149
 
+
11150
 
+
11151
 
+
11152
 
+
11153
 
+
11154
 
+
11155
 
+
11156
 
+
11157
 
+
11158
 
+
11159
 
+
11160
 
+
11161
 
+
11162
 
+
11163
 
+Newman, et al.              Standards Track                     [Page 1]
11164
 
+
11165
 
+RFC 4790                   Collation Registry                 March 2007
11166
 
+
11167
 
+
11168
 
+Table of Contents
11169
 
+
11170
 
+   1.  Introduction . . . . . . . . . . . . . . . . . . . . . . . . .  4
11171
 
+     1.1.  Conventions Used in This Document  . . . . . . . . . . . .  4
11172
 
+   2.  Collation Definition and Purpose . . . . . . . . . . . . . . .  4
11173
 
+     2.1.  Definition . . . . . . . . . . . . . . . . . . . . . . . .  4
11174
 
+     2.2.  Purpose  . . . . . . . . . . . . . . . . . . . . . . . . .  4
11175
 
+     2.3.  Some Other Terms Used in this Document . . . . . . . . . .  5
11176
 
+     2.4.  Sort Keys  . . . . . . . . . . . . . . . . . . . . . . . .  5
11177
 
+   3.  Collation Identifier Syntax  . . . . . . . . . . . . . . . . .  6
11178
 
+     3.1.  Basic Syntax . . . . . . . . . . . . . . . . . . . . . . .  6
11179
 
+     3.2.  Wildcards  . . . . . . . . . . . . . . . . . . . . . . . .  6
11180
 
+     3.3.  Ordering Direction . . . . . . . . . . . . . . . . . . . .  7
11181
 
+     3.4.  URIs . . . . . . . . . . . . . . . . . . . . . . . . . . .  7
11182
 
+     3.5.  Naming Guidelines  . . . . . . . . . . . . . . . . . . . .  7
11183
 
+   4.  Collation Specification Requirements . . . . . . . . . . . . .  8
11184
 
+     4.1.  Collation/Server Interface . . . . . . . . . . . . . . . .  8
11185
 
+     4.2.  Operations Supported . . . . . . . . . . . . . . . . . . .  8
11186
 
+       4.2.1.  Validity . . . . . . . . . . . . . . . . . . . . . . .  9
11187
 
+       4.2.2.  Equality . . . . . . . . . . . . . . . . . . . . . . .  9
11188
 
+       4.2.3.  Substring  . . . . . . . . . . . . . . . . . . . . . .  9
11189
 
+       4.2.4.  Ordering . . . . . . . . . . . . . . . . . . . . . . . 10
11190
 
+     4.3.  Sort Keys  . . . . . . . . . . . . . . . . . . . . . . . . 10
11191
 
+     4.4.  Use of Lookup Tables . . . . . . . . . . . . . . . . . . . 11
11192
 
+   5.  Application Protocol Requirements  . . . . . . . . . . . . . . 11
11193
 
+     5.1.  Character Encoding . . . . . . . . . . . . . . . . . . . . 11
11194
 
+     5.2.  Operations . . . . . . . . . . . . . . . . . . . . . . . . 11
11195
 
+     5.3.  Wildcards  . . . . . . . . . . . . . . . . . . . . . . . . 12
11196
 
+     5.4.  String Comparison  . . . . . . . . . . . . . . . . . . . . 12
11197
 
+     5.5.  Disconnected Clients . . . . . . . . . . . . . . . . . . . 12
11198
 
+     5.6.  Error Codes  . . . . . . . . . . . . . . . . . . . . . . . 13
11199
 
+     5.7.  Octet Collation  . . . . . . . . . . . . . . . . . . . . . 13
11200
 
+   6.  Use by Existing Protocols  . . . . . . . . . . . . . . . . . . 13
11201
 
+   7.  Collation Registration . . . . . . . . . . . . . . . . . . . . 14
11202
 
+     7.1.  Collation Registration Procedure . . . . . . . . . . . . . 14
11203
 
+     7.2.  Collation Registration Format  . . . . . . . . . . . . . . 15
11204
 
+       7.2.1.  Registration Template  . . . . . . . . . . . . . . . . 15
11205
 
+       7.2.2.  The Collation Element  . . . . . . . . . . . . . . . . 15
11206
 
+       7.2.3.  The Identifier Element . . . . . . . . . . . . . . . . 16
11207
 
+       7.2.4.  The Title Element  . . . . . . . . . . . . . . . . . . 16
11208
 
+       7.2.5.  The Operations Element . . . . . . . . . . . . . . . . 16
11209
 
+       7.2.6.  The Specification Element  . . . . . . . . . . . . . . 16
11210
 
+       7.2.7.  The Submitter Element  . . . . . . . . . . . . . . . . 16
11211
 
+       7.2.8.  The Owner Element  . . . . . . . . . . . . . . . . . . 16
11212
 
+       7.2.9.  The Version Element  . . . . . . . . . . . . . . . . . 17
11213
 
+       7.2.10. The Variable Element . . . . . . . . . . . . . . . . . 17
11214
 
+     7.3.  Structure of Collation Registry  . . . . . . . . . . . . . 17
11215
 
+     7.4.  Example Initial Registry Summary . . . . . . . . . . . . . 18
11216
 
+
11217
 
+
11218
 
+
11219
 
+Newman, et al.              Standards Track                     [Page 2]
11220
 
+
11221
 
+RFC 4790                   Collation Registry                 March 2007
11222
 
+
11223
 
+
11224
 
+   8.  Guidelines for Expert Reviewer . . . . . . . . . . . . . . . . 18
11225
 
+   9.  Initial Collations . . . . . . . . . . . . . . . . . . . . . . 19
11226
 
+     9.1.  ASCII Numeric Collation  . . . . . . . . . . . . . . . . . 20
11227
 
+       9.1.1.  ASCII Numeric Collation Description  . . . . . . . . . 20
11228
 
+       9.1.2.  ASCII Numeric Collation Registration . . . . . . . . . 20
11229
 
+     9.2.  ASCII Casemap Collation  . . . . . . . . . . . . . . . . . 21
11230
 
+       9.2.1.  ASCII Casemap Collation Description  . . . . . . . . . 21
11231
 
+       9.2.2.  ASCII Casemap Collation Registration . . . . . . . . . 22
11232
 
+     9.3.  Octet Collation  . . . . . . . . . . . . . . . . . . . . . 22
11233
 
+       9.3.1.  Octet Collation Description  . . . . . . . . . . . . . 22
11234
 
+       9.3.2.  Octet Collation Registration . . . . . . . . . . . . . 23
11235
 
+   10. IANA Considerations  . . . . . . . . . . . . . . . . . . . . . 23
11236
 
+   11. Security Considerations  . . . . . . . . . . . . . . . . . . . 23
11237
 
+   12. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . 23
11238
 
+   13. References . . . . . . . . . . . . . . . . . . . . . . . . . . 24
11239
 
+     13.1. Normative References . . . . . . . . . . . . . . . . . . . 24
11240
 
+     13.2. Informative References . . . . . . . . . . . . . . . . . . 24
11241
 
+
11242
 
+
11243
 
+
11244
 
+
11245
 
+
11246
 
+
11247
 
+
11248
 
+
11249
 
+
11250
 
+
11251
 
+
11252
 
+
11253
 
+
11254
 
+
11255
 
+
11256
 
+
11257
 
+
11258
 
+
11259
 
+
11260
 
+
11261
 
+
11262
 
+
11263
 
+
11264
 
+
11265
 
+
11266
 
+
11267
 
+
11268
 
+
11269
 
+
11270
 
+
11271
 
+
11272
 
+
11273
 
+
11274
 
+
11275
 
+Newman, et al.              Standards Track                     [Page 3]
11276
 
+
11277
 
+RFC 4790                   Collation Registry                 March 2007
11278
 
+
11279
 
+
11280
 
+1.  Introduction
11281
 
+
11282
 
+   The Application Configuration Access Protocol ACAP [11] specification
11283
 
+   introduced the concept of a comparator (which we call collation in
11284
 
+   this document), but failed to create an IANA registry.  With the
11285
 
+   introduction of stringprep [6] and the Unicode Collation Algorithm
11286
 
+   [7], it is now time to create that registry and populate it with some
11287
 
+   initial values appropriate for an international community.  This
11288
 
+   specification replaces and generalizes the definition of a comparator
11289
 
+   in ACAP, and creates a collation registry.
11290
 
+
11291
 
+1.1.  Conventions Used in This Document
11292
 
+
11293
 
+   The key words "MUST", "MUST NOT", "SHOULD", "SHOULD NOT", and "MAY"
11294
 
+   in this document are to be interpreted as defined in "Key words for
11295
 
+   use in RFCs to Indicate Requirement Levels" [1].
11296
 
+
11297
 
+   The attribute syntax specifications use the Augmented Backus-Naur
11298
 
+   Form (ABNF) [2] notation, including the core rules defined in
11299
 
+   Appendix A.  The ABNF production "Language-tag" is imported from
11300
 
+   Language Tags [5] and "reg-name" from URI: Generic Syntax [4].
11301
 
+
11302
 
+2.  Collation Definition and Purpose
11303
 
+
11304
 
+2.1.  Definition
11305
 
+
11306
 
+   A collation is a named function which takes two arbitrary length
11307
 
+   strings as input and can be used to perform one or more of three
11308
 
+   basic comparison operations: equality test, substring match, and
11309
 
+   ordering test.
11310
 
+
11311
 
+2.2.  Purpose
11312
 
+
11313
 
+   Collations are an abstraction for comparison functions so that these
11314
 
+   comparison functions can be used in multiple protocols.  The details
11315
 
+   of a particular comparison operation can be specified by someone with
11316
 
+   appropriate expertise, independent of the application protocols that
11317
 
+   use that collation.  This is similar to the way a charset [13]
11318
 
+   separates the details of octet to character mapping from a protocol
11319
 
+   specification, such as MIME [9], or the way SASL [10] separates the
11320
 
+   details of an authentication mechanism from a protocol specification,
11321
 
+   such as ACAP [11].
11322
 
+
11323
 
+
11324
 
+
11325
 
+
11326
 
+
11327
 
+
11328
 
+
11329
 
+
11330
 
+
11331
 
+Newman, et al.              Standards Track                     [Page 4]
11332
 
+
11333
 
+RFC 4790                   Collation Registry                 March 2007
11334
 
+
11335
 
+
11336
 
+   Here is a small diagram to help illustrate the value of this
11337
 
+   abstraction:
11338
 
+
11339
 
+   +-------------------+                         +-----------------+
11340
 
+   | IMAP i18n SEARCH  |--+                      | Basic           |
11341
 
+   +-------------------+  |                   +--| Collation Spec  |
11342
 
+                          |                   |  +-----------------+
11343
 
+   +-------------------+  |  +-------------+  |  +-----------------+
11344
 
+   | ACAP i18n SEARCH  |--+--| Collation   |--+--| A stringprep    |
11345
 
+   +-------------------+  |  | Registry    |  |  | Collation Spec  |
11346
 
+                          |  +-------------+  |  +-----------------+
11347
 
+   +-------------------+  |                   |  +-----------------+
11348
 
+   | ...other protocol |--+                   |  | locale-specific |
11349
 
+   +-------------------+                      +--| Collation Spec  |
11350
 
+                                                 +-----------------+
11351
 
+
11352
 
+   Thus IMAP, ACAP, and future application protocols with international
11353
 
+   search capability simply specify how to interface to the collation
11354
 
+   registry instead of each protocol specification having to specify all
11355
 
+   the collations it supports.
11356
 
+
11357
 
+2.3.  Some Other Terms Used in this Document
11358
 
+
11359
 
+   The terms client, server, and protocol are used in somewhat unusual
11360
 
+   senses.
11361
 
+
11362
 
+   Client means a user, or a program acting directly on behalf of a
11363
 
+   user.  This may be a mail reader acting as an IMAP client, or it may
11364
 
+   be an interactive shell, where the user can type protocol commands/
11365
 
+   requests directly, or it may be a script or program written by the
11366
 
+   user.
11367
 
+
11368
 
+   Server means a program that performs services requested by the
11369
 
+   client.  This may be a traditional server such as an HTTP server, or
11370
 
+   it may be a Sieve [14] interpreter running a Sieve script written by
11371
 
+   a user.  A server needs to use the operations provided by collations
11372
 
+   in order to fulfill the client's requests.
11373
 
+
11374
 
+   The protocol describes how the client tells the server what it wants
11375
 
+   done, and (if applicable) how the server tells the client about the
11376
 
+   results.  IMAP is a protocol by this definition, and so is the Sieve
11377
 
+   language.
11378
 
+
11379
 
+2.4.  Sort Keys
11380
 
+
11381
 
+   One component of a collation is a transformation, which turns a
11382
 
+   string into a sort key, which is then used while sorting.
11383
 
+
11384
 
+
11385
 
+
11386
 
+
11387
 
+Newman, et al.              Standards Track                     [Page 5]
11388
 
+
11389
 
+RFC 4790                   Collation Registry                 March 2007
11390
 
+
11391
 
+
11392
 
+   The transformation can range from an identity mapping (e.g., the
11393
 
+   i;octet collation Section 9.3) to a mapping that makes the string
11394
 
+   unreadable to a human.
11395
 
+
11396
 
+   This is an implementation detail of collations or servers.  A
11397
 
+   protocol SHOULD NOT expose it to clients, since some collations leave
11398
 
+   the sort key's format up to the implementation, and current
11399
 
+   conformant implementations are known to use different formats.
11400
 
+
11401
 
+3.  Collation Identifier Syntax
11402
 
+
11403
 
+3.1.  Basic Syntax
11404
 
+
11405
 
+   The collation identifier itself is a single US-ASCII string.  The
11406
 
+   identifier MUST NOT be longer than 254 characters, and obeys the
11407
 
+   following grammar:
11408
 
+
11409
 
+     collation-char  = ALPHA / DIGIT / "-" / ";" / "=" / "."
11410
 
+
11411
 
+     collation-id    = collation-prefix ";" collation-core-name
11412
 
+                       *collation-arg
11413
 
+
11414
 
+     collation-scope = Language-tag / "vnd-" reg-name
11415
 
+
11416
 
+     collation-core-name = ALPHA *( ALPHA / DIGIT / "-" )
11417
 
+
11418
 
+     collation-arg   = ";" ALPHA *( ALPHA / DIGIT ) "="
11419
 
+                       1*( ALPHA / DIGIT / "." )
11420
 
+
11421
 
+
11422
 
+   Note: the ABNF production "Language-tag" is imported from Language
11423
 
+   Tags [5] and "reg-name" from URI: Generic Syntax [4].
11424
 
+
11425
 
+   There is a special identifier called "default".  For protocols that
11426
 
+   have a default collation, "default" refers to that collation.  For
11427
 
+   other protocols, the identifier "default" MUST match no collations,
11428
 
+   and servers SHOULD treat it in the same way as they treat nonexistent
11429
 
+   collations.
11430
 
+
11431
 
+3.2.  Wildcards
11432
 
+
11433
 
+   The string a client uses to select a collation MAY contain one or
11434
 
+   more wildcard ("*") characters that match zero or more collation-
11435
 
+   chars.  Wildcard characters MUST NOT be adjacent.  If the wildcard
11436
 
+   string matches multiple collations, the server SHOULD attempt to
11437
 
+   select a widely useful collation in preference to a narrowly useful
11438
 
+   one.
11439
 
+
11440
 
+
11441
 
+
11442
 
+
11443
 
+Newman, et al.              Standards Track                     [Page 6]
11444
 
+
11445
 
+RFC 4790                   Collation Registry                 March 2007
11446
 
+
11447
 
+
11448
 
+     collation-wild  =  ("*" / (ALPHA ["*"])) *(collation-char ["*"])
11449
 
+                         ; MUST NOT exceed 254 characters total
11450
 
+
11451
 
+3.3.  Ordering Direction
11452
 
+
11453
 
+   When used as a protocol element for ordering, the collation
11454
 
+   identifier MAY be prefixed by either "+" or "-" to explicitly specify
11455
 
+   an ordering direction. "+" has no effect on the ordering operation,
11456
 
+   while "-" inverts the result of the ordering operation.  In general,
11457
 
+   collation-order is used when a client requests a collation, and
11458
 
+   collation-selected is used when the server informs the client of the
11459
 
+   selected collation.
11460
 
+
11461
 
+     collation-selected =  ["+" / "-"] collation-id
11462
 
+
11463
 
+     collation-order =  ["+" / "-"] collation-wild
11464
 
+
11465
 
+3.4.  URIs
11466
 
+
11467
 
+   Some protocols are designed to use URIs [4] to refer to collations
11468
 
+   rather than simple tokens.  A special section of the IANA URL space
11469
 
+   is reserved for such usage.  The "collation-uri" form is used to
11470
 
+   refer to a specific named collation (the collation registration may
11471
 
+   not actually be present).  The "collation-auri" form is an abstract
11472
 
+   name for an ordering, a collation pattern or a vendor private
11473
 
+   collator.
11474
 
+
11475
 
+     collation-uri   =  "http://www.iana.org/assignments/collation/"
11476
 
+                        collation-id ".xml"
11477
 
+
11478
 
+     collation-auri  =  ( "http://www.iana.org/assignments/collation/"
11479
 
+                        collation-order ".xml" ) / other-uri
11480
 
+
11481
 
+     other-uri       =  <absoluteURI>
11482
 
+                     ;  excluding the IANA collation namespace.
11483
 
+
11484
 
+3.5.  Naming Guidelines
11485
 
+
11486
 
+   While this specification makes no absolute requirements on the
11487
 
+   structure of collation identifiers, naming consistency is important,
11488
 
+   so the following initial guidelines are provided.
11489
 
+
11490
 
+   Collation identifiers with an international audience typically begin
11491
 
+   with "i;".  Collation identifiers intended for a particular language
11492
 
+   or locale typically begin with a language tag [5] followed by a ";".
11493
 
+   After the first ";" is normally the name of the general collation
11494
 
+   algorithm, followed by a series of algorithm modifications separated
11495
 
+   by the ";" delimiter.  Parameterized modifications will use "=" to
11496
 
+
11497
 
+
11498
 
+
11499
 
+Newman, et al.              Standards Track                     [Page 7]
11500
 
+
11501
 
+RFC 4790                   Collation Registry                 March 2007
11502
 
+
11503
 
+
11504
 
+   delimit the parameter from the value.  The version numbers of any
11505
 
+   lookup tables used by the algorithm SHOULD be present as
11506
 
+   parameterized modifications.
11507
 
+
11508
 
+   Collation identifiers of the form *;vnd-hostname;* are reserved for
11509
 
+   vendor-specific collations created by the owner of the hostname
11510
 
+   following the "vnd-" prefix (e.g., vnd-example.com for the vendor
11511
 
+   example.com).  Registration of such collations (or the name space as
11512
 
+   a whole), with intended use of the "Vendor", is encouraged when a
11513
 
+   public specification or open-source implementation is available, but
11514
 
+   is not required.
11515
 
+
11516
 
+4.  Collation Specification Requirements
11517
 
+
11518
 
+4.1.  Collation/Server Interface
11519
 
+
11520
 
+   The collation itself defines what it operates on.  Most collations
11521
 
+   are expected to operate on character strings.  The i;octet
11522
 
+   (Section 9.3) collation operates on octet strings.  The i;ascii-
11523
 
+   numeric (Section 9.1) operation operates on numbers.
11524
 
+
11525
 
+   This specification defines the collation interface in terms of octet
11526
 
+   strings.  However, implementations may choose to use character
11527
 
+   strings instead.  Such implementations may not be able to implement
11528
 
+   e.g., i;octet.  Since i;octet is not currently mandatory to implement
11529
 
+   for any protocol, this should not be a problem.
11530
 
+
11531
 
+4.2.  Operations Supported
11532
 
+
11533
 
+   A collation specification MUST state which of the three basic
11534
 
+   operations are supported (equality, substring, ordering) and how to
11535
 
+   perform each of the supported operations on any two input character
11536
 
+   strings, including empty strings.  Collations must be deterministic,
11537
 
+   i.e., given a collation with a specific identifier, and any two fixed
11538
 
+   input strings, the result MUST be the same for the same operation.
11539
 
+
11540
 
+   In general, collation operations should behave as their names
11541
 
+   suggest.  While a collation may be new, the operations are not, so
11542
 
+   the new collation's operations should be similar to those of older
11543
 
+   collations.  For example, a date/time collation should not provide a
11544
 
+   "substring" operation that would morph IMAP substring SEARCH into
11545
 
+   e.g., a date-range search.
11546
 
+
11547
 
+   A non-obvious consequence of the rules for each collation operation
11548
 
+   is that, for any single collation, either none or all of the
11549
 
+   operations can return "undefined".  For example, it is not possible
11550
 
+   to have an equality operation that never returns "undefined", and a
11551
 
+   substring operation that occasionally does.
11552
 
+
11553
 
+
11554
 
+
11555
 
+Newman, et al.              Standards Track                     [Page 8]
11556
 
+
11557
 
+RFC 4790                   Collation Registry                 March 2007
11558
 
+
11559
 
+
11560
 
+4.2.1.  Validity
11561
 
+
11562
 
+   The validity test takes one string as argument.  It returns valid if
11563
 
+   its input string is a valid input to the collation's other
11564
 
+   operations, and invalid if not.  (In other words, a string is valid
11565
 
+   if it is equal to itself according to the collation's equality
11566
 
+   operation.)
11567
 
+
11568
 
+   The validity test is provided by all collations.  It MUST NOT be
11569
 
+   listed separately in the collation registration.
11570
 
+
11571
 
+4.2.2.  Equality
11572
 
+
11573
 
+   The equality test always returns "match" or "no-match" when it is
11574
 
+   supplied valid input, and MAY return "undefined" if one or both input
11575
 
+   strings are not valid.
11576
 
+
11577
 
+   The equality test MUST be reflexive and symmetric.  For valid input,
11578
 
+   it MUST be transitive.
11579
 
+
11580
 
+   If a collation provides either a substring or an ordering test, it
11581
 
+   MUST also provide an equality test.  The substring and/or ordering
11582
 
+   tests MUST be consistent with the equality test.
11583
 
+
11584
 
+   The return values of the equality test are called "match", "no-match"
11585
 
+   and "undefined" in this document.
11586
 
+
11587
 
+4.2.3.  Substring
11588
 
+
11589
 
+   The substring matching operation determines if the first string is a
11590
 
+   substring of the second string, i.e., if one or more substrings of
11591
 
+   the second string is equal to the first, as defined by the
11592
 
+   collation's equality operation.
11593
 
+
11594
 
+   A collation that supports substring matching will automatically
11595
 
+   support two special cases of substring matching: prefix and suffix
11596
 
+   matching, if those special cases are supported by the application
11597
 
+   protocol.  It returns "match" or "no-match" when it is supplied valid
11598
 
+   input and returns "undefined" when supplied invalid input.
11599
 
+
11600
 
+   Application protocols MAY return position information for substring
11601
 
+   matches.  If this is done, the position information SHOULD include
11602
 
+   both the starting offset and the ending offset for each match.  This
11603
 
+   is important because more sophisticated collations can match strings
11604
 
+   of unequal length (for example, a pre-composed accented character can
11605
 
+   match a decomposed accented character).  In general, overlapping
11606
 
+   matches SHOULD be reported (as when "ana" occurs twice within
11607
 
+   "banana"), although there are cases where a collation may decide not
11608
 
+
11609
 
+
11610
 
+
11611
 
+Newman, et al.              Standards Track                     [Page 9]
11612
 
+
11613
 
+RFC 4790                   Collation Registry                 March 2007
11614
 
+
11615
 
+
11616
 
+   to.  For example, in a collation which treats all whitespace
11617
 
+   sequences as identical, the substring operation could be defined such
11618
 
+   that " 1 " (SP "1" SP) is reported just once within "  1  " (SP SP
11619
 
+   "1" SP SP), not four times (SP SP "1" SP, SP "1" SP, SP "1" SP SP and
11620
 
+   SP SP "1" SP SP), since the four matches are, in a sense, the same
11621
 
+   match.
11622
 
+
11623
 
+   A string is a substring of itself.  The empty string is a substring
11624
 
+   of all strings.
11625
 
+
11626
 
+   Note that the substring operation of some collations can match
11627
 
+   strings of unequal length.  For example, a pre-composed accented
11628
 
+   character can match a decomposed accented character.  The Unicode
11629
 
+   Collation Algorithm [7] discusses this in more detail.
11630
 
+
11631
 
+   The return values of the substring operation are called "match", "no-
11632
 
+   match", and "undefined" in this document.
11633
 
+
11634
 
+4.2.4.  Ordering
11635
 
+
11636
 
+   The ordering operation determines how two strings are ordered.  It
11637
 
+   MUST be reflexive.  For valid input, it MUST be transitive and
11638
 
+   trichotomous.
11639
 
+
11640
 
+   Ordering returns "less" if the first string is listed before the
11641
 
+   second string, according to the collation; "greater", if the second
11642
 
+   string is listed before the first string; and "equal", if the two
11643
 
+   strings are equal, as defined by the collation's equality operation.
11644
 
+   If one or both strings are invalid, the result of ordering is
11645
 
+   "undefined".
11646
 
+
11647
 
+   When the collation is used with a "+" prefix, the behavior is the
11648
 
+   same as when used with no prefix.  When the collation is used with a
11649
 
+   "-" prefix, the result of the ordering operation of the collation
11650
 
+   MUST be reversed.
11651
 
+
11652
 
+   The return values of the ordering operation are called "less",
11653
 
+   "equal", "greater", and "undefined" in this document.
11654
 
+
11655
 
+4.3.  Sort Keys
11656
 
+
11657
 
+   A collation specification SHOULD describe the internal transformation
11658
 
+   algorithm to generate sort keys.  This algorithm can be applied to
11659
 
+   individual strings, and the result can be stored to potentially
11660
 
+   optimize future comparison operations.  A collation MAY specify that
11661
 
+   the sort key is generated by the identity function.  The sort key may
11662
 
+   have no meaning to a human.  The sort key may not be valid input to
11663
 
+   the collation.
11664
 
+
11665
 
+
11666
 
+
11667
 
+Newman, et al.              Standards Track                    [Page 10]
11668
 
+
11669
 
+RFC 4790                   Collation Registry                 March 2007
11670
 
+
11671
 
+
11672
 
+4.4.  Use of Lookup Tables
11673
 
+
11674
 
+   Some collations use customizable lookup tables, e.g., because the
11675
 
+   tables depend on locale, and may be modified after shipping the
11676
 
+   software.  Collations that use more than one customizable lookup
11677
 
+   table in a documented format MUST assign numbers to the tables they
11678
 
+   use.  This permits an application protocol command to access the
11679
 
+   tables used by a server collation, so that clients and servers use
11680
 
+   the same tables.
11681
 
+
11682
 
+5.  Application Protocol Requirements
11683
 
+
11684
 
+   This section describes the requirements and issues that an
11685
 
+   application protocol needs to consider if it offers searching,
11686
 
+   substring matching and/or sorting, and permits the use of characters
11687
 
+   outside the US-ASCII charset.
11688
 
+
11689
 
+5.1.  Character Encoding
11690
 
+
11691
 
+   The protocol specification has to make sure that it is clear on which
11692
 
+   characters (rather than just octets) the collations are used.  This
11693
 
+   can be done by specifying the protocol itself in terms of characters
11694
 
+   (e.g., in the case of a query language), by specifying a single
11695
 
+   character encoding for the protocol (e.g., UTF-8 [3]), or by
11696
 
+   carefully describing the relevant issues of character encoding
11697
 
+   labeling and conversion.  In the later case, details to consider
11698
 
+   include how to handle unknown charsets, any charsets that are
11699
 
+   mandatory-to-implement, any issues with byte-order that might apply,
11700
 
+   and any transfer encodings that need to be supported.
11701
 
+
11702
 
+5.2.  Operations
11703
 
+
11704
 
+   The protocol must specify which of the operations defined in this
11705
 
+   specification (equality matching, substring matching, and ordering)
11706
 
+   can be invoked in the protocol, and how they are invoked.  There may
11707
 
+   be more than one way to invoke an operation.
11708
 
+
11709
 
+   The protocol MUST provide a mechanism for the client to select the
11710
 
+   collation to use with equality matching, substring matching, and
11711
 
+   ordering.
11712
 
+
11713
 
+   If a protocol needs a total ordering and the collation chosen does
11714
 
+   not provide it because the ordering operation returns "undefined" at
11715
 
+   least once, the recommended fallback is to sort all invalid strings
11716
 
+   after the valid ones, and use i;octet to order the invalid strings.
11717
 
+
11718
 
+   Although the collation's substring function provides a list of
11719
 
+   matches, a protocol need not provide all that to the client.  It may
11720
 
+
11721
 
+
11722
 
+
11723
 
+Newman, et al.              Standards Track                    [Page 11]
11724
 
+
11725
 
+RFC 4790                   Collation Registry                 March 2007
11726
 
+
11727
 
+
11728
 
+   provide only the first matching substring, or even just the
11729
 
+   information that the substring search matched.  In this way,
11730
 
+   collations can be used with protocols that are defined such that "x
11731
 
+   is a substring of y" returns true-false.
11732
 
+
11733
 
+   If the protocol provides positional information for the results of a
11734
 
+   substring match, that positional information SHOULD fully specify the
11735
 
+   substring(s) in the result that matches, independent of the length of
11736
 
+   the search string.  For example, returning both the starting and
11737
 
+   ending offset of the match would suffice, as would the starting
11738
 
+   offset and a length.  Returning just the starting offset is not
11739
 
+   acceptable.  This rule is necessary because advanced collations can
11740
 
+   treat strings of different lengths as equal (for example, pre-
11741
 
+   composed and decomposed accented characters).
11742
 
+
11743
 
+5.3.  Wildcards
11744
 
+
11745
 
+   The protocol MUST specify whether it allows the use of wildcards in
11746
 
+   collation identifiers.  If the protocol allows wildcards, then:
11747
 
+      The protocol MUST specify how comparisons behave in the absence of
11748
 
+      explicit collation negotiation, or when a collation of "default"
11749
 
+      is requested.  The protocol MAY specify that the default collation
11750
 
+      used in such circumstances is sensitive to server configuration.
11751
 
+
11752
 
+      The protocol SHOULD provide a way to list available collations
11753
 
+      matching a given wildcard pattern, or patterns.
11754
 
+
11755
 
+5.4.  String Comparison
11756
 
+
11757
 
+   If a protocol compares strings in any nontrivial way, using a
11758
 
+   collation may be appropriate.  As an example, many protocols use
11759
 
+   case-independent strings.  In many cases, a simple ASCII mapping to
11760
 
+   upper/lower case works well.  In other cases, it may be better to use
11761
 
+   a specifiable collation; for example, so that a server can treat "i"
11762
 
+   and "I" as equivalent in Italy, and different in Turkey (Turkish also
11763
 
+   has a dotted upper-case" I" and a dotless lower-case "i").
11764
 
+
11765
 
+   Protocol designers should consider, in each case, whether to use a
11766
 
+   specifiable collation.  Keywords often have other needs than user
11767
 
+   variables, and search arguments may be different again.
11768
 
+
11769
 
+5.5.  Disconnected Clients
11770
 
+
11771
 
+   If the protocol supports disconnected clients, and a collation is
11772
 
+   used that can use configurable tables (e.g., to support
11773
 
+   locale-specific extensions), then the client may not be able to
11774
 
+   reproduce the server's collation operations while offline.
11775
 
+
11776
 
+
11777
 
+
11778
 
+
11779
 
+Newman, et al.              Standards Track                    [Page 12]
11780
 
+
11781
 
+RFC 4790                   Collation Registry                 March 2007
11782
 
+
11783
 
+
11784
 
+   A mechanism to download such tables has been discussed.  Such a
11785
 
+   mechanism is not included in the present specification, since the
11786
 
+   problem is not yet well understood.
11787
 
+
11788
 
+5.6.  Error Codes
11789
 
+
11790
 
+   The protocol specification should consider assigning protocol error
11791
 
+   codes for the following circumstances:
11792
 
+
11793
 
+   o  The client requests the use of a collation by identifier or
11794
 
+      pattern, but no implemented collation matches that pattern.
11795
 
+
11796
 
+   o  The client attempts to use a collation for an operation that is
11797
 
+      not supported by that collation -- for example, attempting to use
11798
 
+      the "i;ascii-numeric" collation for substring matching.
11799
 
+
11800
 
+   o  The client uses an equality or substring matching collation, and
11801
 
+      the result is an error.  It may be appropriate to distinguish
11802
 
+      between the two input strings, particularly when one is supplied
11803
 
+      by the client and the other is stored by the server.  It might
11804
 
+      also be appropriate to distinguish the specific case of an invalid
11805
 
+      UTF-8 string.
11806
 
+
11807
 
+5.7.  Octet Collation
11808
 
+
11809
 
+   The i;octet (Section 9.3) collation is only usable with protocols
11810
 
+   based on octet-strings.  Clients and servers MUST NOT use i;octet
11811
 
+   with other protocols.
11812
 
+
11813
 
+   If the protocol permits the use of collations with data structures
11814
 
+   other than strings, the protocol MUST describe the default behavior
11815
 
+   for a collation with those data structures.
11816
 
+
11817
 
+6.  Use by Existing Protocols
11818
 
+
11819
 
+   This section is informative.
11820
 
+
11821
 
+   Both ACAP [11] and Sieve [14] are standards track specifications that
11822
 
+   used collations prior to the creation of this specification and
11823
 
+   registry.  Those standards do not meet all the application protocol
11824
 
+   requirements described in Section 5.
11825
 
+
11826
 
+   These protocols allow the use of the i;octet (Section 9.3) collation
11827
 
+   working directly on UTF-8 data, as used in these protocols.
11828
 
+
11829
 
+
11830
 
+
11831
 
+
11832
 
+
11833
 
+
11834
 
+
11835
 
+Newman, et al.              Standards Track                    [Page 13]
11836
 
+
11837
 
+RFC 4790                   Collation Registry                 March 2007
11838
 
+
11839
 
+
11840
 
+   In Sieve, all matches are either true or false.  Accordingly, Sieve
11841
 
+   servers must treat "undefined" and "no-match" results of the equality
11842
 
+   and substring operations as false, and only "match" as true.
11843
 
+
11844
 
+   In ACAP and Sieve, there are no invalid strings.  In this document's
11845
 
+   terms, invalid strings sort after valid strings.
11846
 
+
11847
 
+   IMAP [15] also collates, although that is explicit only when the
11848
 
+   COMPARATOR [17] extension is used.  The built-in IMAP substring
11849
 
+   operation and the ordering provided by the SORT [16] extension may
11850
 
+   not meet the requirements made in this document.
11851
 
+
11852
 
+   Other protocols may be in a similar position.
11853
 
+
11854
 
+   In IMAP, the default collation is i;ascii-casemap, because its
11855
 
+   operations are understood to match IMAP's built-in operations.
11856
 
+
11857
 
+7.  Collation Registration
11858
 
+
11859
 
+7.1.  Collation Registration Procedure
11860
 
+
11861
 
+   The IETF will create a mailing list, collation@ietf.org, which can be
11862
 
+   used for public discussion of collation proposals prior to
11863
 
+   registration.  Use of the mailing list is strongly encouraged.  The
11864
 
+   IESG will appoint a designated expert who will monitor the
11865
 
+   collation@ietf.org mailing list and review registrations.
11866
 
+
11867
 
+   The registration procedure begins when a completed registration
11868
 
+   template is sent to iana@iana.org and collation@ietf.org.  The
11869
 
+   designated expert is expected to tell IANA and the submitter of the
11870
 
+   registration within two weeks whether the registration is approved,
11871
 
+   approved with minor changes, or rejected with cause.  When a
11872
 
+   registration is rejected with cause, it can be re-submitted if the
11873
 
+   concerns listed in the cause are addressed.  Decisions made by the
11874
 
+   designated expert can be appealed to the IESG Applications Area
11875
 
+   Director, then to the IESG.  They follow the normal appeals procedure
11876
 
+   for IESG decisions.
11877
 
+
11878
 
+   Collation registrations in a standards track, BCP, or IESG-approved
11879
 
+   experimental RFC are owned by the IETF, and changes to the
11880
 
+   registration follow normal procedures for updating such documents.
11881
 
+   Collation registrations in other RFCs are owned by the RFC author(s).
11882
 
+   Other collation registrations are owned by the individual(s) listed
11883
 
+   in the contact field of the registration, and IANA will preserve this
11884
 
+   information.
11885
 
+
11886
 
+   If the registration is a change of an existing collation, it MUST be
11887
 
+   approved by the owner.  In the event the owner cannot be contacted
11888
 
+
11889
 
+
11890
 
+
11891
 
+Newman, et al.              Standards Track                    [Page 14]
11892
 
+
11893
 
+RFC 4790                   Collation Registry                 March 2007
11894
 
+
11895
 
+
11896
 
+   for a period of one month, and the designated expert deems the change
11897
 
+   necessary, the IESG MAY re-assign ownership to an appropriate party.
11898
 
+
11899
 
+7.2.  Collation Registration Format
11900
 
+
11901
 
+   Registration of a collation is done by sending a well-formed XML
11902
 
+   document to collation@ietf.org and iana@iana.org.
11903
 
+
11904
 
+7.2.1.  Registration Template
11905
 
+
11906
 
+   Here is a template for the registration:
11907
 
+
11908
 
+   <?xml version='1.0'?>
11909
 
+   <!DOCTYPE collation SYSTEM 'collationreg.dtd'>
11910
 
+   <collation rfc="YYYY" scope="global" intendedUse="common">
11911
 
+     <identifier>collation identifier</identifier>
11912
 
+     <title>technical title for collation</title>
11913
 
+     <operations>equality order substring</operations>
11914
 
+     <specification>specification reference</specification>
11915
 
+     <owner>email address of owner or IETF</owner>
11916
 
+     <submitter>email address of submitter</submitter>
11917
 
+     <version>1</version>
11918
 
+   </collation>
11919
 
+
11920
 
+7.2.2.  The Collation Element
11921
 
+
11922
 
+   The root of the registration document MUST be a <collation> element.
11923
 
+   The collation element contains the other elements in the
11924
 
+   registration, which are described in the following sub-subsections,
11925
 
+   in the order given here.
11926
 
+
11927
 
+   The <collation> element MAY include an "rfc=" attribute if the
11928
 
+   specification is in an RFC.  The "rfc=" attribute gives only the
11929
 
+   number of the RFC, without any prefix, such as "RFC", or suffix, such
11930
 
+   as ".txt".
11931
 
+
11932
 
+   The <collation> element MUST include a "scope=" attribute, which MUST
11933
 
+   have one of the values "global", "local", or "other".
11934
 
+
11935
 
+   The <collation> element MUST include an "intendedUse=" attribute,
11936
 
+   which must have one of the values "common", "limited", "vendor", or
11937
 
+   "deprecated".  Collation specifications intended for "common" use are
11938
 
+   expected to reference standards from standards bodies with
11939
 
+   significant experience dealing with the details of international
11940
 
+   character sets.
11941
 
+
11942
 
+   Be aware that future revisions of this specification may add
11943
 
+   additional function types, as well as additional XML attributes,
11944
 
+
11945
 
+
11946
 
+
11947
 
+Newman, et al.              Standards Track                    [Page 15]
11948
 
+
11949
 
+RFC 4790                   Collation Registry                 March 2007
11950
 
+
11951
 
+
11952
 
+   values, and elements.  Any system that automatically parses these XML
11953
 
+   documents MUST take this into account to preserve future
11954
 
+   compatibility.
11955
 
+
11956
 
+7.2.3.  The Identifier Element
11957
 
+
11958
 
+   The <identifier> element gives the precise identifier of the
11959
 
+   collation, e.g., i;ascii-casemap.  The <identifier> element is
11960
 
+   mandatory.
11961
 
+
11962
 
+7.2.4.  The Title Element
11963
 
+
11964
 
+   The <title> element gives the title of the collation.  The <title>
11965
 
+   element is mandatory.
11966
 
+
11967
 
+7.2.5.  The Operations Element
11968
 
+
11969
 
+   The <operations> element lists which of the three operations
11970
 
+   ("equality", "order" or "substring") the collation provides,
11971
 
+   separated by single spaces.  The <operations> element is mandatory.
11972
 
+
11973
 
+7.2.6.  The Specification Element
11974
 
+
11975
 
+   The <specification> element describes where to find the
11976
 
+   specification.  The <specification> element is mandatory.  It MAY
11977
 
+   have a URI attribute.  There may be more than one <specification>
11978
 
+   element, in which case, they together form the specification.
11979
 
+
11980
 
+   If it is discovered that parts of a collation specification conflict,
11981
 
+   a new revision of the collation is necessary, and the
11982
 
+   collation@ietf.org mailing list should be notified.
11983
 
+
11984
 
+7.2.7.  The Submitter Element
11985
 
+
11986
 
+   The <submitter> element provides an RFC 2822 [12] email address for
11987
 
+   the person who submitted the registration.  It is optional if the
11988
 
+   <owner> element contains an email address.
11989
 
+
11990
 
+   There may be more than one <submitter> element.
11991
 
+
11992
 
+7.2.8.  The Owner Element
11993
 
+
11994
 
+   The <owner> element contains either the four letters "IETF" or an
11995
 
+   email address of the owner of the registration.  The <owner> element
11996
 
+   is mandatory.  There may be more than one <owner> element.  If so,
11997
 
+   all owners are equal.  Each owner can speak for all.
11998
 
+
11999
 
+
12000
 
+
12001
 
+
12002
 
+
12003
 
+Newman, et al.              Standards Track                    [Page 16]
12004
 
+
12005
 
+RFC 4790                   Collation Registry                 March 2007
12006
 
+
12007
 
+
12008
 
+7.2.9.  The Version Element
12009
 
+
12010
 
+   The <version> element MUST be included when the registration is
12011
 
+   likely to be revised, or has been revised in such a way that the
12012
 
+   results change for one or more input strings.  The <version> element
12013
 
+   is optional.
12014
 
+
12015
 
+7.2.10.  The Variable Element
12016
 
+
12017
 
+   The <variable> element specifies an optional variable to control the
12018
 
+   collation's behaviour, for example whether it is case sensitive.  The
12019
 
+   <variable> element is optional.  When <variable> is used, it must
12020
 
+   contain <name> and <default> elements, and it may contain one or more
12021
 
+   <value> elements.
12022
 
+
12023
 
+7.2.10.1.  The Name Element
12024
 
+
12025
 
+   The <name> element specifies the name value of a variable.  The
12026
 
+   <name> element is mandatory.
12027
 
+
12028
 
+7.2.10.2.  The Default Element
12029
 
+
12030
 
+   The <default> element specifies the default value of a variable.  The
12031
 
+   <default> element is mandatory.
12032
 
+
12033
 
+7.2.10.3.  The Value Element
12034
 
+
12035
 
+   The <value> element specifies a legal value of a variable.  The
12036
 
+   <value> element is optional.  If one or more <value> elements are
12037
 
+   present, only those values are legal.  If none are, then the
12038
 
+   variable's legal values do not form an enumerated set, and the rules
12039
 
+   MUST be specified in an RFC accompanying the registration.
12040
 
+
12041
 
+7.3.  Structure of Collation Registry
12042
 
+
12043
 
+   Once the registration is approved, IANA will store each XML
12044
 
+   registration document in a URL of the form
12045
 
+   http://www.iana.org/assignments/collation/collation-id.xml, where
12046
 
+   collation-id is the content of the identifier element in the
12047
 
+   registration.  Both the submitter and the designated expert are
12048
 
+   responsible for verifying that the XML is well-formed.  The
12049
 
+   registration document should avoid using new elements.  If any are
12050
 
+   necessary, it is important to be consistent with other registrations.
12051
 
+
12052
 
+   IANA will also maintain a text summary of the registry under the name
12053
 
+   http://www.iana.org/assignments/collation/collation-index.html.  This
12054
 
+   summary is divided into four sections.  The first section is for
12055
 
+   collations intended for common use.  This section is intended for
12056
 
+
12057
 
+
12058
 
+
12059
 
+Newman, et al.              Standards Track                    [Page 17]
12060
 
+
12061
 
+RFC 4790                   Collation Registry                 March 2007
12062
 
+
12063
 
+
12064
 
+   collation registrations published in IESG-approved RFCs, or for
12065
 
+   locally scoped collations from the primary standards body for that
12066
 
+   locale.  The designated expert is encouraged to reject collation
12067
 
+   registrations with an intended use of "common" if the expert believes
12068
 
+   it should be "limited", as it is desirable to keep the number of
12069
 
+   "common" registrations small and of high quality.  The second section
12070
 
+   is reserved for limited-use collations.  The third section is
12071
 
+   reserved for registered vendor-specific collations.  The final
12072
 
+   section is reserved for deprecated collations.
12073
 
+
12074
 
+7.4.  Example Initial Registry Summary
12075
 
+
12076
 
+   The following is an example of how IANA might structure the initial
12077
 
+   registry summary.html file:
12078
 
+
12079
 
+     Collation                              Functions Scope Reference
12080
 
+     ---------                              --------- ----- ---------
12081
 
+   Common Use Collations:
12082
 
+     i;ascii-casemap                        e, o, s   Local [RFC 4790]
12083
 
+
12084
 
+   Limited Use Collations:
12085
 
+     i;octet                                e, o, s   Other [RFC 4790]
12086
 
+     i;ascii-numeric                        e, o      Other [RFC 4790]
12087
 
+
12088
 
+   Vendor Collations:
12089
 
+
12090
 
+   Deprecated Collations:
12091
 
+
12092
 
+
12093
 
+   References
12094
 
+   ----------
12095
 
+   [RFC 4790]  Newman, C., Duerst, M., Gulbrandsen, A., "Internet
12096
 
+               Application Protocol Collation Registry", RFC 4790,
12097
 
+               Sun Microsystems, March 2007.
12098
 
+
12099
 
+8.  Guidelines for Expert Reviewer
12100
 
+
12101
 
+   The expert reviewer appointed by the IESG has fairly broad latitude
12102
 
+   for this registry.  While a number of collations are expected
12103
 
+   (particularly customizations of the UCA for localized use), an
12104
 
+   explosion of collations (particularly common-use collations) is not
12105
 
+   desirable for widespread interoperability.  However, it is important
12106
 
+   for the expert reviewer to provide cause when rejecting a
12107
 
+   registration, and, when possible, to describe corrective action to
12108
 
+
12109
 
+
12110
 
+
12111
 
+
12112
 
+
12113
 
+
12114
 
+
12115
 
+Newman, et al.              Standards Track                    [Page 18]
12116
 
+
12117
 
+RFC 4790                   Collation Registry                 March 2007
12118
 
+
12119
 
+
12120
 
+   permit the registration to proceed.  The following table includes
12121
 
+   some example reasons to reject a registration with cause:
12122
 
+
12123
 
+   o  The registration is not a well-formed XML document.
12124
 
+
12125
 
+   o  The registration has an intended use of "common", but there is no
12126
 
+      evidence the collation will be widely deployed, so it should be
12127
 
+      listed as "limited".
12128
 
+
12129
 
+   o  The registration has an intended use of "common", but it is
12130
 
+      redundant with the functionality of a previously registered
12131
 
+      "common" collation.
12132
 
+
12133
 
+   o  The registration has an intended use of "common", but the
12134
 
+      specification is not detailed enough to allow interoperable
12135
 
+      implementations by others.
12136
 
+
12137
 
+   o  The collation identifier fails to precisely identify the version
12138
 
+      numbers of relevant tables to use.
12139
 
+
12140
 
+   o  The registration fails to meet one of the "MUST" requirements in
12141
 
+      Section 4.
12142
 
+
12143
 
+   o  The collation identifier fails to meet the syntax in Section 3.
12144
 
+
12145
 
+   o  The collation specification referenced in the registration is
12146
 
+      vague or has optional features without a clear behavior specified.
12147
 
+
12148
 
+   o  The referenced specification does not adequately address security
12149
 
+      considerations specific to that collation.
12150
 
+
12151
 
+   o  The registration's operations are needlessly different from those
12152
 
+      of traditional operations.
12153
 
+
12154
 
+   o  The registration's XML is needlessly different from that of
12155
 
+      already registered collations.
12156
 
+
12157
 
+9.  Initial Collations
12158
 
+
12159
 
+   This section registers the three collations that were originally
12160
 
+   defined in [11], and are implemented in most [14] engines.  Some of
12161
 
+   the behavior of these collations is perhaps not ideal, such as
12162
 
+   i;ascii-casemap accepting non-ASCII input.  Compatibility with widely
12163
 
+   deployed code was judged more important than fixing the collations.
12164
 
+   Some of the aspects of these collations are necessary to maintain
12165
 
+   compatibility with widely deployed code.
12166
 
+
12167
 
+
12168
 
+
12169
 
+
12170
 
+
12171
 
+Newman, et al.              Standards Track                    [Page 19]
12172
 
+
12173
 
+RFC 4790                   Collation Registry                 March 2007
12174
 
+
12175
 
+
12176
 
+9.1.  ASCII Numeric Collation
12177
 
+
12178
 
+9.1.1.  ASCII Numeric Collation Description
12179
 
+
12180
 
+   The "i;ascii-numeric" collation is a simple collation intended for
12181
 
+   use with arbitrarily-sized, unsigned decimal integer numbers stored
12182
 
+   as octet strings.  US-ASCII digits (0x30 to 0x39) represent digits of
12183
 
+   the numbers.  Before converting from string to integer, the input
12184
 
+   string is truncated at the first non-digit character.  All input is
12185
 
+   valid; strings that do not start with a digit represent positive
12186
 
+   infinity.
12187
 
+
12188
 
+   The collation supports equality and ordering, but does not support
12189
 
+   the substring operation.
12190
 
+
12191
 
+   The equality operation returns "match" if the two strings represent
12192
 
+   the same number (i.e., leading zeroes and trailing non-digits are
12193
 
+   disregarded), and "no-match" if the two strings represent different
12194
 
+   numbers.
12195
 
+
12196
 
+   The ordering operation returns "less" if the first string represents
12197
 
+   a smaller number than the second, "equal" if they represent the same
12198
 
+   number, and "greater" if the first string represents a larger number
12199
 
+   than the second.
12200
 
+
12201
 
+   Some examples: "0" is less than "1", and "1" is less than
12202
 
+   "4294967298". "4294967298", "04294967298", and "4294967298b" are all
12203
 
+   equal. "04294967298" is less than "". "", "x", and "y" are equal.
12204
 
+
12205
 
+9.1.2.  ASCII Numeric Collation Registration
12206
 
+
12207
 
+   <?xml version='1.0'?>
12208
 
+   <!DOCTYPE collation SYSTEM 'collationreg.dtd'>
12209
 
+   <collation rfc="4790" scope="other" intendedUse="limited">
12210
 
+     <identifier>i;ascii-numeric</identifier>
12211
 
+     <title>ASCII Numeric</title>
12212
 
+     <operations>equality order</operations>
12213
 
+     <specification>RFC 4790</specification>
12214
 
+     <owner>IETF</owner>
12215
 
+     <submitter>chris.newman@sun.com</submitter>
12216
 
+   </collation>
12217
 
+
12218
 
+
12219
 
+
12220
 
+
12221
 
+
12222
 
+
12223
 
+
12224
 
+
12225
 
+
12226
 
+
12227
 
+Newman, et al.              Standards Track                    [Page 20]
12228
 
+
12229
 
+RFC 4790                   Collation Registry                 March 2007
12230
 
+
12231
 
+
12232
 
+9.2.  ASCII Casemap Collation
12233
 
+
12234
 
+9.2.1.  ASCII Casemap Collation Description
12235
 
+
12236
 
+   The "i;ascii-casemap" collation is a simple collation that operates
12237
 
+   on octet strings and treats US-ASCII letters case-insensitively.  It
12238
 
+   provides equality, substring, and ordering operations.  All input is
12239
 
+   valid.  Note that letters outside ASCII are not treated case-
12240
 
+   insensitively.
12241
 
+
12242
 
+   Its equality, ordering, and substring operations are as for i;octet,
12243
 
+   except that at first, the lower-case letters (octet values 97-122) in
12244
 
+   each input string are changed to upper case (octet values 65-90).
12245
 
+
12246
 
+   Care should be taken when using OS-supplied functions to implement
12247
 
+   this collation, as it is not locale sensitive.  Functions, such as
12248
 
+   strcasecmp and toupper, are sometimes locale sensitive, and may
12249
 
+   inappropriately map lower-case letters other than a-z to upper case.
12250
 
+
12251
 
+   The i;ascii-casemap collation is well-suited for use with many
12252
 
+   Internet protocols and computer languages.  Use with natural language
12253
 
+   is often inappropriate; even though the collation apparently supports
12254
 
+   languages such as Swahili and English, in real-world use, it tends to
12255
 
+   mis-sort a number of types of string:
12256
 
+
12257
 
+   o  people and place names containing non-ASCII,
12258
 
+
12259
 
+   o  words such as "naive" (if spelled with an accent, the accented
12260
 
+      character could push the word to the wrong spot in a sorted list),
12261
 
+
12262
 
+   o  names such as "Lloyd" (which, in Welsh, sorts after "Lyon", unlike
12263
 
+      in English),
12264
 
+
12265
 
+   o  strings containing euro and pound sterling symbols, quotation
12266
 
+      marks other than '"', dashes/hyphens, etc.
12267
 
+
12268
 
+
12269
 
+
12270
 
+
12271
 
+
12272
 
+
12273
 
+
12274
 
+
12275
 
+
12276
 
+
12277
 
+
12278
 
+
12279
 
+
12280
 
+
12281
 
+
12282
 
+
12283
 
+Newman, et al.              Standards Track                    [Page 21]
12284
 
+
12285
 
+RFC 4790                   Collation Registry                 March 2007
12286
 
+
12287
 
+
12288
 
+9.2.2.  ASCII Casemap Collation Registration
12289
 
+
12290
 
+   <?xml version='1.0'?>
12291
 
+   <!DOCTYPE collation SYSTEM 'collationreg.dtd'>
12292
 
+   <collation rfc="4790" scope="local" intendedUse="common">
12293
 
+     <identifier>i;ascii-casemap</identifier>
12294
 
+     <title>ASCII Casemap</title>
12295
 
+     <operations>equality order substring</operations>
12296
 
+     <specification>RFC 4790</specification>
12297
 
+     <owner>IETF</owner>
12298
 
+     <submitter>chris.newman@sun.com</submitter>
12299
 
+   </collation>
12300
 
+
12301
 
+9.3.  Octet Collation
12302
 
+
12303
 
+9.3.1.  Octet Collation Description
12304
 
+
12305
 
+   The "i;octet" collation is a simple and fast collation intended for
12306
 
+   use on binary octet strings rather than on character data.  Protocols
12307
 
+   that want to make this collation available have to do so by
12308
 
+   explicitly allowing it.  If not explicitly allowed, it MUST NOT be
12309
 
+   used.  It never returns an "undefined" result.  It provides equality,
12310
 
+   substring, and ordering operations.
12311
 
+
12312
 
+   The ordering algorithm is as follows:
12313
 
+
12314
 
+   1.  If both strings are the empty string, return the result "equal".
12315
 
+
12316
 
+   2.  If the first string is empty and the second is not, return the
12317
 
+       result "less".
12318
 
+
12319
 
+   3.  If the second string is empty and the first is not, return the
12320
 
+       result "greater".
12321
 
+
12322
 
+   4.  If both strings begin with the same octet value, remove the first
12323
 
+       octet from both strings and repeat this algorithm from step 1.
12324
 
+
12325
 
+   5.  If the unsigned value (0 to 255) of the first octet of the first
12326
 
+       string is less than the unsigned value of the first octet of the
12327
 
+       second string, then return "less".
12328
 
+
12329
 
+   6.  If this step is reached, return "greater".
12330
 
+
12331
 
+   This algorithm is roughly equivalent to the C library function
12332
 
+   memcmp, with appropriate length checks added.
12333
 
+
12334
 
+
12335
 
+
12336
 
+
12337
 
+
12338
 
+
12339
 
+Newman, et al.              Standards Track                    [Page 22]
12340
 
+
12341
 
+RFC 4790                   Collation Registry                 March 2007
12342
 
+
12343
 
+
12344
 
+   The matching operation returns "match" if the sorting algorithm would
12345
 
+   return "equal".  Otherwise, the matching operation returns "no-
12346
 
+   match".
12347
 
+
12348
 
+   The substring operation returns "match" if the first string is the
12349
 
+   empty string, or if there exists a substring of the second string of
12350
 
+   length equal to the length of the first string, which would result in
12351
 
+   a "match" result from the equality function.  Otherwise, the
12352
 
+   substring operation returns "no-match".
12353
 
+
12354
 
+9.3.2.  Octet Collation Registration
12355
 
+
12356
 
+   This collation is defined with intendedUse="limited" because it can
12357
 
+   only be used by protocols that explicitly allow it.
12358
 
+
12359
 
+   <?xml version='1.0'?>
12360
 
+   <!DOCTYPE collation SYSTEM 'collationreg.dtd'>
12361
 
+   <collation rfc="4790" scope="global" intendedUse="limited">
12362
 
+     <identifier>i;octet</identifier>
12363
 
+     <title>Octet</title>
12364
 
+     <operations>equality order substring</operations>
12365
 
+     <specification>RFC 4790</specification>
12366
 
+     <owner>IETF</owner>
12367
 
+     <submitter>chris.newman@sun.com</submitter>
12368
 
+   </collation>
12369
 
+
12370
 
+10.  IANA Considerations
12371
 
+
12372
 
+   Section 7 defines how to register collations with IANA.  Section 9
12373
 
+   defines a list of predefined collations that have been registered
12374
 
+   with IANA.
12375
 
+
12376
 
+11.  Security Considerations
12377
 
+
12378
 
+   Collations will normally be used with UTF-8 strings.  Thus, the
12379
 
+   security considerations for UTF-8 [3], stringprep [6], and Unicode
12380
 
+   TR-36 [8] also apply, and are normative to this specification.
12381
 
+
12382
 
+12.  Acknowledgements
12383
 
+
12384
 
+   The authors want to thank all who have contributed to this document,
12385
 
+   including Brian Carpenter, John Cowan, Dave Cridland, Mark Davis,
12386
 
+   Spencer Dawkins, Lisa Dusseault, Lars Eggert, Frank Ellermann, Philip
12387
 
+   Guenther, Tony Hansen, Ted Hardie, Sam Hartman, Kjetil Torgrim Homme,
12388
 
+   Michael Kay, John Klensin, Alexey Melnikov, Jim Melton, and Abhijit
12389
 
+   Menon-Sen.
12390
 
+
12391
 
+
12392
 
+
12393
 
+
12394
 
+
12395
 
+Newman, et al.              Standards Track                    [Page 23]
12396
 
+
12397
 
+RFC 4790                   Collation Registry                 March 2007
12398
 
+
12399
 
+
12400
 
+13.  References
12401
 
+
12402
 
+13.1.  Normative References
12403
 
+
12404
 
+   [1]   Bradner, S., "Key words for use in RFCs to Indicate Requirement
12405
 
+         Levels", BCP 14, RFC 2119, March 1997.
12406
 
+
12407
 
+   [2]   Crocker, D. and P. Overell, "Augmented BNF for Syntax
12408
 
+         Specifications: ABNF", RFC 4234, October 2005.
12409
 
+
12410
 
+   [3]   Yergeau, F., "UTF-8, a transformation format of ISO 10646",
12411
 
+         STD 63, RFC 3629, November 2003.
12412
 
+
12413
 
+   [4]   Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform
12414
 
+         Resource Identifier (URI): Generic Syntax", RFC 3986,
12415
 
+         January 2005.
12416
 
+
12417
 
+   [5]   Phillips, A. and M. Davis, "Tags for Identifying Languages",
12418
 
+         BCP 47, RFC 4646, September 2006.
12419
 
+
12420
 
+   [6]   Hoffman, P. and M. Blanchet, "Preparation of Internationalized
12421
 
+         Strings ("stringprep")", RFC 3454, December 2002.
12422
 
+
12423
 
+   [7]   Davis, M. and K. Whistler, "Unicode Collation Algorithm version
12424
 
+         14", May 2005,
12425
 
+         <http://www.unicode.org/reports/tr10/tr10-14.html>.
12426
 
+
12427
 
+   [8]   Davis, M. and M. Suignard, "Unicode Security Considerations",
12428
 
+         February 2006, <http://www.unicode.org/reports/tr36/>.
12429
 
+
12430
 
+13.2.  Informative References
12431
 
+
12432
 
+   [9]   Freed, N. and N. Borenstein, "Multipurpose Internet Mail
12433
 
+         Extensions (MIME) Part One: Format of Internet Message Bodies",
12434
 
+         RFC 2045, November 1996.
12435
 
+
12436
 
+   [10]  Melnikov, A., "Simple Authentication and Security Layer
12437
 
+         (SASL)", RFC 4422, June 2006.
12438
 
+
12439
 
+   [11]  Newman, C. and J. Myers, "ACAP -- Application Configuration
12440
 
+         Access Protocol", RFC 2244, November 1997.
12441
 
+
12442
 
+   [12]  Resnick, P., "Internet Message Format", RFC 2822, April 2001.
12443
 
+
12444
 
+   [13]  Freed, N. and J. Postel, "IANA Charset Registration
12445
 
+         Procedures", BCP 19, RFC 2978, October 2000.
12446
 
+
12447
 
+
12448
 
+
12449
 
+
12450
 
+
12451
 
+Newman, et al.              Standards Track                    [Page 24]
12452
 
+
12453
 
+RFC 4790                   Collation Registry                 March 2007
12454
 
+
12455
 
+
12456
 
+   [14]  Showalter, T., "Sieve: A Mail Filtering Language", RFC 3028,
12457
 
+         January 2001.
12458
 
+
12459
 
+   [15]  Crispin, M., "Internet Message Access Protocol - Version
12460
 
+         4rev1", RFC 3501, March 2003.
12461
 
+
12462
 
+   [16]  Crispin, M. and K. Murchison, "Internet Message Access Protocol
12463
 
+         - Sort and Thread Extensions", Work in Progress, May 2004.
12464
 
+
12465
 
+   [17]  Newman, C. and A. Gulbrandsen, "Internet Message Access
12466
 
+         Protocol Internationalization", Work in Progress, January 2006.
12467
 
+
12468
 
+Authors' Addresses
12469
 
+
12470
 
+   Chris Newman
12471
 
+   Sun Microsystems
12472
 
+   1050 Lakes Drive
12473
 
+   West Covina, CA  91790
12474
 
+   USA
12475
 
+
12476
 
+   EMail: chris.newman@sun.com
12477
 
+
12478
 
+
12479
 
+   Martin Duerst
12480
 
+   Aoyama Gakuin University
12481
 
+   5-10-1 Fuchinobe
12482
 
+   Sagamihara, Kanagawa  229-8558
12483
 
+   Japan
12484
 
+
12485
 
+   Phone: +81 42 759 6329
12486
 
+   Fax:   +81 42 759 6495
12487
 
+   EMail: duerst@it.aoyama.ac.jp
12488
 
+   URI:   http://www.sw.it.aoyama.ac.jp/D%C3%BCrst/
12489
 
+
12490
 
+   Note: Please write "Duerst" with u-umlaut wherever possible, for
12491
 
+   example as "D&#252;rst" in XML and HTML.
12492
 
+
12493
 
+
12494
 
+   Arnt Gulbrandsen
12495
 
+   Oryx Mail Systems GmbH
12496
 
+   Schweppermannstr. 8
12497
 
+   81671 Munich
12498
 
+   Germany
12499
 
+
12500
 
+   Fax:   +49 89 4502 9758
12501
 
+   EMail: arnt@oryx.com
12502
 
+   URI:   http://www.oryx.com/arnt/
12503
 
+
12504
 
+
12505
 
+
12506
 
+
12507
 
+Newman, et al.              Standards Track                    [Page 25]
12508
 
+
12509
 
+RFC 4790                   Collation Registry                 March 2007
12510
 
+
12511
 
+
12512
 
+Full Copyright Statement
12513
 
+
12514
 
+   Copyright (C) The IETF Trust (2007).
12515
 
+
12516
 
+   This document is subject to the rights, licenses and restrictions
12517
 
+   contained in BCP 78, and except as set forth therein, the authors
12518
 
+   retain all their rights.
12519
 
+
12520
 
+   This document and the information contained herein are provided on an
12521
 
+   "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS
12522
 
+   OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY, THE IETF TRUST AND
12523
 
+   THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS
12524
 
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF
12525
 
+   THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
12526
 
+   WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
12527
 
+
12528
 
+Intellectual Property
12529
 
+
12530
 
+   The IETF takes no position regarding the validity or scope of any
12531
 
+   Intellectual Property Rights or other rights that might be claimed to
12532
 
+   pertain to the implementation or use of the technology described in
12533
 
+   this document or the extent to which any license under such rights
12534
 
+   might or might not be available; nor does it represent that it has
12535
 
+   made any independent effort to identify any such rights.  Information
12536
 
+   on the procedures with respect to rights in RFC documents can be
12537
 
+   found in BCP 78 and BCP 79.
12538
 
+
12539
 
+   Copies of IPR disclosures made to the IETF Secretariat and any
12540
 
+   assurances of licenses to be made available, or the result of an
12541
 
+   attempt made to obtain a general license or permission for the use of
12542
 
+   such proprietary rights by implementers or users of this
12543
 
+   specification can be obtained from the IETF on-line IPR repository at
12544
 
+   http://www.ietf.org/ipr.
12545
 
+
12546
 
+   The IETF invites any interested party to bring to its attention any
12547
 
+   copyrights, patents or patent applications, or other proprietary
12548
 
+   rights that may cover technology that may be required to implement
12549
 
+   this standard.  Please address the information to the IETF at
12550
 
+   ietf-ipr@ietf.org.
12551
 
+
12552
 
+Acknowledgement
12553
 
+
12554
 
+   Funding for the RFC Editor function is currently provided by the
12555
 
+   Internet Society.
12556
 
+
12557
 
+
12558
 
+
12559
 
+
12560
 
+
12561
 
+
12562
 
+
12563
 
+Newman, et al.              Standards Track                    [Page 26]
12564
 
+
12565
 
diff -urN dovecot-1.2.4/dovecot-libsieve/doc/rfc/copy.rfc3894.txt dovecot-1.2.4.debian/dovecot-libsieve/doc/rfc/copy.rfc3894.txt
12566
 
--- dovecot-1.2.4/dovecot-libsieve/doc/rfc/copy.rfc3894.txt     1970-01-01 01:00:00.000000000 +0100
12567
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/doc/rfc/copy.rfc3894.txt      2008-08-04 10:39:20.000000000 +0200
12568
 
@@ -0,0 +1,283 @@
12569
 
+
12570
 
+
12571
 
+
12572
 
+
12573
 
+
12574
 
+
12575
 
+Network Working Group                                         J. Degener
12576
 
+Request for Comments: 3894                                Sendmail, Inc.
12577
 
+Category: Standards Track                                   October 2004
12578
 
+
12579
 
+
12580
 
+             Sieve Extension: Copying Without Side Effects
12581
 
+
12582
 
+Status of this Memo
12583
 
+
12584
 
+   This document specifies an Internet standards track protocol for the
12585
 
+   Internet community, and requests discussion and suggestions for
12586
 
+   improvements.  Please refer to the current edition of the "Internet
12587
 
+   Official Protocol Standards" (STD 1) for the standardization state
12588
 
+   and status of this protocol.  Distribution of this memo is unlimited.
12589
 
+
12590
 
+Copyright Notice
12591
 
+
12592
 
+   Copyright (C) The Internet Society (2004).
12593
 
+
12594
 
+Abstract
12595
 
+
12596
 
+   The Sieve scripting language allows users to control handling and
12597
 
+   disposal of their incoming e-mail.  By default, an e-mail message
12598
 
+   that is processed by a Sieve script is saved in the owner's "inbox".
12599
 
+   Actions such as "fileinto" and "redirect" cancel this default
12600
 
+   behavior.
12601
 
+
12602
 
+   This document defines a new keyword parameter, ":copy", to be used
12603
 
+   with the Sieve "fileinto" and "redirect" actions.  Adding ":copy" to
12604
 
+   an action suppresses cancellation of the default "inbox" save.  It
12605
 
+   allows users to add commands to an existing script without changing
12606
 
+   the meaning of the rest of the script.
12607
 
+
12608
 
+1.  Introduction
12609
 
+
12610
 
+   The Sieve scripting language [SIEVE] allows users to control handling
12611
 
+   and disposal of their incoming e-mail.  Two frequently used Sieve
12612
 
+   commands are "fileinto" (saving into a local message store, such as
12613
 
+   an IMAP server) and "redirect" (forwarding to another e-mail
12614
 
+   address).  Both of these cancel the Sieve default behavior of saving
12615
 
+   into the user's "inbox".
12616
 
+
12617
 
+   But some users have the notion of forwarding an extra copy of a
12618
 
+   message for safekeeping to another e-mail address, or of saving a
12619
 
+   copy in a folder - in addition to the regular message delivery, which
12620
 
+   shouldn't be affected by the copy.
12621
 
+
12622
 
+
12623
 
+
12624
 
+
12625
 
+
12626
 
+Degener                     Standards Track                     [Page 1]
12627
 
+
12628
 
+RFC 3894      Sieve Extension - Copy Without Side Effects   October 2004
12629
 
+
12630
 
+
12631
 
+   If saving an extra copy is all the user wanted to do,
12632
 
+
12633
 
+      fileinto "unfiltered";
12634
 
+      keep;
12635
 
+
12636
 
+   would do the job.  The "keep" command does explicitly what the
12637
 
+   cancelled default behavior did.  But the explicit "keep" is a poor
12638
 
+   substitute for the implicit "keep" when more processing follows:
12639
 
+
12640
 
+      fileinto "unfiltered";
12641
 
+      keep;
12642
 
+
12643
 
+      if header "Subject" "MAKE MONEY FAST!!!"
12644
 
+      {
12645
 
+              discard;
12646
 
+      }
12647
 
+
12648
 
+   In this example, the "discard" is ineffective against the explicit
12649
 
+   "keep"; the discarded message still ends up in the user's inbox.
12650
 
+
12651
 
+   It is possible to generate Sieve code that perfectly expresses a
12652
 
+   user's wishes, but such code quickly grows unwieldy because it needs
12653
 
+   to keep track of the state that the implicit "keep" would have had
12654
 
+   without the "fileinto" or "redirect" command.
12655
 
+
12656
 
+   This extension tries to make life easier for user interface designers
12657
 
+   and script writers by allowing them to express the "copy" semantics
12658
 
+   directly.
12659
 
+
12660
 
+2.  Conventions used
12661
 
+
12662
 
+   Conventions for notations are as in [SIEVE] section 1.1, including
12663
 
+   use of [KEYWORDS] and "Syntax:" label for the definition of action
12664
 
+   and tagged arguments syntax.
12665
 
+
12666
 
+   The capability string associated with extension defined in this
12667
 
+   document is "copy".
12668
 
+
12669
 
+3.  ":copy" extension to the "fileinto" and "redirect" commands
12670
 
+
12671
 
+   Syntax:
12672
 
+        "fileinto" [":copy"] <folder: string>
12673
 
+        "redirect" [":copy"] <address: string>
12674
 
+
12675
 
+   If the optional ":copy" keyword is specified with "fileinto" or
12676
 
+   "redirect", the tagged command does not cancel the implicit "keep".
12677
 
+   Instead, it merely files or redirects a copy in addition to whatever
12678
 
+   else is happening to the message.
12679
 
+
12680
 
+
12681
 
+
12682
 
+Degener                     Standards Track                     [Page 2]
12683
 
+
12684
 
+RFC 3894      Sieve Extension - Copy Without Side Effects   October 2004
12685
 
+
12686
 
+
12687
 
+   Example:
12688
 
+
12689
 
+      require ["copy", "fileinto"];
12690
 
+      fileinto :copy "incoming";
12691
 
+
12692
 
+      # ... more processing follows ...
12693
 
+
12694
 
+4.  Security Considerations
12695
 
+
12696
 
+   The "copy" extension makes it easier to eavesdrop on a user's message
12697
 
+   stream without the user noticing.  This was technically possible
12698
 
+   before if an attacker gained read/write access to a user's Sieve
12699
 
+   scripts, but now an attacker no longer needs to parse a script in
12700
 
+   order to modify it.  Write access to Sieve scripts must be protected
12701
 
+   as strongly as read/write access to e-mail, for example by using
12702
 
+   secure directory protocols such as correctly parameterized LDAP over
12703
 
+   TLS [LDAP].
12704
 
+
12705
 
+   Organizations that wish to monitor their users' e-mail traffic must
12706
 
+   familiarize themselves with local data protection laws before
12707
 
+   creating stores of old e-mail traffic without control, or perhaps
12708
 
+   even knowledge, of the sender or intended recipients.
12709
 
+
12710
 
+   Organizations that legally use "redirect :copy" to eavesdrop on
12711
 
+   correspondence (for example, by keeping a log to answer questions
12712
 
+   about insider trading at a later time) can avoid future problems by
12713
 
+   setting users' privacy expectations correctly.
12714
 
+
12715
 
+5.  IANA Considerations
12716
 
+
12717
 
+   The following template specifies the IANA registration of the "copy"
12718
 
+   Sieve extension specified in this document.
12719
 
+
12720
 
+   To: iana@iana.org
12721
 
+   Subject: Registration of new Sieve extension
12722
 
+
12723
 
+   Capability name: copy
12724
 
+   Capability keyword: copy
12725
 
+   Capability arguments: N/A
12726
 
+   Standards Track: RFC 3894
12727
 
+   Person and email address to contact for further information:
12728
 
+
12729
 
+      Jutta Degener
12730
 
+      Sendmail, Inc.
12731
 
+      6425 Christie Ave, 4th Floor
12732
 
+      Emeryville, CA 94608
12733
 
+
12734
 
+      Email: jutta@sendmail.com
12735
 
+
12736
 
+
12737
 
+
12738
 
+Degener                     Standards Track                     [Page 3]
12739
 
+
12740
 
+RFC 3894      Sieve Extension - Copy Without Side Effects   October 2004
12741
 
+
12742
 
+
12743
 
+   This information has been added to the list of Sieve extensions given
12744
 
+   on http://www.iana.org/assignments/sieve-extensions.
12745
 
+
12746
 
+6.  Acknowledgments
12747
 
+
12748
 
+   Thanks to Eric Allman, Ned Freed, Will Lee, Nigel Swinson, and Rand
12749
 
+   Wacker for corrections and comments.
12750
 
+
12751
 
+7.  References
12752
 
+
12753
 
+7.1.  Normative References
12754
 
+
12755
 
+   [KEYWORDS] Bradner, S., "Key words for use in RFCs to Indicate
12756
 
+              Requirement Levels", BCP 14, RFC 2119, March 1997.
12757
 
+
12758
 
+   [SIEVE]    Showalter, T., "Sieve: A Mail Filtering Language", RFC
12759
 
+              3028, January 2001.
12760
 
+
12761
 
+7.2.  Informative References
12762
 
+
12763
 
+   [LDAP]     Wahl, M., Alvestrand, H., Hodges, J., and R. Morgan,
12764
 
+              "Authentication Methods for LDAP", RFC 2829, May 2000.
12765
 
+
12766
 
+Author's Address
12767
 
+
12768
 
+   Jutta Degener
12769
 
+   Sendmail, Inc.
12770
 
+   6425 Christie Ave, 4th Floor
12771
 
+   Emeryville, CA 94608
12772
 
+
12773
 
+   EMail: jutta@sendmail.com
12774
 
+
12775
 
+
12776
 
+
12777
 
+
12778
 
+
12779
 
+
12780
 
+
12781
 
+
12782
 
+
12783
 
+
12784
 
+
12785
 
+
12786
 
+
12787
 
+
12788
 
+
12789
 
+
12790
 
+
12791
 
+
12792
 
+
12793
 
+
12794
 
+Degener                     Standards Track                     [Page 4]
12795
 
+
12796
 
+RFC 3894      Sieve Extension - Copy Without Side Effects   October 2004
12797
 
+
12798
 
+
12799
 
+Full Copyright Statement
12800
 
+
12801
 
+   Copyright (C) The Internet Society (2004).
12802
 
+
12803
 
+   This document is subject to the rights, licenses and restrictions
12804
 
+   contained in BCP 78, and except as set forth therein, the authors
12805
 
+   retain all their rights.
12806
 
+
12807
 
+   This document and the information contained herein are provided on an
12808
 
+   "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/S HE
12809
 
+   REPRESENTS OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE
12810
 
+   INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR
12811
 
+   IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF
12812
 
+   THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
12813
 
+   WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
12814
 
+
12815
 
+Intellectual Property
12816
 
+
12817
 
+   The IETF takes no position regarding the validity or scope of any
12818
 
+   Intellectual Property Rights or other rights that might be claimed to
12819
 
+   pertain to the implementation or use of the technology described in
12820
 
+   this document or the extent to which any license under such rights
12821
 
+   might or might not be available; nor does it represent that it has
12822
 
+   made any independent effort to identify any such rights.  Information
12823
 
+   on the IETF's procedures with respect to rights in IETF Documents can
12824
 
+   be found in BCP 78 and BCP 79.
12825
 
+
12826
 
+   Copies of IPR disclosures made to the IETF Secretariat and any
12827
 
+   assurances of licenses to be made available, or the result of an
12828
 
+   attempt made to obtain a general license or permission for the use of
12829
 
+   such proprietary rights by implementers or users of this
12830
 
+   specification can be obtained from the IETF on-line IPR repository at
12831
 
+   http://www.ietf.org/ipr.
12832
 
+
12833
 
+   The IETF invites any interested party to bring to its attention any
12834
 
+   copyrights, patents or patent applications, or other proprietary
12835
 
+   rights that may cover technology that may be required to implement
12836
 
+   this standard.  Please address the information to the IETF at ietf-
12837
 
+   ipr@ietf.org.
12838
 
+
12839
 
+Acknowledgement
12840
 
+
12841
 
+   Funding for the RFC Editor function is currently provided by the
12842
 
+   Internet Society.
12843
 
+
12844
 
+
12845
 
+
12846
 
+
12847
 
+
12848
 
+
12849
 
+
12850
 
+Degener                     Standards Track                     [Page 5]
12851
 
+
12852
 
diff -urN dovecot-1.2.4/dovecot-libsieve/doc/rfc/deprecated/draft-martin-sieve-notify-01.txt dovecot-1.2.4.debian/dovecot-libsieve/doc/rfc/deprecated/draft-martin-sieve-notify-01.txt
12853
 
--- dovecot-1.2.4/dovecot-libsieve/doc/rfc/deprecated/draft-martin-sieve-notify-01.txt  1970-01-01 01:00:00.000000000 +0100
12854
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/doc/rfc/deprecated/draft-martin-sieve-notify-01.txt   2001-11-29 06:42:35.000000000 +0100
12855
 
@@ -0,0 +1,457 @@
12856
 
+
12857
 
+
12858
 
+
12859
 
+
12860
 
+
12861
 
+
12862
 
+
12863
 
+Network Working Group                                         Tim Martin
12864
 
+Document: draft-martin-sieve-notify-01.txt            Wolfgang Segmuller
12865
 
+Expires December 6, 2001                                     1 June 2001
12866
 
+
12867
 
+
12868
 
+         Sieve -- An extension for providing instant notifications
12869
 
+
12870
 
+                      <draft-ietf-sieve-notify-01.txt>
12871
 
+
12872
 
+Status of this Memo
12873
 
+
12874
 
+    This document is an Internet-Draft and is in full conformance with
12875
 
+    all provisions of Section 10 of RFC2026.  Internet-Drafts are
12876
 
+    working documents of the Internet Engineering Task Force (IETF), its
12877
 
+    areas, and its working groups.  Note that other groups may also
12878
 
+    distribute working documents as Internet-Drafts.
12879
 
+
12880
 
+    Internet-Drafts are draft documents valid for a maximum of six
12881
 
+    months and may be updated, replaced, or obsoleted by other documents
12882
 
+    at any time.  It is inappropriate to use Internet- Drafts as
12883
 
+    reference material or to cite them other than as "work in progress."
12884
 
+
12885
 
+   
12886
 
+     The list of current Internet-Drafts can be accessed at
12887
 
+     http://www.ietf.org/1id-abstracts.html
12888
 
+
12889
 
+     The list of Internet-Draft Shadow Directories can be accessed at
12890
 
+     http://www.ietf.org/shadow.html.
12891
 
+
12892
 
+
12893
 
+    Distribution of this memo is unlimited.
12894
 
+
12895
 
+
12896
 
+Abstract
12897
 
+
12898
 
+    Users go to great lengths to be notified as quickly as possible that
12899
 
+    they have received new mail. Most of these methods involve polling
12900
 
+    to check for new messages periodically. A push method handled by the
12901
 
+    final delivery agent gives users quicker notifications and saves
12902
 
+    server resources. This document does not specify the notification
12903
 
+    method but is expected that using existing instant messaging
12904
 
+    infrastructure such as Zephyr, ICQ, or SMS messages will be popular.
12905
 
+    This draft describes an extension to the Sieve mail filtering
12906
 
+    language that allows users to give specific preferences for
12907
 
+    notification of Sieve actions.
12908
 
+
12909
 
+
12910
 
+
12911
 
+
12912
 
+
12913
 
+
12914
 
+
12915
 
+
12916
 
+
12917
 
+
12918
 
+
12919
 
+Expires December 6, 2001        Martin                          [Page 1]
12920
 
+
12921
 
+Internet Draft      Sieve -- Notifications extension        June 1, 2001
12922
 
+
12923
 
+
12924
 
+                           TTaabbllee ooff CCoonntteennttss
12925
 
+
12926
 
+
12927
 
+
12928
 
+Status of this Memo  . . . . . . . . . . . . . . . . . . . . . . . .   1
12929
 
+
12930
 
+Abstract . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .   1
12931
 
+
12932
 
+1.     Introduction  . . . . . . . . . . . . . . . . . . . . . . . .   3
12933
 
+1.1.   Conventions Used in This Document . . . . . . . . . . . . . .   3
12934
 
+
12935
 
+2.     Capability Identifier . . . . . . . . . . . . . . . . . . . .   3
12936
 
+
12937
 
+3.     Actions . . . . . . . . . . . . . . . . . . . . . . . . . . .   3
12938
 
+3.1.   Notify action . . . . . . . . . . . . . . . . . . . . . . . .   3
12939
 
+3.2.   Denotify Action . . . . . . . . . . . . . . . . . . . . . . .   5
12940
 
+
12941
 
+4.     Interaction with Other Sieve Actions  . . . . . . . . . . . .   6
12942
 
+
12943
 
+5.     Security Considerations . . . . . . . . . . . . . . . . . . .   7
12944
 
+
12945
 
+6.     Acknowledgments . . . . . . . . . . . . . . . . . . . . . . .   7
12946
 
+
12947
 
+7.     Copyright . . . . . . . . . . . . . . . . . . . . . . . . . .   7
12948
 
+
12949
 
+8.     References  . . . . . . . . . . . . . . . . . . . . . . . . .   8
12950
 
+
12951
 
+9.     Author's Addresses  . . . . . . . . . . . . . . . . . . . . .   8
12952
 
+
12953
 
+
12954
 
+
12955
 
+
12956
 
+
12957
 
+
12958
 
+
12959
 
+
12960
 
+
12961
 
+
12962
 
+
12963
 
+
12964
 
+
12965
 
+
12966
 
+
12967
 
+
12968
 
+
12969
 
+
12970
 
+
12971
 
+
12972
 
+
12973
 
+
12974
 
+
12975
 
+Expires December 6, 2001        Martin                          [Page 2]
12976
 
+
12977
 
+Internet Draft      Sieve -- Notifications extension        June 1, 2001
12978
 
+
12979
 
+
12980
 
+1.  Introduction
12981
 
+
12982
 
+    This is an extension to the Sieve language defined by [SIEVE] for
12983
 
+    providing instant notifications of sieve actions that have been
12984
 
+    preformed. It defines the new action "notify".
12985
 
+
12986
 
+    This document does not dictate the notification method used.
12987
 
+    Examples of possible notification methods are Zephyr and ICQ. The
12988
 
+    method shall be site-defined.
12989
 
+
12990
 
+    Sieve interpreters for which notifications are impractical or is not
12991
 
+    possible SHOULD ignore this extension.
12992
 
+
12993
 
+    Conventions for notations are as in [SIEVE] section 1.1, including
12994
 
+    use of [KEYWORDS].
12995
 
+
12996
 
+
12997
 
+1.1.  Conventions Used in This Document
12998
 
+    The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
12999
 
+    "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
13000
 
+    document are to be interpreted as described in [KEYWORDS].
13001
 
+
13002
 
+
13003
 
+
13004
 
+2.  Capability Identifier
13005
 
+
13006
 
+    The capability string associated with the extension defined in this
13007
 
+    document is "notify".
13008
 
+
13009
 
+
13010
 
+
13011
 
+3.  Actions
13012
 
+
13013
 
+
13014
 
+
13015
 
+
13016
 
+3.1.  Notify action
13017
 
+
13018
 
+    Syntax:   notify [":method" string]
13019
 
+               [":id" string]
13020
 
+               [":options" 1*(string-list / number)]
13021
 
+               [<":low" / ":normal" / ":high">]
13022
 
+               ["message:" string]
13023
 
+
13024
 
+    The Notify action specifies that a notification should be sent to
13025
 
+    the user upon successful handling of this message.
13026
 
+
13027
 
+    The format of the notification is implementation-defined. However,
13028
 
+
13029
 
+
13030
 
+
13031
 
+Expires December 6, 2001        Martin                          [Page 3]
13032
 
+
13033
 
+Internet Draft      Sieve -- Notifications extension        June 1, 2001
13034
 
+
13035
 
+
13036
 
+    all content specified in the notify action, including Sieve actions
13037
 
+    taken on the message, SHOULD be included. If errors occurred in
13038
 
+    another action they SHOULD be reported in the notification. In
13039
 
+    addition, if the notification method does not provide a timestamp,
13040
 
+    one SHOULD be appended to the notification. Implementations SHOULD
13041
 
+    NOT include extraneous information.
13042
 
+
13043
 
+    The :method tag identifies the notification method that will be
13044
 
+    used. If the :method tag is not specified, the default
13045
 
+    implementation defined notification method MUST be used.  The
13046
 
+    possible values of this will be site-specific.  If a method is
13047
 
+    specified that the implementation does not support, the notification
13048
 
+    MUST be ignored. An implementation treats this as a warning
13049
 
+    condition and execution of the sieve script MUST continue.
13050
 
+
13051
 
+    The :id tag can be used to give the notify action an unique
13052
 
+    identifier. This identifier can be used later in the script to
13053
 
+    cancel the specific notify. The string may have any value and SHOULD
13054
 
+    NOT be included in the notification.
13055
 
+
13056
 
+    The :options tag is used to send parameters to the notification
13057
 
+    method. This might be the phone number for an SMS message or a
13058
 
+    user's ICQ identifier.
13059
 
+
13060
 
+    The priority parameter specifies the importance of the notification.
13061
 
+    The priority parameter has the following values: ":high" (very
13062
 
+    important), ":normal", and ":low" (not very important). If no
13063
 
+    priority is given, a default priority of ":normal" SHOULD be
13064
 
+    assumed. Some notification methods allow users to specify their
13065
 
+    state of activity (for example "busy" or "away from keyboard"). If
13066
 
+    the notification method provides this information it SHOULD be used
13067
 
+    to selectively send notifications.  If, for example, the user marks
13068
 
+    herself as "busy", an implementation SHOULD NOT send a notification
13069
 
+    for a new mailing list message with a priority of :low, however the
13070
 
+    user should be notified of a high priority action.  If the
13071
 
+    notification method allows users to filter messages based upon
13072
 
+    certain parameters in the message, users should be able to filter
13073
 
+    based upon priority. If the notification method does not support
13074
 
+    priority, then this parameter MUST be ignored.
13075
 
+
13076
 
+    The :message tag specifies the message data to be included in the
13077
 
+    notification. The entirety of the string SHOULD be sent but
13078
 
+    implementations MAY shorten the message for technical or aesthetic
13079
 
+    reasons. Message may include the message variables defined below. If
13080
 
+    the message parameter is absent, a default message of "$from$:
13081
 
+    $subject$" will be used.
13082
 
+
13083
 
+         $from$     - the display name or address of the RFC 822 from
13084
 
+
13085
 
+
13086
 
+
13087
 
+Expires December 6, 2001        Martin                          [Page 4]
13088
 
+
13089
 
+Internet Draft      Sieve -- Notifications extension        June 1, 2001
13090
 
+
13091
 
+
13092
 
+         $env-from$ - the address of the RFC 821 from
13093
 
+
13094
 
+         $subject$  - the subject of the message
13095
 
+
13096
 
+         $text$     - the first text/* part
13097
 
+
13098
 
+         $text[n]$  - the first n bytes of the first text/* part
13099
 
+
13100
 
+    If there are errors sending the notification, the Sieve interpreter
13101
 
+    SHOULD ignore the notification and not retry indefinitely.
13102
 
+
13103
 
+    This action MUST NOT cancel the implicit keep.
13104
 
+
13105
 
+    Example:
13106
 
+         require ["notify","fileinto"];
13107
 
+
13108
 
+            if header :contains "from" "boss@example.org" {
13109
 
+                notify :high "This is probably very important";
13110
 
+            }
13111
 
+
13112
 
+            if header :contains "to" "sievemailinglist@example.org" {
13113
 
+                notify :low "[SIEVE] $from$: $subject$";
13114
 
+                fileinto "INBOX.sieve";
13115
 
+            }
13116
 
+
13117
 
+
13118
 
+
13119
 
+
13120
 
+3.2.  Denotify Action
13121
 
+
13122
 
+    Syntax: denotify [MATCH-TYPE string] [<":low" / ":normal" /
13123
 
+    ":high">]
13124
 
+
13125
 
+    The denotify action can be used to cancel a previous notification.
13126
 
+    If the priority, ":low" / ":normal" / ":high", is specified, then
13127
 
+    only cancel those notifications with the specified priority.  If a
13128
 
+    MATCH-TYPE with a string is specified, then only those notifications
13129
 
+    whose :id tag matches the specified string using the match-type
13130
 
+    operator are canceled.  The ascii-casemap comparator MUST be used.
13131
 
+
13132
 
+    If no notifications exist that match the search criteria, then the
13133
 
+    denotify has no effect.  A denotify only cancels notifications that
13134
 
+    have already been requested.  It is not possible to preemptively
13135
 
+    cancel a notification.
13136
 
+
13137
 
+    The sequence:
13138
 
+
13139
 
+      denotify;
13140
 
+
13141
 
+
13142
 
+
13143
 
+Expires December 6, 2001        Martin                          [Page 5]
13144
 
+
13145
 
+Internet Draft      Sieve -- Notifications extension        June 1, 2001
13146
 
+
13147
 
+
13148
 
+      notify;
13149
 
+
13150
 
+    will still generate a notification.  The denotify does not cancel
13151
 
+    the notify.
13152
 
+
13153
 
+    The following table shows which notifies would get cancelled:
13154
 
+
13155
 
+                                        # what is cancelled
13156
 
+      denotify                          # all notifications
13157
 
+      denotify :matches "*"             # all notifications with :id tag
13158
 
+      denotify :high                    # all high priority notifications
13159
 
+      denotify :is "foobar"             # all notifications with id "foobar"
13160
 
+      denotify :matches "foo*" :normal  # all normal priority notifications
13161
 
+                                        #   with id that starts with "foo"
13162
 
+
13163
 
+    Example:
13164
 
+             require "notify";
13165
 
+
13166
 
+             notify :method "sms" :options "408-555-1212" :id "foobar";
13167
 
+             if header :contains "from" "boss@example.org" {
13168
 
+                notify :method "sms" :options "408-555-1212" :id "foobar" :high
13169
 
+                       :message "BOSS: $subject$";
13170
 
+             }
13171
 
+
13172
 
+             if header :contains "to" "sievemailinglist@example.org" {
13173
 
+                denotify :is "foobar";
13174
 
+             }
13175
 
+
13176
 
+             if header :contains "subject" "FYI:" {
13177
 
+                # don't need high priority notification for
13178
 
+                # a 'for your information'
13179
 
+                denotify :is "foobar" :high;
13180
 
+             }
13181
 
+
13182
 
+
13183
 
+
13184
 
+
13185
 
+4.  Interaction with Other Sieve Actions
13186
 
+
13187
 
+    Notifications MUST be sent in all cases, unless a reject action is
13188
 
+    also executed. Users may wish to be notified of a message being
13189
 
+    discarded, for example. The reject action is given an exception
13190
 
+    because implementations may wish to restrict users from seeing the
13191
 
+    contents of a rejected message. However, notifications MAY be
13192
 
+    modified to not include any data from the original rejected message.
13193
 
+
13194
 
+    The notify action MUST NOT cancel the implicit keep.
13195
 
+
13196
 
+
13197
 
+
13198
 
+
13199
 
+Expires December 6, 2001        Martin                          [Page 6]
13200
 
+
13201
 
+Internet Draft      Sieve -- Notifications extension        June 1, 2001
13202
 
+
13203
 
+
13204
 
+    The denotify action MUST NOT affect any actions other than the
13205
 
+    notify action.
13206
 
+
13207
 
+    Failures of other actions MAY be reported in the notification.
13208
 
+
13209
 
+
13210
 
+
13211
 
+
13212
 
+
13213
 
+5.  Security Considerations
13214
 
+
13215
 
+    Security considerations are discussed in [SIEVE]. Additionally
13216
 
+    implementations must be careful to follow the security
13217
 
+    considerations of the specific notification methods. It is believed
13218
 
+    that this extension does not introduce any additional security
13219
 
+    concerns.
13220
 
+
13221
 
+    The notify action is potentially very dangerous.  The path the
13222
 
+    notification takes through the network may not be secure.  An error
13223
 
+    in the options string may cause the message to be transmitted to
13224
 
+    someone it was not intended for.
13225
 
+
13226
 
+    Just because a notification is received doesn't mean it was sent by
13227
 
+    the sieve implementation.  It might be possible to forge
13228
 
+    notifications with some notification methods.
13229
 
+
13230
 
+
13231
 
+6.  Acknowledgments
13232
 
+
13233
 
+    Thanks to Larry Greenfield, Sarah Robeson, Tim Showalter, and Barry
13234
 
+    Leiba for help with this document.
13235
 
+
13236
 
+
13237
 
+
13238
 
+7.  Copyright
13239
 
+
13240
 
+    Copyright (C) The Internet Society 1999. All Rights Reserved.
13241
 
+
13242
 
+    This document and translations of it may be copied and furnished to
13243
 
+    others, and derivative works that comment on or otherwise explain it
13244
 
+    or assist in its implementation may be prepared, copied, published
13245
 
+    and distributed, in whole or in part, without restriction of any
13246
 
+    kind, provided that the above copyright notice and this paragraph
13247
 
+    are included on all such copies and derivative works.  However, this
13248
 
+    document itself may not be modified in any way, such as by removing
13249
 
+    the copyright notice or references to the Internet Society or other
13250
 
+    Internet organizations, except as needed for the purpose of
13251
 
+    developing Internet standards in which case the procedures for
13252
 
+
13253
 
+
13254
 
+
13255
 
+Expires December 6, 2001        Martin                          [Page 7]
13256
 
+
13257
 
+Internet Draft      Sieve -- Notifications extension        June 1, 2001
13258
 
+
13259
 
+
13260
 
+    copyrights defined in the Internet Standards process must be
13261
 
+    followed, or as required to translate it into languages other than
13262
 
+    English.
13263
 
+
13264
 
+    The limited permissions granted above are perpetual and will not be
13265
 
+    revoked by the Internet Society or its successors or assigns.
13266
 
+
13267
 
+    This document and the information contained herein is provided on an
13268
 
+    "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
13269
 
+    TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
13270
 
+    BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
13271
 
+    HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
13272
 
+    MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
13273
 
+
13274
 
+
13275
 
+8.  References
13276
 
+
13277
 
+    [ABNF] Crocker, Overell, "Augmented BNF for Syntax Specifications:
13278
 
+    ABNF", RFC 2234, Internet Mail Consortium, Demon Internet Ltd,
13279
 
+    November 1997.
13280
 
+
13281
 
+    [SIEVE]; Showalter, T.; "Sieve: A Mail Filtering Language"; RFC
13282
 
+    3028; Mirapoint, Inc.; January 2001
13283
 
+
13284
 
+
13285
 
+9.  Author's Addresses
13286
 
+
13287
 
+    Tim Martin
13288
 
+    Mirapoint Inc.
13289
 
+    909 Hermosa Court
13290
 
+    Sunnyvale, CA 94085
13291
 
+
13292
 
+    Phone: (408) 720-3835
13293
 
+    EMail: tmartin@mirapoint.com
13294
 
+
13295
 
+    Wolfgang Segmuller
13296
 
+    IBM T.J. Watson Research Center
13297
 
+    30 Saw Mill River Rd
13298
 
+    Hawthorne, NY  10532
13299
 
+
13300
 
+    Phone: (914) 784-7408
13301
 
+    Email: whs@watson.ibm.com
13302
 
+
13303
 
+
13304
 
+
13305
 
+
13306
 
+
13307
 
+
13308
 
+
13309
 
+
13310
 
+
13311
 
+Expires December 6, 2001        Martin                          [Page 8]
13312
 
+
13313
 
diff -urN dovecot-1.2.4/dovecot-libsieve/doc/rfc/deprecated/draft-melnikov-sieve-imapflags-03.txt dovecot-1.2.4.debian/dovecot-libsieve/doc/rfc/deprecated/draft-melnikov-sieve-imapflags-03.txt
13314
 
--- dovecot-1.2.4/dovecot-libsieve/doc/rfc/deprecated/draft-melnikov-sieve-imapflags-03.txt     1970-01-01 01:00:00.000000000 +0100
13315
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/doc/rfc/deprecated/draft-melnikov-sieve-imapflags-03.txt      2000-07-24 17:42:00.000000000 +0200
13316
 
@@ -0,0 +1,426 @@
13317
 
+Network Working Group                                       
13318
 
+Internet Draft: Sieve -- IMAP flag Extension                 A. Melnikov
13319
 
+Document: draft-melnikov-sieve-imapflags-03.txt   Messaging Direct, Ltd.
13320
 
+Expires: January 2001                                          July 2000
13321
 
+
13322
 
+
13323
 
+                      Sieve -- IMAP flag Extension
13324
 
+
13325
 
+
13326
 
+Status of this memo
13327
 
+
13328
 
+   This document is an Internet-Draft and is in full conformance with
13329
 
+   all provisions of Section 10 of RFC2026.  Internet-Drafts are
13330
 
+   working documents of the Internet Engineering Task Force (IETF), its
13331
 
+   areas, and its working groups.  Note that other groups may also
13332
 
+   distribute working documents as Internet-Drafts.
13333
 
+
13334
 
+   Internet-Drafts are draft documents valid for a maximum of six
13335
 
+   months and may be updated, replaced, or obsoleted by other documents
13336
 
+   at any time.  It is inappropriate to use Internet- Drafts as
13337
 
+   reference material or to cite them other than as "work in progress."
13338
 
+
13339
 
+  
13340
 
+     The list of current Internet-Drafts can be accessed at
13341
 
+     http://www.ietf.org/ietf/1id-abstracts.txt
13342
 
+
13343
 
+     The list of Internet-Draft Shadow Directories can be accessed at
13344
 
+     http://www.ietf.org/shadow.html.
13345
 
+
13346
 
+   The protocol discussed in this document is experimental and subject
13347
 
+   to change.  Persons planning on either implementing or  using  this
13348
 
+   protocol  are STRONGLY URGED to get in touch with the author before
13349
 
+   embarking on such a project.
13350
 
+
13351
 
+Copyright
13352
 
+
13353
 
+   Copyright (C) The Internet Society 2000.  All Rights Reserved.
13354
 
+
13355
 
+Abstract
13356
 
+
13357
 
+   Recent discussions   have  shown  that  it  is  desirable  to  set
13358
 
+   different [IMAP] flags on message delivery.  This can be done, for
13359
 
+   example, by a SIEVE interpreter that works as a part of a Mail Delivery
13360
 
+   Agent.
13361
 
+
13362
 
+   This document describes an extension to the  Sieve  mail  filtering
13363
 
+   language for setting [IMAP] flags. The extension allows to set both 
13364
 
+   [IMAP] system flags and [IMAP] keywords.
13365
 
+
13366
 
+
13367
 
+0. Meta-information on this draft
13368
 
+
13369
 
+   This information  is intended to facilitate discussion.  It will be
13370
 
+   removed when this document leaves the Internet-Draft stage.
13371
 
+
13372
 
+
13373
 
+0.1. Discussion
13374
 
+
13375
 
+   This draft is intended to be compared with the Sieve mail filtering
13376
 
+   language,  an  Internet-Draft  being  discussed  on the MTA Filters
13377
 
+   mailing list at <ietf-mta-filters@imc.org>.  Subscription  requests
13378
 
+   can  be  sent  to <ietf-mta-filters-request@imc.org> (send an email
13379
 
+   message with the word "subscribe" in the body). More information on
13380
 
+   the  mailing  list  along  with  a  WWW archive of back messages is
13381
 
+   available at <http://www.imc.org/ietf-mta-filters/>.
13382
 
+
13383
 
+
13384
 
+0.2. Changes from the version submitted to the SIEVE mailing list
13385
 
+
13386
 
+   1. Added addflag and removeflag actions
13387
 
+
13388
 
+   2. Changed the semantics of setflag (setflag is not additive any more)
13389
 
+
13390
 
+   3. Corrected   section  "Interaction  with  Other  Sieve  Actions".
13391
 
+      Removed incorrect reference to  the  forward  action  as  to  an
13392
 
+      action that prohibits setflag.
13393
 
+
13394
 
+   4. Added  paragraph  about  the  mutual  order of fileinto/keep and
13395
 
+      setflag/addflag/removeflag actions.
13396
 
+
13397
 
+
13398
 
+0.3. Changes from the revision 00
13399
 
+
13400
 
+   1. Corrected Capability Identifier section (Section 2)
13401
 
+
13402
 
+   2. Corrected "Interaction with Other Sieve Actions" section (Section 4)
13403
 
+
13404
 
+   3. Examples were updated to be compatible with Sieve-07 draft
13405
 
+
13406
 
+   4. Added "mark" and "unmark" actions
13407
 
+
13408
 
+
13409
 
+0.4. Changes from the revision 01
13410
 
+
13411
 
+   1. Some language fixes based on Tony Hansen comments
13412
 
+
13413
 
+   2. Clarified that the extension allows to set both IMAP System Flags and Keywords
13414
 
+
13415
 
+
13416
 
+0.5. Changes from the revision 02
13417
 
+
13418
 
+   1. BugFix: all backslashes must be escaped
13419
 
+
13420
 
+   2. Added extended example and more detailed description of addflag/removeflag additivity.
13421
 
+
13422
 
+   3. Minor example bugfixes
13423
 
+
13424
 
+
13425
 
+1. Introduction
13426
 
+
13427
 
+   This is  an  extension to the Sieve language defined by [SIEVE] for
13428
 
+   setting [IMAP] flags.  It defines several  new  actions  "setflag",
13429
 
+   "addflag", "removeflag", "mark" and "unmark".
13430
 
+
13431
 
+   This document  doesn't dictate how the SIEVE interpreter will set the [IMAP]
13432
 
+   flags. In particular, the SIEVE interpreter may work as an IMAP client,
13433
 
+   or may have direct access to the mailstore.
13434
 
+
13435
 
+   SIEVE interpreters  that  don't  support  integration  with IMAP
13436
 
+   SHOULD ignore this extension.
13437
 
+
13438
 
+   Conventions for notations are as in [SIEVE] section 1.1,  including
13439
 
+   use of [KEYWORDS].
13440
 
+
13441
 
+
13442
 
+2. Capability Identifier
13443
 
+
13444
 
+   The capability string associated with extension defined in this document
13445
 
+   is "imapflags".
13446
 
+
13447
 
+
13448
 
+3. Actions
13449
 
+
13450
 
+   All actions described in this specification (setflag, addflag, removeflag,
13451
 
+   mark, unmark) operate on an internal variable that contains the set of [IMAP] flags
13452
 
+   associated with the message being delivered. When the interpreter starts executing
13453
 
+   a script this variable contains an empty set. The 'addflag' action adds flags
13454
 
+   to the existing set. The 'removeflag' action removes flags from the existing set. 
13455
 
+   The 'setflag' action replaces the existing set of flags with a new set. 
13456
 
+   Whenever the interpreter encounters a 'fileinto' or 'keep' action it files
13457
 
+   the message with the current set of flags.
13458
 
+
13459
 
+
13460
 
+3.1. Setflag Action
13461
 
+
13462
 
+   Syntax:   setflag <list-of-flags>
13463
 
+
13464
 
+   Setflag is used for setting  [IMAP]  system flags or keywords. Setflag
13465
 
+   replaces  any previously  set  flags.  It  should  be  used together with keep
13466
 
+   or fileinto.  It MUST be ignored  if  mailstore or target mailbox doesn't
13467
 
+   support  the storing of any flags.
13468
 
+
13469
 
+   Flags can  be  set  only for the message that is currently being processed by
13470
 
+   SIEVE.  When called with keep,  setflag sets flags in  the user's  main
13471
 
+   mailbox.  When  called  with  fileinto,  setflag  sets flags in the
13472
 
+   mailbox indicated by the parameter.
13473
 
+
13474
 
+   The order of setflag/fileinto or setflag/keep is important  in  the
13475
 
+   script. Any setflag action applies only to subsequent fileinto/keep
13476
 
+   actions in a script till next occurence of setflag/addflag/removeflag/mark/unmark.
13477
 
+
13478
 
+   Server MUST ignore all flags that it can't store permanently.  This
13479
 
+   means,  in  particular,  that if the user's main mailbox can't store any
13480
 
+   flags, then the following SIEVE script produces no actions
13481
 
+
13482
 
+      Example:  if size :over 500K {
13483
 
+                    setflag "\\Deleted";
13484
 
+                }
13485
 
+
13486
 
+   A more substantial example is:
13487
 
+
13488
 
+      Example:
13489
 
+        if header :contains "from" "boss@frobnitzm.edu" {
13490
 
+          setflag "\\Flagged";
13491
 
+          fileinto "INBOX.From Boss";
13492
 
+        }
13493
 
+
13494
 
+
13495
 
+3.2. Addflag action
13496
 
+
13497
 
+   Syntax:   addflag <list-of-flags>
13498
 
+
13499
 
+   Addflag is used for setting [IMAP] flags. However unlike setflag it
13500
 
+   doesn't replace any previously set flags.  This means that multiple
13501
 
+   occurrences of addflag are treated additively.
13502
 
+
13503
 
+   For example, the following two actions
13504
 
+
13505
 
+      addflag "\\Deleted";
13506
 
+      addflag "\\Answered";
13507
 
+
13508
 
+   produce the same result as the single action
13509
 
+
13510
 
+      addflag ["\\Deleted", "\\Answered"];
13511
 
+
13512
 
+   In all other  respects  addflag  behaves  the  same  way  as
13513
 
+   setflag.
13514
 
+
13515
 
+
13516
 
+3.3. Removeflag Action
13517
 
+
13518
 
+   Syntax:   removeflag <list-of-flags>
13519
 
+
13520
 
+   Removeflag is used for  setting  [IMAP]  flags.  Removeflag  clears
13521
 
+   flags previously set by setflag/addflag.  Calling removeflag with a
13522
 
+   flag that wasn't set before is not an error and is ignored.
13523
 
+   Multiple occurrences of removeflag are treated additively.
13524
 
+
13525
 
+   In all other respects removeflag behaves  the  same  way  as
13526
 
+   setflag.
13527
 
+
13528
 
+      Example:
13529
 
+        if header :contains "Disposition-Notification-To" "mel@example.com" {
13530
 
+          addflag "$MDNRequired";
13531
 
+        }
13532
 
+        if header :contains "from" "imap@cac.washington.edu" {
13533
 
+          removeflag "$MDNRequired";
13534
 
+          fileinto "INBOX.imap-list";
13535
 
+        }
13536
 
+
13537
 
+
13538
 
+3.4. Mark and Unmark Actions
13539
 
+
13540
 
+   Syntax:   mark
13541
 
+
13542
 
+   Syntax:   unmark
13543
 
+
13544
 
+   The mark action allows a message to be marked as urgent. Implementers are free
13545
 
+   to choose any flag or any  combination  of  [IMAP] flags,  however  it  is
13546
 
+   RECOMMENDED  that  the [IMAP]  \Flagged  flag be  used.  The mark  action is
13547
 
+   semantically equivalent to 'addflag "\\Flagged"'.
13548
 
+
13549
 
+   The unmark action allows the flag previously  set  by  the Mark
13550
 
+   action to be unset. Unmark SHOULD at least clear the [IMAP] \Flagged flag
13551
 
+   and MUST clear all flags that could be added with mark.
13552
 
+   Unmark MAY clear other flags as well.  The unmark action is semantically
13553
 
+   equivalent to 'removeflag "\\Flagged"'.
13554
 
+
13555
 
+
13556
 
+3.5 Extended example
13557
 
+
13558
 
+   #
13559
 
+   # Example Sieve Filter
13560
 
+   # Declare any optional features or extension used by the script
13561
 
+   #
13562
 
+   require ["fileinto", "reject", "imapflags"];
13563
 
+
13564
 
+   #
13565
 
+   # Reject any large messages
13566
 
+   #
13567
 
+   if size :over 1M
13568
 
+           {
13569
 
+           if header :is "From" "boss@company.com"
13570
 
+                      {
13571
 
+                      addflag "\\Flagged $Big";
13572
 
+   # The message will be marked as "\Flagged $Big" when filed into mailbox "Big messages"
13573
 
+                      }
13574
 
+           fileinto "Big messages";
13575
 
+           }
13576
 
+
13577
 
+   if header :is "From" "grandma@example.net"
13578
 
+           {
13579
 
+           addflag ["\\Answered", "$MDNSent"];
13580
 
+   # If the message is bigger than 1Mb it will be marked as "\Flagged $Big \Answered $MDNSent" 
13581
 
+   # when filed into mailbox "grandma". If the message is shorter than 1Mb it will be marked as
13582
 
+   # "\Answered $MDNSent"
13583
 
+           fileinto "GrandMa";  # move to "GrandMa" folder
13584
 
+           }
13585
 
+
13586
 
+   #
13587
 
+   # Handle messages from known mailing lists
13588
 
+   # Move messages from IETF filter discussion list to filter folder
13589
 
+   #
13590
 
+   if header :is "Sender" "owner-ietf-mta-filters@imc.org"
13591
 
+           {
13592
 
+           setflag "\\Flagged";
13593
 
+   # Message will always have just "\Flagged" flag
13594
 
+           keep;
13595
 
+           }
13596
 
+
13597
 
+   #
13598
 
+   # Keep all messages to or from people in my company
13599
 
+   #
13600
 
+   elsif anyof address :domain :is ["From", "To"] "company.com"
13601
 
+           {
13602
 
+           keep;               # keep in "In" folder
13603
 
+           }
13604
 
+   #
13605
 
+   # Try and catch unsolicited email.  If a message is not to me,
13606
 
+   # or it contains a subject known to be spam, file it away.
13607
 
+   #
13608
 
+   elsif anyof (not address :all :contains
13609
 
+                  ["To", "Cc", "Bcc"] "me@company.com",
13610
 
+                header :matches "subject"
13611
 
+                  ["*make*money*fast*", "*university*dipl*mas*"])
13612
 
+           {
13613
 
+           removeflag "\\Flagged";
13614
 
+           # If message header does not contain my address,
13615
 
+           # it's from a list.
13616
 
+           fileinto "spam";   # move to "spam" folder
13617
 
+           }
13618
 
+   else
13619
 
+           {
13620
 
+           # Move all other (non-company) mail to "personal"
13621
 
+           # folder.
13622
 
+           fileinto "personal";
13623
 
+           }
13624
 
+
13625
 
+
13626
 
+
13627
 
+4. Interaction with Other Sieve Actions
13628
 
+
13629
 
+   Sieve actions sometimes  prohibit  each  other  in  order  to  make
13630
 
+   filtering scripts less likely to cause serious problems.
13631
 
+
13632
 
+   It is   strongly   discouraged  to  use setflag/addflag/removeflag/mark/unmark
13633
 
+   actions together with reject,  because  that  action doesn't allow keeping  a
13634
 
+   received message.
13635
 
+
13636
 
+   The SIEVE interpreter  MUST  ignore any setflag/addflag/removeflag/mark/unmark
13637
 
+   commands when they are used  with  reject. The SIEVE interpreter MUST ignore these
13638
 
+   commands when no keep (implicit or explicit) or fileinto actions will be taken.
13639
 
+
13640
 
+   A SIEVE verifier SHOULD reject a script that contains a
13641
 
+   setflag/addflag/removeflag/mark/unmark action together with  reject.
13642
 
+
13643
 
+
13644
 
+5. Other Considerations
13645
 
+
13646
 
+   This extension intentionally doesn't allow setting [IMAP] flags  on an
13647
 
+   arbitrary message in the [IMAP] message store.
13648
 
+
13649
 
+
13650
 
+6. Security Considerations
13651
 
+
13652
 
+   Security considerations are discussed in the [IMAP] and [SIEVE].
13653
 
+   It is belived that this  extension  doesn't  introduce any
13654
 
+   additional security concerns.
13655
 
+
13656
 
+
13657
 
+7. Formal Grammar
13658
 
+
13659
 
+   The grammar used in this section is the same as the ABNF described in
13660
 
+   [ABNF].
13661
 
+
13662
 
+   action =/ setflag / addflag / removeflag / mark / unmark
13663
 
+
13664
 
+   setflag = "setflag" WSP string-list
13665
 
+     ;; a list of [IMAP] flags
13666
 
+
13667
 
+   addflag = "addflag" WSP string-list
13668
 
+     ;; a list of [IMAP] flags
13669
 
+
13670
 
+   removeflag = "removeflag" WSP string-list
13671
 
+     ;; a list of [IMAP] flags
13672
 
+
13673
 
+   mark = "mark"
13674
 
+
13675
 
+   unmark = "unmark"
13676
 
+
13677
 
+
13678
 
+8.  Acknowledgments
13679
 
+
13680
 
+    This document has been revised in part based on comments and
13681
 
+    discussions which took place on and off the SIEVE mailing list.
13682
 
+    The help of those who took the time to review the draft and make
13683
 
+    suggestions is appreciated, especially that of Tim Showalter,
13684
 
+    Barry Leiba, and Randall Gellens. Special thanks to Tony Hansen,
13685
 
+    David Lamb and Roman Migal for helping me explain better the concept.
13686
 
+
13687
 
+
13688
 
+9. Author's Address
13689
 
+
13690
 
+    Alexey Melnikov
13691
 
+    Messaging Direct, Ltd.
13692
 
+
13693
 
+    Address : #900, 10117 Jasper Avenue, Edmonton, Alberta, Canada,
13694
 
+    T5J1W8
13695
 
+
13696
 
+    Email: mel@messagingdirect.com
13697
 
+
13698
 
+
13699
 
+Appendices
13700
 
+
13701
 
+Appendix A.  References
13702
 
+
13703
 
+   [SIEVE] Showalter, T.,  "Sieve: A Mail Filtering Language", Mirapoint,
13704
 
+   Work in Progress, draft-showalter-sieve-XX.txt
13705
 
+
13706
 
+   [ABNF] Crocker, D.,  "Augmented BNF for Syntax Specifications: ABNF",
13707
 
+   Internet Mail Consortium, RFC 2234, November, 1997.
13708
 
+
13709
 
+   [KEYWORDS] Bradner, S., "Key  words  for  use  in  RFCs  to  Indicate
13710
 
+   Requirement Levels", Harvard University, RFC 2119, March 1997.
13711
 
+
13712
 
+   [IMAP] Crispin, M., "INTERNET MESSAGE ACCESS PROTOCOL - VERSION 4rev1",
13713
 
+   University of Washington, RFC 2060, December 1996.
13714
 
+
13715
 
+
13716
 
+Appendix B. Full Copyright Statement
13717
 
+
13718
 
+    Copyright (C) The Internet Society 2000. All Rights Reserved.
13719
 
+
13720
 
+    This document and translations of it may be copied and furnished to
13721
 
+    others, and derivative works that comment on or otherwise explain it
13722
 
+    or assist in its implementation may be prepared, copied, published
13723
 
+    and distributed, in whole or in part, without restriction of any
13724
 
+    kind, provided that the above copyright notice and this paragraph
13725
 
+    are included on all such copies and derivative works.  However, this
13726
 
+    document itself may not be modified in any way, such as by removing
13727
 
+    the copyright notice or references to the Internet Society or other
13728
 
+    Internet organizations, except as needed for the purpose of
13729
 
+    developing Internet standards in which case the procedures for
13730
 
+    copyrights defined in the Internet Standards process must be
13731
 
+    followed, or as required to translate it into languages other than
13732
 
+    English.
13733
 
+
13734
 
+    The limited permissions granted above are perpetual and will not be
13735
 
+    revoked by the Internet Society or its successors or assigns.
13736
 
+
13737
 
+    This document and the information contained herein is provided on an
13738
 
+    "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
13739
 
+    TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
13740
 
+    BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
13741
 
+    HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
13742
 
+    MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
13743
 
diff -urN dovecot-1.2.4/dovecot-libsieve/doc/rfc/draft-degener-sieve-multiscript-00.txt dovecot-1.2.4.debian/dovecot-libsieve/doc/rfc/draft-degener-sieve-multiscript-00.txt
13744
 
--- dovecot-1.2.4/dovecot-libsieve/doc/rfc/draft-degener-sieve-multiscript-00.txt       1970-01-01 01:00:00.000000000 +0100
13745
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/doc/rfc/draft-degener-sieve-multiscript-00.txt        2009-01-21 23:50:10.000000000 +0100
13746
 
@@ -0,0 +1,244 @@
13747
 
+Network Working Group                                       Jutta Degener
13748
 
+Internet Draft                                               Rand Wacker
13749
 
+Expires: October 2003                                          April 2003
13750
 
+
13751
 
+
13752
 
+              Sieve -- Sequential Execution of Multiple Scripts
13753
 
+                 <draft-degener-sieve-multiscript-00.txt>
13754
 
+
13755
 
+
13756
 
+Status of this memo
13757
 
+
13758
 
+   This document is an Internet-Draft and is subject to all
13759
 
+   provisions of Section 10 of RFC2026.
13760
 
+
13761
 
+   Internet-Drafts are working documents of the Internet Engineering
13762
 
+   Task Force (IETF), its areas, and its working groups.  Note that
13763
 
+   other groups may also distribute working documents as
13764
 
+   Internet-Drafts.
13765
 
+
13766
 
+   Internet-Drafts are draft documents valid for a maximum of six
13767
 
+   months and may be updated, replaced, or obsoleted by other
13768
 
+   documents at any time.  It is inappropriate to use Internet-
13769
 
+   Drafts as reference material or to cite them other than as
13770
 
+   "work in progress."
13771
 
+
13772
 
+   The list of current Internet-Drafts can be accessed at
13773
 
+   http://www.ietf.org/1id-abstracts.html
13774
 
+
13775
 
+   The list of Internet-Draft Shadow Directories can be accessed at
13776
 
+   http://www.ietf.org/shadow.html
13777
 
+
13778
 
+
13779
 
+Abstract
13780
 
+
13781
 
+   This document defines sieve behavior relevant when multiple
13782
 
+   scripts are executed sequentially on the same message.
13783
 
+
13784
 
+
13785
 
+1. Introduction
13786
 
+
13787
 
+   E-mail messages frequently are processed by multiple agents
13788
 
+   that implement nested layers of corporate policies.
13789
 
+
13790
 
+   For example, a provider may offer access to services that
13791
 
+   perform spam- and virus filtering; a single corporation
13792
 
+   may restrict e-mail to certain subdomains, or filter for
13793
 
+   keywords; individual divisions within a corporation may
13794
 
+   implement even more intrusive handling of e-mail messages,
13795
 
+   for example by keeping a copy of all correspondence.
13796
 
+   Amidst all of this, of course, users may still use sieve
13797
 
+   filters to presort, redirect, or notify other accounts
13798
 
+   as in the classic sieve use scenario.
13799
 
+
13800
 
+   In this context, it is desirable to specify an execution
13801
 
+   model for sieve scripts when executed in series.  This
13802
 
+   allows each layer of the mail filtering hierarchy to use
13803
 
+   a separate sieve script to express its policies.
13804
 
+
13805
 
+
13806
 
+2. Conventions used.
13807
 
+
13808
 
+   Conventions for notations are as in [SIEVE] section 1.1, including
13809
 
+   use of [KEYWORDS] and "Syntax:" label for the definition of action
13810
 
+   and tagged arguments syntax.
13811
 
+
13812
 
+   This document defines no sieve extensions and no capability string.
13813
 
+
13814
 
+
13815
 
+3. Sequential Script Execution Model
13816
 
+
13817
 
+   When multiple scripts are executed for a message, they
13818
 
+   are executed in a specific order.
13819
 
+
13820
 
+   Within this order, this document defines that trailing
13821
 
+   scripts will be executed as long as the message is being
13822
 
+   "kept", that is, as long as either an implicit or explicit
13823
 
+   "keep" is in effect.
13824
 
+
13825
 
+   In other words, for every script but the last, "keep"
13826
 
+   doesn't mean "file this message into INBOX", it means
13827
 
+   "process this message with the next sieve script."
13828
 
+
13829
 
+
13830
 
+4. Locality of script actions
13831
 
+
13832
 
+   This document strongly limits the effects of scripts
13833
 
+   on each other.
13834
 
+
13835
 
+   The "require" clauses at the beginning of a script
13836
 
+   only apply to this particular script, not to following
13837
 
+   ones.   Different stages in the script processing
13838
 
+   may support different "require" areas.  For example,
13839
 
+   it is conceivable that "fileinto" is not supported
13840
 
+   for a stage other than a user's private script.
13841
 
+
13842
 
+   The "stop;" command ends the execution of its single
13843
 
+   containing script, not of scripts in general.
13844
 
+
13845
 
+   After one script terminates, the next script is executed
13846
 
+   if an implicit or explicit "keep" is in effect.
13847
 
+   (To end all script execution, a script should execute
13848
 
+   "discard; stop;".)
13849
 
+
13850
 
+   For sieve engines that implement the "variables" extension,
13851
 
+   variable state is not carried over between scripts.
13852
 
+
13853
 
+   For sieve engines that implement the "notify" extension,
13854
 
+   the "denotify" action in one script can only cancel
13855
 
+   "notify" actions from that same script.
13856
 
+
13857
 
+   However, if a sequence of script executions results in
13858
 
+   the same message sent to the same recipient, or filed to
13859
 
+   the same destination folder, more than once, an implementation
13860
 
+   MAY only produce a single message, even if the commands
13861
 
+   executed stem from multiple scripts.
13862
 
+
13863
 
+   If a sieve implementation enforces the incompatibility
13864
 
+   of "reject" with other actions (a SHOULD in [SIEVE]),
13865
 
+   it MUST only enforce it within one script; an action
13866
 
+   in a preceding script MUST be compatible with a "reject"
13867
 
+   in a later script.
13868
 
+
13869
 
+
13870
 
+5. Script Errors
13871
 
+
13872
 
+   When an error occurs during processing of any of the
13873
 
+   scripts, all message processing stops, and the message
13874
 
+   is treated as if the final script had executed a "keep;".
13875
 
+
13876
 
+
13877
 
+6. Security Considerations
13878
 
+
13879
 
+   A script executed before another script can prevent the
13880
 
+   trailing script from running (by executing "discard; stop;"
13881
 
+   or by encountering an error.)  This is deliberate.
13882
 
+
13883
 
+   Corporate filtering of employee e-mail may violate the
13884
 
+   privacy expectations of employees.  However, since these
13885
 
+   instances are the ones running the software that handles
13886
 
+   employee e-mail to begin with, they already have the
13887
 
+   technical capability to do this.
13888
 
+
13889
 
+
13890
 
+7. Acknowledgments
13891
 
+
13892
 
+   Thanks to Eric Allman, Will Lee, Dowson Tong, and Chris Markle for comments.
13893
 
+
13894
 
+
13895
 
+8. Authors' Addresses
13896
 
+
13897
 
+   Jutta Degener
13898
 
+   Sendmail, Inc.
13899
 
+   6425 Christie Ave, 4th Floor
13900
 
+   Emeryville, CA 94608
13901
 
+   Email: jutta@sendmail.com
13902
 
+
13903
 
+   Rand Wacker
13904
 
+   Sendmail, Inc.
13905
 
+   6425 Christie Ave, 4th Floor
13906
 
+   Emeryville, CA 94608
13907
 
+   Email: rand@sendmail.com
13908
 
+
13909
 
+
13910
 
+9. Discussion
13911
 
+
13912
 
+   This section will be removed when this document leaves the
13913
 
+   Internet-Draft stage.
13914
 
+
13915
 
+   This draft is intended as an extension to the Sieve mail filtering
13916
 
+   language.  Sieve extensions are discussed on the MTA Filters mailing
13917
 
+   list at <ietf-mta-filters@imc.org>.  Subscription  requests can
13918
 
+   be sent to <ietf-mta-filters-request@imc.org> (send an email
13919
 
+   message with the word "subscribe" in the body).
13920
 
+
13921
 
+   More information on the mailing list along with a WWW archive of
13922
 
+   back messages is available at <http://www.imc.org/ietf-mta-filters/>.
13923
 
+
13924
 
+
13925
 
+9.1 Comparison to draft-daboo-sieve-include-00
13926
 
+
13927
 
+   The "include" sieve extension describes a mechanism for
13928
 
+   naming and combining multiple scripts.  This document doesn't
13929
 
+   do that; how the sequence of scripts to be executed on a
13930
 
+   message is determined is left up to the environment and likely
13931
 
+   out of control of the script owner.
13932
 
+
13933
 
+   The "include" sieve extension creates a hierarchical
13934
 
+   tree of nested scripts; this extension describes sequential,
13935
 
+   not hierarchical execution.
13936
 
+
13937
 
+   The "include" sieve extension defines the semantics of
13938
 
+   "stop" to stop all sieve execution, not just that of the
13939
 
+   innermost containing script.  It adds a new "return" command
13940
 
+   to explicitly end execution of a single script.
13941
 
+   This document specifies that "stop" just stops a single script, 
13942
 
+   and uses the redefined meaning of "keep" to regulate the
13943
 
+   flow of messages through scripts.
13944
 
+
13945
 
+
13946
 
+9.2 "require" keyword
13947
 
+
13948
 
+   This draft started out with a "require" keyword, "multiscript",
13949
 
+   but since what it describes lies outside the domain of strict
13950
 
+   sieve language behavior, I'm not sure it needs one.
13951
 
+
13952
 
+
13953
 
+Appendices
13954
 
+
13955
 
+Appendix A.  References
13956
 
+
13957
 
+   [KEYWORDS]  Bradner, S., "Key words for use in RFCs to Indicate
13958
 
+               Requirement Levels", RFC 2119, March 1997.
13959
 
+
13960
 
+   [SIEVE]     Showalter, T.,  "Sieve: A Mail Filtering Language", RFC 3028,
13961
 
+               January 2001.
13962
 
+
13963
 
+
13964
 
+Appendix B. Full Copyright Statement
13965
 
+
13966
 
+    Copyright (C) The Internet Society 2002,2003. All Rights Reserved.
13967
 
+
13968
 
+    This document and translations of it may be copied and furnished to
13969
 
+    others, and derivative works that comment on or otherwise explain it
13970
 
+    or assist in its implementation may be prepared, copied, published
13971
 
+    and distributed, in whole or in part, without restriction of any
13972
 
+    kind, provided that the above copyright notice and this paragraph
13973
 
+    are included on all such copies and derivative works.  However, this
13974
 
+    document itself may not be modified in any way, such as by removing
13975
 
+    the copyright notice or references to the Internet Society or other
13976
 
+    Internet organizations, except as needed for the purpose of
13977
 
+    developing Internet standards in which case the procedures for
13978
 
+    copyrights defined in the Internet Standards process must be
13979
 
+    followed, or as required to translate it into languages other than
13980
 
+    English.
13981
 
+
13982
 
+    The limited permissions granted above are perpetual and will not be
13983
 
+    revoked by the Internet Society or its successors or assigns.
13984
 
+
13985
 
+    This document and the information contained herein is provided on an
13986
 
+    "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
13987
 
+    TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
13988
 
+    BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
13989
 
+    HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
13990
 
+    MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
13991
 
diff -urN dovecot-1.2.4/dovecot-libsieve/doc/rfc/draft-duerst-mailto-bis-05.txt dovecot-1.2.4.debian/dovecot-libsieve/doc/rfc/draft-duerst-mailto-bis-05.txt
13992
 
--- dovecot-1.2.4/dovecot-libsieve/doc/rfc/draft-duerst-mailto-bis-05.txt       1970-01-01 01:00:00.000000000 +0100
13993
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/doc/rfc/draft-duerst-mailto-bis-05.txt        2008-12-09 17:43:27.000000000 +0100
13994
 
@@ -0,0 +1,1064 @@
13995
 
+
13996
 
+
13997
 
+
13998
 
+Network Working Group                                          M. Duerst
13999
 
+Internet-Draft                                  Aoyama Gakuin University
14000
 
+Obsoletes: 2368 (if approved)                                L. Masinter
14001
 
+Intended status: Standards Track              Adobe Systems Incorporated
14002
 
+Expires: August 28, 2008                                     J. Zawinski
14003
 
+                                                              DNA Lounge
14004
 
+                                                       February 25, 2008
14005
 
+
14006
 
+
14007
 
+                        The 'mailto' URI Scheme
14008
 
+                       draft-duerst-mailto-bis-05
14009
 
+
14010
 
+Status of this Memo
14011
 
+
14012
 
+   By submitting this Internet-Draft, each author represents that any
14013
 
+   applicable patent or other IPR claims of which he or she is aware
14014
 
+   have been or will be disclosed, and any of which he or she becomes
14015
 
+   aware will be disclosed, in accordance with Section 6 of BCP 79.
14016
 
+
14017
 
+   Internet-Drafts are working documents of the Internet Engineering
14018
 
+   Task Force (IETF), its areas, and its working groups.  Note that
14019
 
+   other groups may also distribute working documents as Internet-
14020
 
+   Drafts.
14021
 
+
14022
 
+   Internet-Drafts are draft documents valid for a maximum of six months
14023
 
+   and may be updated, replaced, or obsoleted by other documents at any
14024
 
+   time.  It is inappropriate to use Internet-Drafts as reference
14025
 
+   material or to cite them other than as "work in progress."
14026
 
+
14027
 
+   The list of current Internet-Drafts can be accessed at
14028
 
+   http://www.ietf.org/ietf/1id-abstracts.txt.
14029
 
+
14030
 
+   The list of Internet-Draft Shadow Directories can be accessed at
14031
 
+   http://www.ietf.org/shadow.html.
14032
 
+
14033
 
+   This Internet-Draft will expire on August 28, 2008.
14034
 
+
14035
 
+Copyright Notice
14036
 
+
14037
 
+   Copyright (C) The IETF Trust (2008).
14038
 
+
14039
 
+Abstract
14040
 
+
14041
 
+   This document defines the format of Uniform Resource Identifiers
14042
 
+   (URI) to identify resources that are reached using Internet mail.  It
14043
 
+   adds better internationalization and compatibility with IRIs (RFC
14044
 
+   3987) to the previous syntax of 'mailto' URIs (RFC 2368).
14045
 
+
14046
 
+
14047
 
+
14048
 
+
14049
 
+Duerst, et al.           Expires August 28, 2008                [Page 1]
14050
 
+
14051
 
+Internet-Draft           The 'mailto' URI Scheme           February 2008
14052
 
+
14053
 
+
14054
 
+Table of Contents
14055
 
+
14056
 
+   1.  Introduction . . . . . . . . . . . . . . . . . . . . . . . . .  3
14057
 
+   2.  Syntax of a mailto URI . . . . . . . . . . . . . . . . . . . .  3
14058
 
+   3.  Semantics and Operations . . . . . . . . . . . . . . . . . . .  6
14059
 
+   4.  Unsafe Header Fields . . . . . . . . . . . . . . . . . . . . .  6
14060
 
+   5.  Encoding . . . . . . . . . . . . . . . . . . . . . . . . . . .  7
14061
 
+   6.  Deployment of UTF-8-Based Percent-Encoding . . . . . . . . . .  7
14062
 
+   7.  Examples . . . . . . . . . . . . . . . . . . . . . . . . . . .  8
14063
 
+     7.1.  Examples Conforming to RFC2368 . . . . . . . . . . . . . .  8
14064
 
+     7.2.  Examples of Complicated Email Addresses  . . . . . . . . .  9
14065
 
+     7.3.  Examples Using UTF-8-Based Percent-Encoding  . . . . . . . 10
14066
 
+   8.  Security Considerations  . . . . . . . . . . . . . . . . . . . 11
14067
 
+   9.  IANA Considerations  . . . . . . . . . . . . . . . . . . . . . 12
14068
 
+     9.1.  Registration of the Body Header Field  . . . . . . . . . . 13
14069
 
+   10. Main Changes from RFC 2368 . . . . . . . . . . . . . . . . . . 13
14070
 
+   11. Change Log . . . . . . . . . . . . . . . . . . . . . . . . . . 14
14071
 
+     11.1. Changes between draft 04 and draft 05  . . . . . . . . . . 14
14072
 
+     11.2. Changes between draft 03 and draft 04  . . . . . . . . . . 14
14073
 
+     11.3. Changes between draft 02 and draft 03  . . . . . . . . . . 15
14074
 
+     11.4. Changes between draft 01 and draft 02  . . . . . . . . . . 15
14075
 
+     11.5. Changes between draft 00 and draft 01  . . . . . . . . . . 15
14076
 
+     11.6. Changes from RFC 2368  . . . . . . . . . . . . . . . . . . 16
14077
 
+   12. Acknowledgments  . . . . . . . . . . . . . . . . . . . . . . . 16
14078
 
+   13. References . . . . . . . . . . . . . . . . . . . . . . . . . . 16
14079
 
+     13.1. Normative References . . . . . . . . . . . . . . . . . . . 16
14080
 
+     13.2. Informative References . . . . . . . . . . . . . . . . . . 17
14081
 
+   Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . . 17
14082
 
+   Intellectual Property and Copyright Statements . . . . . . . . . . 19
14083
 
+
14084
 
+
14085
 
+
14086
 
+
14087
 
+
14088
 
+
14089
 
+
14090
 
+
14091
 
+
14092
 
+
14093
 
+
14094
 
+
14095
 
+
14096
 
+
14097
 
+
14098
 
+
14099
 
+
14100
 
+
14101
 
+
14102
 
+
14103
 
+
14104
 
+
14105
 
+Duerst, et al.           Expires August 28, 2008                [Page 2]
14106
 
+
14107
 
+Internet-Draft           The 'mailto' URI Scheme           February 2008
14108
 
+
14109
 
+
14110
 
+1.  Introduction
14111
 
+
14112
 
+   The 'mailto' URI scheme is used to identify resources that are
14113
 
+   reached using Internet mail.  In its simplest form, a 'mailto' URI
14114
 
+   contains an Internet mail address.  For interactions that require
14115
 
+   message headers or message bodies to be specified, the 'mailto' URI
14116
 
+   scheme also allows setting mail header fields and the message body.
14117
 
+
14118
 
+   This specification extends the previous scheme definition to also
14119
 
+   allow character data to be percent-encoded based on UTF-8, which
14120
 
+   offers a better and more consistent way of dealing with non-ASCII
14121
 
+   characters for internationalization.
14122
 
+
14123
 
+   This specification does not address the needs of the ongoing Email
14124
 
+   Address Internationalization effort (see [RFC4952]).  In particular,
14125
 
+   this specification does not include syntax for fallback addresses.
14126
 
+   This may be fixed in a future version of this specification.
14127
 
+
14128
 
+   In this document, the key words "MUST", "MUST NOT", "REQUIRED",
14129
 
+   "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY",
14130
 
+   and "OPTIONAL" are to be interpreted as described in [RFC2119].
14131
 
+
14132
 
+   In this document, URIs are enclosed in '<' and '>' as described in
14133
 
+   Appendix C of [STD66].  Extra whitespace and line breaks added to
14134
 
+   present long URIs are not part of the actual URI.
14135
 
+
14136
 
+
14137
 
+2.  Syntax of a mailto URI
14138
 
+
14139
 
+   The syntax of a 'mailto' URI is described using the ABNF of [STD68],
14140
 
+   non-terminal definitions from [RFC2822] (domain, dot-atom, quoted-
14141
 
+   string) and non-terminal definitions from [STD66] (unreserved, pct-
14142
 
+   encoded):
14143
 
+
14144
 
+      mailtoURI   = "mailto:" [ to ] [ hfields ]
14145
 
+      to          = [ addr-spec *("%2C" addr-spec ) ]
14146
 
+      hfields     = "?" hfield *( "&" hfield )
14147
 
+      hfield      = hfname "=" hfvalue
14148
 
+      hfname      = *qchar
14149
 
+      hfvalue     = *qchar
14150
 
+      addr-spec   = local-part "@" domain
14151
 
+      local-part  = dot-atom / quoted-string
14152
 
+      qchar       = unreserved / pct-encoded / some-delims
14153
 
+      some-delims = "!" / "$" / "'" / "(" / ")" / "*"
14154
 
+                  / "+" / "," / ";" / ":" / "@"
14155
 
+
14156
 
+   <addr-spec> is a mail address as specified in [RFC2822], but
14157
 
+   excluding <comment> from [RFC2822].  However, the following changes
14158
 
+
14159
 
+
14160
 
+
14161
 
+Duerst, et al.           Expires August 28, 2008                [Page 3]
14162
 
+
14163
 
+Internet-Draft           The 'mailto' URI Scheme           February 2008
14164
 
+
14165
 
+
14166
 
+   apply:
14167
 
+
14168
 
+   1.  A number of characters that can appear in <addr-spec> have to be
14169
 
+       percent-encoded.  These are the characters that cannot appear in
14170
 
+       an URI according to [STD66] as well as "%" (because it is used
14171
 
+       for percent-encoding) and all the characters in gen-delims except
14172
 
+       "@" (i.e. "/", "?", "#", "[" and "]").  Of the characters in sub-
14173
 
+       delims, at least the following also have to be percent-encoded:
14174
 
+       "&", ";", and "=".  Care has to be taken both when encoding as
14175
 
+       well as when decoding to make sure these operations are applied
14176
 
+       only once.
14177
 
+
14178
 
+   2.  <obs-local-part> and <NO-WS-CTL> as defined in [RFC2822] are not
14179
 
+       allowed.
14180
 
+
14181
 
+   3.  Whitespace and comments within <local-part> and <domain> are not
14182
 
+       allowed.  They would not have any operational semantics.
14183
 
+
14184
 
+   4.  Percent-encoding can be used in the <domain> part of an <addr-
14185
 
+       spec>, in order to denote an internationalized domain name.  The
14186
 
+       considerations for <reg-name> in [STD66] apply.  In particular,
14187
 
+       non-ASCII characters must first be encoded according to UTF-8
14188
 
+       [STD63], and then each octet of the corresponding UTF-8 sequence
14189
 
+       must be percent-encoded to be represented as URI characters.  URI
14190
 
+       producing applications must not use percent-encoding in domain
14191
 
+       names unless it is used to represent a UTF-8 character sequence.
14192
 
+       When the internationalized domain name is used to compose a
14193
 
+       message, the name must be transformed to the IDNA encoding where
14194
 
+       appropriate [RFC3490].  URI producers should provide these domain
14195
 
+       names in the IDNA encoding, rather than percent-encoded, if they
14196
 
+       wish to maximize interoperability with legacy 'mailto' URI
14197
 
+       interpreters.
14198
 
+
14199
 
+   5.  Percent-encoding of non-ASCII octets in the <local-part> of an
14200
 
+       <addr-spec> is reserved for the internationalization of the
14201
 
+       <local-part>.  Non-ASCII characters must first be encoded
14202
 
+       according to UTF-8 [STD63], and then each octet of the
14203
 
+       corresponding UTF-8 sequence must be percent-encoded to be
14204
 
+       represented as URI characters.  Any other percent-encoding of
14205
 
+       non-ASCII characters is prohibited.  When a <local-part>
14206
 
+       containing non-ASCII characters will be used to compose a
14207
 
+       message, the <local-part> must be transformed to conform to
14208
 
+       whatever encoding may be defined in a future specification for
14209
 
+       the internationalization of email addresses.
14210
 
+
14211
 
+   <hfname> and <hfvalue> are encodings of an [RFC2822] header field
14212
 
+   name and value, respectively.  Percent-encoding is needed for the
14213
 
+   same characters as listed above for <addr-spec>. <hfname> is case-
14214
 
+
14215
 
+
14216
 
+
14217
 
+Duerst, et al.           Expires August 28, 2008                [Page 4]
14218
 
+
14219
 
+Internet-Draft           The 'mailto' URI Scheme           February 2008
14220
 
+
14221
 
+
14222
 
+   insensitive, but <hfvalue> in general is case-sensitive.
14223
 
+
14224
 
+   The special <hfname> "body" indicates that the associated <hfvalue>
14225
 
+   is the body of the message.  The "body" field value should contain
14226
 
+   the content for the first text/plain body part of the message.  The
14227
 
+   "body" pseudo header field is primarily intended for the generation
14228
 
+   of short text messages for automatic processing (such as "subscribe"
14229
 
+   messages for mailing lists), not for general MIME bodies.  The "body"
14230
 
+   pseudo header field name has been registered with IANA for this
14231
 
+   special purpose, see Section 9.1.
14232
 
+
14233
 
+   Within 'mailto' URIs, the characters "?", "=", and "&" are reserved.
14234
 
+
14235
 
+   Because the "&" (ampersand) character is reserved in HTML and XML,
14236
 
+   any 'mailto' URI which contains an ampersand must be spelled
14237
 
+   differently in HTML and XML than in other contexts.  A 'mailto' URI
14238
 
+   which appears in an HTML or XML document must escape the "&", e.g. as
14239
 
+   "&amp;".
14240
 
+
14241
 
+   Non-ASCII characters can be encoded in hfvalue as follows:
14242
 
+
14243
 
+   1.  MIME encoded words (as defined in [RFC2047]) are permitted in
14244
 
+       header field values, but not in an <hfvalue> of a "body"
14245
 
+       <hfname>.
14246
 
+
14247
 
+   2.  Non-ASCII characters can be encoded according to UTF-8 [STD63],
14248
 
+       and then each octet of the corresponding UTF-8 sequence is
14249
 
+       percent-encoded to be represented as URI characters.  When header
14250
 
+       field values encoded in this way are used to compose a message,
14251
 
+       the <hfvalue> must be transformed into MIME encoded words
14252
 
+       [RFC2047], except for an <hfvalue> of a "body" <hfname>, which
14253
 
+       has to be encoded according to [RFC2045].  Please note that for
14254
 
+       MIME encoded words and for bodies in composed email messages,
14255
 
+       encodings other than UTF-8 MAY be used as long as the characters
14256
 
+       are properly transcoded.
14257
 
+
14258
 
+   MIME encoded words and UTF-8-based percent-encoding SHOULD NOT both
14259
 
+   be used sequentially in the same <hfvalue>, and MUST NOT be combined.
14260
 
+
14261
 
+   Also note that it is legal to specify both <to> and an <hfname> whose
14262
 
+   value is "to".  That is,
14263
 
+
14264
 
+   <mailto:addr1@an.example%2C%20addr2@an.example>
14265
 
+
14266
 
+   is equivalent to
14267
 
+
14268
 
+   <mailto:?to=addr1@an.example%2C%20addr2@an.example>
14269
 
+
14270
 
+
14271
 
+
14272
 
+
14273
 
+Duerst, et al.           Expires August 28, 2008                [Page 5]
14274
 
+
14275
 
+Internet-Draft           The 'mailto' URI Scheme           February 2008
14276
 
+
14277
 
+
14278
 
+   is equivalent to
14279
 
+
14280
 
+   <mailto:addr1@an.example?to=addr2@an.example>
14281
 
+
14282
 
+   However, the latter form is NOT RECOMMENDED.  Implementations should
14283
 
+   be careful not to produce two "To:" header fields in a message; the
14284
 
+   "To:" header field may occur at most once in a message ([RFC2822],
14285
 
+   Section 3.6).  Also, creators of 'mailto' URIs should be careful to
14286
 
+   not include other message header fields multiple times if these
14287
 
+   header fields can only be used once in a message.
14288
 
+
14289
 
+   Creators of 'mailto' URIs SHOULD avoid using the same <hfname>
14290
 
+   multiple times in the same URI to avoid interoperability problems.
14291
 
+   If the same <hfname> appears multiple times in an URI, behavior
14292
 
+   varies widely for different user agents, and for each <hfname>.
14293
 
+   Examples include only using the first or last <hfname>/<hfvalue>
14294
 
+   pair, combining each <hfvalue> by simple concatenation, or in a way
14295
 
+   appropriate for the corresponding header field, or creating multiple
14296
 
+   header fields.
14297
 
+
14298
 
+
14299
 
+3.  Semantics and Operations
14300
 
+
14301
 
+   A 'mailto' URI designates an "internet resource", which is the
14302
 
+   mailbox specified in the address.  When additional header fields are
14303
 
+   supplied, the resource designated is the same address, but with an
14304
 
+   additional profile for accessing the resource.  While there are
14305
 
+   Internet resources that can only be accessed via electronic mail, the
14306
 
+   'mailto' URI is not intended as a way of retrieving such objects
14307
 
+   automatically.
14308
 
+
14309
 
+   In current practice, resolving URIs such as those in the 'http' URI
14310
 
+   scheme causes an immediate interaction between client software and a
14311
 
+   host running an interactive server.  The 'mailto' URI has unusual
14312
 
+   semantics because resolving such a URI does not cause an immediate
14313
 
+   interaction.  Instead, the client creates a message to the designated
14314
 
+   address with the various header fields set as default.  The user can
14315
 
+   edit the message, send this message unedited, or choose not to send
14316
 
+   the message.  The operation of how any URI scheme is resolved is not
14317
 
+   mandated by the URI specifications.
14318
 
+
14319
 
+
14320
 
+4.  Unsafe Header Fields
14321
 
+
14322
 
+   The user agent interpreting a 'mailto' URI SHOULD choose not to
14323
 
+   create a message if any of the header fields are considered
14324
 
+   dangerous; it may also choose to create a message with only a subset
14325
 
+   of the header fields given in the URI.  Only a limited set of header
14326
 
+
14327
 
+
14328
 
+
14329
 
+Duerst, et al.           Expires August 28, 2008                [Page 6]
14330
 
+
14331
 
+Internet-Draft           The 'mailto' URI Scheme           February 2008
14332
 
+
14333
 
+
14334
 
+   fields such as Subject and Keywords, as well as Body, are believed to
14335
 
+   be both safe and useful in the general case.  In cases where the
14336
 
+   source of an URI is well known, and/or specific header fields are
14337
 
+   limited to specific well-known values, other header fields may be
14338
 
+   considered safe, too.
14339
 
+
14340
 
+   The creator of a 'mailto' URI cannot expect the resolver of a URI to
14341
 
+   understand more than the "subject" header field and "body".  Clients
14342
 
+   that resolve 'mailto' URIs into mail messages MUST be able to
14343
 
+   correctly create [RFC2822]-compliant mail messages using the
14344
 
+   "subject" header field and "body".
14345
 
+
14346
 
+
14347
 
+5.  Encoding
14348
 
+
14349
 
+   [STD66] requires that many characters in URIs be encoded.  This
14350
 
+   affects the 'mailto' URI scheme for some common characters that might
14351
 
+   appear in addresses, header fields, or message contents.  One such
14352
 
+   character is space (" ", ASCII hex 20).  Note the examples below that
14353
 
+   use "%20" for space in the message body.  Also note that line breaks
14354
 
+   in the body of a message MUST be encoded with "%0D%0A".
14355
 
+
14356
 
+   People creating 'mailto' URIs must be careful to encode any reserved
14357
 
+   characters that are used in the URIs so that properly-written URI
14358
 
+   interpreters can read them.  Also, client software that reads URIs
14359
 
+   must be careful to decode strings before creating the mail message so
14360
 
+   that the mail messages appear in a form that the recipient software
14361
 
+   will understand.  These strings should be decoded before showing the
14362
 
+   message to the sending user.
14363
 
+
14364
 
+   Software creating 'mailto' URIs likewise has to be careful to encode
14365
 
+   any reserved characters that are used.  One kind of software creating
14366
 
+   'mailto' URIs are HTML forms.  Current implementations encode a space
14367
 
+   as '+', but this creates problems because such a '+' standing for a
14368
 
+   space cannot be distinguished from a real '+' in a 'mailto' URI.
14369
 
+   When producing 'mailto' URIs, all spaces SHOULD be encoded as %20.
14370
 
+
14371
 
+   The 'mailto' URI scheme is limited in that it does not provide for
14372
 
+   substitution of variables.  Thus, a message body that must include a
14373
 
+   user's email address cannot be encoded using the 'mailto' URI.  This
14374
 
+   limitation also prevents 'mailto' URIs that are signed with public
14375
 
+   keys and other such variable information.
14376
 
+
14377
 
+
14378
 
+6.  Deployment of UTF-8-Based Percent-Encoding
14379
 
+
14380
 
+   UTF-8-based percent-encoding should only be used in actual 'mailto'
14381
 
+   URIs once it is well deployed in software that interprets 'mailto'
14382
 
+
14383
 
+
14384
 
+
14385
 
+Duerst, et al.           Expires August 28, 2008                [Page 7]
14386
 
+
14387
 
+Internet-Draft           The 'mailto' URI Scheme           February 2008
14388
 
+
14389
 
+
14390
 
+   URIs (such as mail user agents).
14391
 
+
14392
 
+
14393
 
+7.  Examples
14394
 
+
14395
 
+7.1.  Examples Conforming to RFC2368
14396
 
+
14397
 
+   A URI for an ordinary individual mailing address:
14398
 
+
14399
 
+   <mailto:chris@example.com>
14400
 
+
14401
 
+   A URI for a mail response system that requires the name of the file
14402
 
+   in the subject:
14403
 
+
14404
 
+   <mailto:infobot@example.com?subject=current-issue>
14405
 
+
14406
 
+   A mail response system that requires a "send" request in the body:
14407
 
+
14408
 
+   <mailto:infobot@example.com?body=send%20current-issue>
14409
 
+
14410
 
+   A similar URI, with two lines with different "send" requests (in this
14411
 
+   case, "send current-issue" and, on the next line, "send index"):
14412
 
+
14413
 
+   <mailto:infobot@
14414
 
+   example.com?body=send%20current-issue%0D%0Asend%20index>
14415
 
+
14416
 
+   An interesting use of 'mailto' URIs occurs when browsing archives of
14417
 
+   messages.  A link can be provided that allows to reply to a message
14418
 
+   and conserve threading information.  This is done by adding a In-
14419
 
+   Reply-To header field containing the Message-ID of the message where
14420
 
+   the link is added, for example:
14421
 
+
14422
 
+   <mailto:list@example.org?In-Reply-To=%3C3469A91.D10AF4C@
14423
 
+   example.com%3E>
14424
 
+
14425
 
+   A request to subscribe to a mailing list:
14426
 
+
14427
 
+   <mailto:majordomo@example.com?body=subscribe%20bamboo-l>
14428
 
+
14429
 
+   A URI for a single user which includes a CC of another user:
14430
 
+
14431
 
+   <mailto:joe@example.com?cc=bob@example.com&body=hello>
14432
 
+
14433
 
+   Note the use of the "&" reserved character above.  The following
14434
 
+   example, using "?" twice, is incorrect:
14435
 
+
14436
 
+   <mailto:joe@example.com?cc=bob@example.com?body=hello> ; WRONG!
14437
 
+
14438
 
+
14439
 
+
14440
 
+
14441
 
+Duerst, et al.           Expires August 28, 2008                [Page 8]
14442
 
+
14443
 
+Internet-Draft           The 'mailto' URI Scheme           February 2008
14444
 
+
14445
 
+
14446
 
+   According to [RFC2822], the characters "?", "&", and even "%" may
14447
 
+   occur in addr-specs.  The fact that they are reserved characters is
14448
 
+   not a problem: those characters may appear in 'mailto' URIs, they
14449
 
+   just may not appear in unencoded form.  The standard URI encoding
14450
 
+   mechanisms ("%" followed by a two-digit hex number) must be used in
14451
 
+   these cases.
14452
 
+
14453
 
+   To indicate the address "gorby%kremvax@example.com" one would use:
14454
 
+
14455
 
+   <mailto:gorby%25kremvax@example.com>
14456
 
+
14457
 
+   To indicate the address "unlikely?address@example.com", and include
14458
 
+   another header field, one would use:
14459
 
+
14460
 
+   <mailto:unlikely%3Faddress@example.com?blat=foop>
14461
 
+
14462
 
+   As described above, the "&" (ampersand) character is reserved in HTML
14463
 
+   and must be replaced e.g. with "&amp;".  Thus, a URI with an internal
14464
 
+   ampersand might look like:
14465
 
+
14466
 
+   Click <a href="mailto:joe@an.example?cc=bob@
14467
 
+   an.example&amp;body=hello">mailto:joe@an.example?cc=bob@
14468
 
+   an.example&amp;body=hello</a> to send a greeting message to Joe and
14469
 
+   Bob.
14470
 
+
14471
 
+   When an email address itself includes an "&" (ampersand) character,
14472
 
+   that character has to be percent-escaped.  For example, the 'mailto'
14473
 
+   URI to send mail to "Mike&family@example.org" is
14474
 
+   <mailto:Mike%26family@example.org>.
14475
 
+
14476
 
+7.2.  Examples of Complicated Email Addresses
14477
 
+
14478
 
+   Following are a few examples of how to treat email addresses that
14479
 
+   contain complicated escaping syntax.
14480
 
+
14481
 
+   Email address: "not@me"@example.org; corresponding 'mailto' URI:
14482
 
+
14483
 
+   <mailto:%22not%40me%22@example.org>.
14484
 
+
14485
 
+   Email address: "oh\\no"@example.org; corresponding 'mailto' URI:
14486
 
+
14487
 
+   <mailto:%22oh%5C%5Cno%22@example.org>.
14488
 
+
14489
 
+   Email address: "\\\"it's\ ugly\\\""@example.org; corresponding
14490
 
+   'mailto' URI:
14491
 
+
14492
 
+   <mailto:%22%5C%5C%5C%22it's%22%20ugly%5C%5C%5C%22%22@example.org>.
14493
 
+
14494
 
+
14495
 
+
14496
 
+
14497
 
+Duerst, et al.           Expires August 28, 2008                [Page 9]
14498
 
+
14499
 
+Internet-Draft           The 'mailto' URI Scheme           February 2008
14500
 
+
14501
 
+
14502
 
+7.3.  Examples Using UTF-8-Based Percent-Encoding
14503
 
+
14504
 
+   Sending a mail with the subject "coffee" in French, i.e. "cafe" where
14505
 
+   the final e is an e-acute, using UTF-8 and percent-encoding:
14506
 
+
14507
 
+   <mailto:user@example.org?subject=caf%C3%A9>
14508
 
+
14509
 
+   The same subject, this time using an encoded-word (escaping the "="
14510
 
+   and "?" characters used in the encoded-word syntax, because they are
14511
 
+   reserved):
14512
 
+
14513
 
+   <mailto:user@
14514
 
+   example.org?subject=%3D%3Futf-8%3FQ%3Fcaf%3DC3%3DA9%3F%3D>
14515
 
+
14516
 
+   The same subject, this time encoded as iso-8859-1:
14517
 
+
14518
 
+   <mailto:user@
14519
 
+   example.org?subject=%3D%3Fiso-8859-1%3FQ%3Fcaf%3DE9%3F%3D>
14520
 
+
14521
 
+   Going back to straight UTF-8 and adding a body with the same value:
14522
 
+
14523
 
+   <mailto:user@example.org?subject=caf%C3%A9&body=caf%C3%A9>
14524
 
+
14525
 
+   This 'mailto' URI may result in a message looking like this:
14526
 
+
14527
 
+      From: sender@example.net
14528
 
+      To: user@example.org
14529
 
+      Subject: =?utf-8?Q?caf=C3=A9?=
14530
 
+      Content-Type: text/plain;charset=utf-8
14531
 
+      Content-Transfer-Encoding: quoted-printable
14532
 
+
14533
 
+      caf=C3=A9
14534
 
+
14535
 
+   The software sending the email is not restricted to UTF-8, but can
14536
 
+   use other encodings.  The following shows the same email using iso-
14537
 
+   8859-1 two times:
14538
 
+
14539
 
+      From: sender@example.net
14540
 
+      To: user@example.org
14541
 
+      Subject: =?iso-8859-1?Q?caf=E9?=
14542
 
+      Content-Type: text/plain;charset=iso-8859-1
14543
 
+      Content-Transfer-Encoding: quoted-printable
14544
 
+
14545
 
+      caf=E9
14546
 
+
14547
 
+   Different content transfer encodings (i.e. "8bit" or "base64" instead
14548
 
+   of "quoted-printable") and different encodings in encoded words (i.e.
14549
 
+   "B" instead of "Q") can also be used.
14550
 
+
14551
 
+
14552
 
+
14553
 
+Duerst, et al.           Expires August 28, 2008               [Page 10]
14554
 
+
14555
 
+Internet-Draft           The 'mailto' URI Scheme           February 2008
14556
 
+
14557
 
+
14558
 
+   For more examples of encoding the word coffee in different languages,
14559
 
+   see [RFC2324].
14560
 
+
14561
 
+   The following example uses the Japanese word "natto" (Unicode
14562
 
+   characters U+7D0D U+8C46) as a domain name label, sending a mail to a
14563
 
+   user at "natto".example.org:
14564
 
+
14565
 
+   <mailto:user@%E7%B4%8D%E8%B1%86.example.org?subject=Test&body=NATTO>
14566
 
+
14567
 
+   When constructing the email, the domain name label is converted to
14568
 
+   punycode.  The resulting message may look as follows:
14569
 
+
14570
 
+      From: sender@example.net
14571
 
+      To: user@xn--99zt52a.example.org
14572
 
+      Subject: Test
14573
 
+      Content-Type: text/plain
14574
 
+      Content-Transfer-Encoding: 7bit
14575
 
+
14576
 
+      NATTO
14577
 
+
14578
 
+
14579
 
+8.  Security Considerations
14580
 
+
14581
 
+   The 'mailto' URI scheme can be used to send a message from one user
14582
 
+   to another, and thus can introduce many security concerns.  Mail
14583
 
+   messages can be logged at the originating site, the recipient site,
14584
 
+   and intermediary sites along the delivery path.  If the messages are
14585
 
+   not encoded, they can also be read at any of those sites.
14586
 
+
14587
 
+   A 'mailto' URI gives a template for a message that can be sent by
14588
 
+   mail client software.  The contents of that template may be opaque or
14589
 
+   difficult to read by the user at the time of specifying the URI.
14590
 
+   Thus, a mail client should never send a message based on a 'mailto'
14591
 
+   URI without first showing the full message that will be sent to the
14592
 
+   user (including all header fields that were specified by the 'mailto'
14593
 
+   URI), fully decoded, and asking the user for approval to send the
14594
 
+   message as electronic mail.  The mail client should also make it
14595
 
+   clear that the user is about to send an electronic mail message,
14596
 
+   since the user may not be aware that this is the result of a 'mailto'
14597
 
+   URI.
14598
 
+
14599
 
+   A mail client should never send anything without complete disclosure
14600
 
+   to the user of what will be sent; it should disclose not only the
14601
 
+   message destination, but also any header fields.  Unrecognized header
14602
 
+   fields, or header fields with values inconsistent with those the mail
14603
 
+   client would normally send should be especially suspect.  MIME header
14604
 
+   fields (MIME- Version, Content-*) are most likely inappropriate,
14605
 
+   except when added by the MUA to correctly encode the text(s) being
14606
 
+
14607
 
+
14608
 
+
14609
 
+Duerst, et al.           Expires August 28, 2008               [Page 11]
14610
 
+
14611
 
+Internet-Draft           The 'mailto' URI Scheme           February 2008
14612
 
+
14613
 
+
14614
 
+   sent, as are those relating to routing (From, Apparently-To, etc.)
14615
 
+
14616
 
+   Note that some header fields are inherently unsafe to include in a
14617
 
+   message generated from a URI.  For example, header fields such as
14618
 
+   "From:", and so on, should never be interpreted from a URI.  In
14619
 
+   general, the fewer header fields interpreted from the URI, the less
14620
 
+   likely it is that a sending agent will create an unsafe message.
14621
 
+
14622
 
+   Examples of problems with sending unapproved mail include:
14623
 
+
14624
 
+      mail that breaks laws upon delivery, such as making illegal
14625
 
+      threats;
14626
 
+
14627
 
+      mail that identifies the sender as someone interested in breaking
14628
 
+      laws;
14629
 
+
14630
 
+      mail that identifies the sender to an unwanted third party;
14631
 
+
14632
 
+      mail that causes a financial charge to be incurred on the sender;
14633
 
+
14634
 
+      mail that causes an action on the recipient machine that causes
14635
 
+      damage that might be attributed to the sender.
14636
 
+
14637
 
+   Programs that interpret 'mailto' URIs should ensure that the SMTP
14638
 
+   "From" address (the SMTP envelope return path given as an argument to
14639
 
+   the SMTP MAIL FROM command) is set and correct, and that the
14640
 
+   resulting email is a complete, workable message.
14641
 
+
14642
 
+   'mailto' URIs on public Web pages expose mail addresses for
14643
 
+   harvesting.  This applies to all mail addresses included in the
14644
 
+   'mailto' URI, including the addresses in a "bcc" hfvalue.  Those
14645
 
+   addresses will not be sent to the recipients in the 'to' field and in
14646
 
+   the "to" and "cc" hfvalues, but will still be publicly visible in the
14647
 
+   URI.
14648
 
+
14649
 
+   The security considerations of [STD66], [RFC3490], [RFC3491], and
14650
 
+   [RFC3987] also apply.  Implementers and users are recommended to
14651
 
+   check them carefully.
14652
 
+
14653
 
+
14654
 
+9.  IANA Considerations
14655
 
+
14656
 
+   This document changes the definition of the 'mailto' URI scheme; the
14657
 
+   registry of URI schemes needs to be updated to refer to this document
14658
 
+   rather than its predecessor, [RFC2368].
14659
 
+
14660
 
+
14661
 
+
14662
 
+
14663
 
+
14664
 
+
14665
 
+Duerst, et al.           Expires August 28, 2008               [Page 12]
14666
 
+
14667
 
+Internet-Draft           The 'mailto' URI Scheme           February 2008
14668
 
+
14669
 
+
14670
 
+9.1.  Registration of the Body Header Field
14671
 
+
14672
 
+   IANA is herewith requested to register the Body header field in the
14673
 
+   Message Header Fields Registry ([RFC3864]) as follows:
14674
 
+
14675
 
+   Header field name:
14676
 
+      Body
14677
 
+
14678
 
+   Applicable protocol:
14679
 
+      None. This registration is made to assure that this header field
14680
 
+      name is not used at all, in order to not create any problems
14681
 
+      for 'mailto' URIs.
14682
 
+
14683
 
+   Status:
14684
 
+      reserved
14685
 
+
14686
 
+   Author/Change controller:
14687
 
+      IETF
14688
 
+
14689
 
+   Specification document(s):
14690
 
+      Internet-Draft draft-duerst-mailto-bis-05.txt
14691
 
+      (Note to RFC Editor: Replace this with
14692
 
+       RFC YYYY (RFC number of this specification))
14693
 
+
14694
 
+   Related information:
14695
 
+      none
14696
 
+
14697
 
+
14698
 
+10.  Main Changes from RFC 2368
14699
 
+
14700
 
+   The main changes from RFC 2368 are as follows:
14701
 
+
14702
 
+   o  Changed syntax from RFC 2822 <mailbox> to RFC 2822 <addr-spec>.
14703
 
+
14704
 
+   o  Allowed UTF-8-based percent-encoding for domain names and in
14705
 
+      <hfvalue>.
14706
 
+
14707
 
+   o  Nailed down percent-encoding in <local-part> to be based on UTF-8,
14708
 
+      reserved for future use.
14709
 
+
14710
 
+   o  Removed prohibition against "Bcc:" header fields, but added a
14711
 
+      warning about their visibility and harvesting for spam.
14712
 
+
14713
 
+   o  Added clarifications for escaping.
14714
 
+
14715
 
+
14716
 
+
14717
 
+
14718
 
+
14719
 
+
14720
 
+
14721
 
+Duerst, et al.           Expires August 28, 2008               [Page 13]
14722
 
+
14723
 
+Internet-Draft           The 'mailto' URI Scheme           February 2008
14724
 
+
14725
 
+
14726
 
+11.  Change Log
14727
 
+
14728
 
+   [RFC Editor, please remove this section before publication.]
14729
 
+
14730
 
+11.1.  Changes between draft 04 and draft 05
14731
 
+
14732
 
+   o  Added "Main Changes from RFC 2368" to help implementation updates
14733
 
+      from RFC 2368.
14734
 
+
14735
 
+   o  Added a warning about spam harvesting and visibility of bcc
14736
 
+      addresses.
14737
 
+
14738
 
+   o  Clarified that <addr-spec> does not include comments.
14739
 
+
14740
 
+   o  Changed names of syntax productions to be better in line with
14741
 
+      standard terminology: headers -> hfields, header -> hfield, hname
14742
 
+      -> hfname, hvalue -> hfvalue.
14743
 
+
14744
 
+   o  Streamlined terminology: mailto, mailto: -> 'mailto'; LHS ->
14745
 
+      <local-part>; consistently used '<' and '>' for ABNF production
14746
 
+      names.
14747
 
+
14748
 
+   o  Changed section heading from "Unsafe Headers" to "Unsafe Header
14749
 
+      Fields".
14750
 
+
14751
 
+   o  Got rid of references and the word 'update' in the Abstract.
14752
 
+
14753
 
+   o  Updated ABNF reference to [STD68]
14754
 
+
14755
 
+   o  Some minor wording cleanup.
14756
 
+
14757
 
+11.2.  Changes between draft 03 and draft 04
14758
 
+
14759
 
+   o  Added mention of internationalization (not just IRI) to abstract.
14760
 
+
14761
 
+   o  Updated reference from draft-ietf-eai-framework to RFC 4952,
14762
 
+      simplified referring text.
14763
 
+
14764
 
+   o  Used MUST for resolvers to understand Subject and Body for clear
14765
 
+      interoperability.
14766
 
+
14767
 
+   o  Noted that multiple identical hnames can cause interoperability
14768
 
+      problems and SHOULD be avoided.
14769
 
+
14770
 
+   o  Note the problem of '+' produced by HTML forms, made clear that
14771
 
+      %20 SHOULD be used for encoding spaces.
14772
 
+
14773
 
+
14774
 
+
14775
 
+
14776
 
+
14777
 
+Duerst, et al.           Expires August 28, 2008               [Page 14]
14778
 
+
14779
 
+Internet-Draft           The 'mailto' URI Scheme           February 2008
14780
 
+
14781
 
+
14782
 
+   o  Removed warning against using bcc; doesn't seem to be of any harm
14783
 
+      if user checks explicitly.
14784
 
+
14785
 
+   o  Some minor wording cleanup.
14786
 
+
14787
 
+11.3.  Changes between draft 02 and draft 03
14788
 
+
14789
 
+   o  Adjusted description of mailto URI in abstract to match intro.
14790
 
+
14791
 
+   o  Added registration template for body header field.
14792
 
+
14793
 
+   o  Clarified requirements for produced email message.
14794
 
+
14795
 
+   o  Clarified case (in)sensitivity of header field names and values.
14796
 
+
14797
 
+   o  Introduced reference to EAI-framework, explained to what extent it
14798
 
+      has been taken into account.
14799
 
+
14800
 
+   o  Changed reference label from RFC3986 to STD66.
14801
 
+
14802
 
+11.4.  Changes between draft 01 and draft 02
14803
 
+
14804
 
+   o  Fixed phone/fax for Martin.
14805
 
+
14806
 
+   o  Changed examples to reduce cases with both a 'to' field and a 'to'
14807
 
+      hname.
14808
 
+
14809
 
+   o  Fixed syntax to not rely on non-terminals from RFC 2396.  Changed
14810
 
+      description of set of characters that needs to be escaped.
14811
 
+
14812
 
+   o  Mollified warning about header fields other than Subject,
14813
 
+      Keywords, and Body.
14814
 
+
14815
 
+   o  Clarified prohibition of mixing different encodings (%-escaping
14816
 
+      and Mime encoded words) for header fields.
14817
 
+
14818
 
+   o  Improved some examples.  Fixed some terminology.
14819
 
+
14820
 
+11.5.  Changes between draft 00 and draft 01
14821
 
+
14822
 
+   o  Added clarification about permitted syntax and escaping on email
14823
 
+      address LHS, and more complicated examples.
14824
 
+
14825
 
+   o  Added text about more safe headers in case origin or mailto URIs
14826
 
+      is known.
14827
 
+
14828
 
+   o  Fixed date of [STD66]
14829
 
+
14830
 
+
14831
 
+
14832
 
+
14833
 
+Duerst, et al.           Expires August 28, 2008               [Page 15]
14834
 
+
14835
 
+Internet-Draft           The 'mailto' URI Scheme           February 2008
14836
 
+
14837
 
+
14838
 
+   o  Added a sentence referencing [RFC2119]
14839
 
+
14840
 
+   o  Added Jamie back in as a co-author.  Changed address/affiliation
14841
 
+      for Martin.
14842
 
+
14843
 
+11.6.  Changes from RFC 2368
14844
 
+
14845
 
+   o  For interoperability with IRIs ([RFC3987]), allowed percent-
14846
 
+      encoding, fixed to UTF-8, in the domain name part of an email
14847
 
+      address, in LHS part of an address (currently reserved because not
14848
 
+      operationally usable), and in hvalue parts.
14849
 
+
14850
 
+   o  Changed from 'URL' to 'URI'
14851
 
+
14852
 
+   o  Updated references: ABNF to [STD68]; message syntax to [RFC2822],
14853
 
+      URI Generic Syntax to [STD66]
14854
 
+
14855
 
+   o  Expanded "#mailbox", because the "#" shortcut is no longer
14856
 
+      available; needs checking
14857
 
+
14858
 
+
14859
 
+12.  Acknowledgments
14860
 
+
14861
 
+   This document was derived from [RFC2368]; the acknowledgments from
14862
 
+   this specification still apply.  In addition, we thank Paul Hoffman
14863
 
+   for his work on [RFC2368].
14864
 
+
14865
 
+   Valuable input on this document was received from (in no particular
14866
 
+   order): Paul Hoffman, Charles Lindsey, Tim Kindberg, Frank Ellermann,
14867
 
+   Etan Wexler, Michael Haardt, Michael Anthony Puls II, and Alfred
14868
 
+   Hoenes.
14869
 
+
14870
 
+
14871
 
+13.  References
14872
 
+
14873
 
+13.1.  Normative References
14874
 
+
14875
 
+   [RFC2045]  Freed, N. and N. Borenstein, "Multipurpose Internet Mail
14876
 
+              Extensions (MIME) Part One: Format of Internet Message
14877
 
+              Bodies", November 1996.
14878
 
+
14879
 
+   [RFC2047]  Moore, K., "MIME Part Three: Message Header Extensions for
14880
 
+              Non-ASCII Text", RFC 2047, November 1996.
14881
 
+
14882
 
+   [RFC2119]  Bradner, S., "Key words for use in RFCs to Indicate
14883
 
+              Requirement Levels", BCP 14, RFC 2119, March 1997.
14884
 
+
14885
 
+   [RFC2822]  Resnik, P., "Internet Message Format", RFC 2822,
14886
 
+
14887
 
+
14888
 
+
14889
 
+Duerst, et al.           Expires August 28, 2008               [Page 16]
14890
 
+
14891
 
+Internet-Draft           The 'mailto' URI Scheme           February 2008
14892
 
+
14893
 
+
14894
 
+              April 2001.
14895
 
+
14896
 
+   [RFC3490]  Faltstrom, P., Hoffman, P., and A. Costello,
14897
 
+              "Internationalizing Domain Names in Applications (IDNA)",
14898
 
+              RFC 3490, March 2003.
14899
 
+
14900
 
+   [RFC3491]  Hoffman, P. and M. Blanchet, "Nameprep: A Stringprep
14901
 
+              Profile for Internationalized Domain Names (IDN)",
14902
 
+              RFC 3491, March 2003.
14903
 
+
14904
 
+   [RFC3864]  Klyne, G., Nottingham, M., and J. Mogul, "Registration
14905
 
+              Procedures for Message Header Fields", RFC 3864, BCP 90,
14906
 
+              September 2004.
14907
 
+
14908
 
+   [RFC3987]  Duerst, M. and M. Suignard, "Internationalized Resource
14909
 
+              Identifiers (IRIs)", RFC 3987, January 2005.
14910
 
+
14911
 
+   [STD63]    Yergeau, F., "UTF-8, a transformation format of ISO
14912
 
+              10646", STD 63, RFC 3629, November 2003.
14913
 
+
14914
 
+   [STD66]    Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform
14915
 
+              Resource Identifier (URI): Generic Syntax", STD 66,
14916
 
+              RFC 3986, January 2005.
14917
 
+
14918
 
+   [STD68]    Crocker, D. and P. Overell, "Augmented BNF for Syntax
14919
 
+              Specifications: ABNF", STD 68, RFC 5234, January 2008.
14920
 
+
14921
 
+13.2.  Informative References
14922
 
+
14923
 
+   [RFC2324]  Masinter, L., "Hyper Text Coffee Pot Control Protocol
14924
 
+              (HTCPCP/1.0)", RFC 2324, April 1998.
14925
 
+
14926
 
+   [RFC2368]  Hoffman, P., Masinter, L., and J. Zawinski, "The mailto
14927
 
+              URL scheme", RFC 2368, July 1998.
14928
 
+
14929
 
+   [RFC4952]  Klensin, J. and Y. Ko, "Overview and Framework for
14930
 
+              Internationalized Email", RFC 4952, July 2007.
14931
 
+
14932
 
+
14933
 
+
14934
 
+
14935
 
+
14936
 
+
14937
 
+
14938
 
+
14939
 
+
14940
 
+
14941
 
+
14942
 
+
14943
 
+
14944
 
+
14945
 
+Duerst, et al.           Expires August 28, 2008               [Page 17]
14946
 
+
14947
 
+Internet-Draft           The 'mailto' URI Scheme           February 2008
14948
 
+
14949
 
+
14950
 
+Authors' Addresses
14951
 
+
14952
 
+   Martin Duerst (Note: Please write "Duerst" with u-umlaut wherever possible, for example as "D&#252;rst" in XML and HTML.)
14953
 
+   Aoyama Gakuin University
14954
 
+   5-10-1 Fuchinobe
14955
 
+   Sagamihara, Kanagawa  229-8558
14956
 
+   Japan
14957
 
+
14958
 
+   Phone: +81 42 759 6329
14959
 
+   Fax:   +81 42 759 6495
14960
 
+   Email: mailto:duerst@it.aoyama.ac.jp
14961
 
+   URI:   http://www.sw.it.aoyama.ac.jp/D%C3%BCrst/
14962
 
+
14963
 
+
14964
 
+   Larry Masinter
14965
 
+   Adobe Systems Incorporated
14966
 
+   345 Park Ave
14967
 
+   San Jose, CA  95110
14968
 
+   USA
14969
 
+
14970
 
+   Phone: +1-408-536-3024
14971
 
+   Email: LMM@acm.org
14972
 
+   URI:   http://larry.masinter.net/
14973
 
+
14974
 
+
14975
 
+   Jamie Zawinski
14976
 
+   DNA Lounge
14977
 
+   375 Eleventh Street
14978
 
+   San Francisco, CA  94103
14979
 
+   USA
14980
 
+
14981
 
+   Email: jwz@jwz.org
14982
 
+
14983
 
+
14984
 
+
14985
 
+
14986
 
+
14987
 
+
14988
 
+
14989
 
+
14990
 
+
14991
 
+
14992
 
+
14993
 
+
14994
 
+
14995
 
+
14996
 
+
14997
 
+
14998
 
+
14999
 
+
15000
 
+
15001
 
+Duerst, et al.           Expires August 28, 2008               [Page 18]
15002
 
+
15003
 
+Internet-Draft           The 'mailto' URI Scheme           February 2008
15004
 
+
15005
 
+
15006
 
+Full Copyright Statement
15007
 
+
15008
 
+   Copyright (C) The IETF Trust (2008).
15009
 
+
15010
 
+   This document is subject to the rights, licenses and restrictions
15011
 
+   contained in BCP 78, and except as set forth therein, the authors
15012
 
+   retain all their rights.
15013
 
+
15014
 
+   This document and the information contained herein are provided on an
15015
 
+   "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS
15016
 
+   OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY, THE IETF TRUST AND
15017
 
+   THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS
15018
 
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF
15019
 
+   THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
15020
 
+   WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
15021
 
+
15022
 
+
15023
 
+Intellectual Property
15024
 
+
15025
 
+   The IETF takes no position regarding the validity or scope of any
15026
 
+   Intellectual Property Rights or other rights that might be claimed to
15027
 
+   pertain to the implementation or use of the technology described in
15028
 
+   this document or the extent to which any license under such rights
15029
 
+   might or might not be available; nor does it represent that it has
15030
 
+   made any independent effort to identify any such rights.  Information
15031
 
+   on the procedures with respect to rights in RFC documents can be
15032
 
+   found in BCP 78 and BCP 79.
15033
 
+
15034
 
+   Copies of IPR disclosures made to the IETF Secretariat and any
15035
 
+   assurances of licenses to be made available, or the result of an
15036
 
+   attempt made to obtain a general license or permission for the use of
15037
 
+   such proprietary rights by implementers or users of this
15038
 
+   specification can be obtained from the IETF on-line IPR repository at
15039
 
+   http://www.ietf.org/ipr.
15040
 
+
15041
 
+   The IETF invites any interested party to bring to its attention any
15042
 
+   copyrights, patents or patent applications, or other proprietary
15043
 
+   rights that may cover technology that may be required to implement
15044
 
+   this standard.  Please address the information to the IETF at
15045
 
+   ietf-ipr@ietf.org.
15046
 
+
15047
 
+
15048
 
+Acknowledgment
15049
 
+
15050
 
+   Funding for the RFC Editor function is provided by the IETF
15051
 
+   Administrative Support Activity (IASA).
15052
 
+
15053
 
+
15054
 
+
15055
 
+
15056
 
+
15057
 
+Duerst, et al.           Expires August 28, 2008               [Page 19]
15058
 
+
15059
 
diff -urN dovecot-1.2.4/dovecot-libsieve/doc/rfc/draft-ietf-sieve-include-01.txt dovecot-1.2.4.debian/dovecot-libsieve/doc/rfc/draft-ietf-sieve-include-01.txt
15060
 
--- dovecot-1.2.4/dovecot-libsieve/doc/rfc/draft-ietf-sieve-include-01.txt      1970-01-01 01:00:00.000000000 +0100
15061
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/doc/rfc/draft-ietf-sieve-include-01.txt       2009-03-29 19:26:28.000000000 +0200
15062
 
@@ -0,0 +1,616 @@
15063
 
+
15064
 
+
15065
 
+
15066
 
+Network Working Group                                           C. Daboo
15067
 
+Internet-Draft                                                  A. Stone
15068
 
+Expires: September 30, 2009                               March 29, 2009
15069
 
+
15070
 
+
15071
 
+                Sieve Email Filtering: Include Extension
15072
 
+                      draft-ietf-sieve-include-01
15073
 
+
15074
 
+Status of this Memo
15075
 
+
15076
 
+   This Internet-Draft is submitted to IETF in full conformance with the
15077
 
+   provisions of BCP 78 and BCP 79.  This document may contain material
15078
 
+   from IETF Documents or IETF Contributions published or made publicly
15079
 
+   available before November 10, 2008.  The person(s) controlling the
15080
 
+   copyright in some of this material may not have granted the IETF
15081
 
+   Trust the right to allow modifications of such material outside the
15082
 
+   IETF Standards Process.  Without obtaining an adequate license from
15083
 
+   the person(s) controlling the copyright in such materials, this
15084
 
+   document may not be modified outside the IETF Standards Process, and
15085
 
+   derivative works of it may not be created outside the IETF Standards
15086
 
+   Process, except to format it for publication as an RFC or to
15087
 
+   translate it into languages other than English.
15088
 
+
15089
 
+   Internet-Drafts are working documents of the Internet Engineering
15090
 
+   Task Force (IETF), its areas, and its working groups.  Note that
15091
 
+   other groups may also distribute working documents as Internet-
15092
 
+   Drafts.
15093
 
+
15094
 
+   Internet-Drafts are draft documents valid for a maximum of six months
15095
 
+   and may be updated, replaced, or obsoleted by other documents at any
15096
 
+   time.  It is inappropriate to use Internet-Drafts as reference
15097
 
+   material or to cite them other than as "work in progress."
15098
 
+
15099
 
+   The list of current Internet-Drafts can be accessed at
15100
 
+   http://www.ietf.org/ietf/1id-abstracts.txt.
15101
 
+
15102
 
+   The list of Internet-Draft Shadow Directories can be accessed at
15103
 
+   http://www.ietf.org/shadow.html.
15104
 
+
15105
 
+   This Internet-Draft will expire on September 30, 2009.
15106
 
+
15107
 
+Copyright Notice
15108
 
+
15109
 
+   Copyright (c) 2009 IETF Trust and the persons identified as the
15110
 
+   document authors.  All rights reserved.
15111
 
+
15112
 
+   This document is subject to BCP 78 and the IETF Trust's Legal
15113
 
+   Provisions Relating to IETF Documents in effect on the date of
15114
 
+
15115
 
+
15116
 
+
15117
 
+Daboo & Stone          Expires September 30, 2009               [Page 1]
15118
 
+
15119
 
+Internet-Draft          Sieve Extension: Include              March 2009
15120
 
+
15121
 
+
15122
 
+   publication of this document (http://trustee.ietf.org/license-info).
15123
 
+   Please review these documents carefully, as they describe your rights
15124
 
+   and restrictions with respect to this document.
15125
 
+
15126
 
+Abstract
15127
 
+
15128
 
+   The Sieve Email Filtering "include" extension permits users to
15129
 
+   include one Sieve script inside another.  This can make managing
15130
 
+   large scripts or multiple sets of scripts much easier, and allows a
15131
 
+   site and its users to build up libraries of scripts.  Users are able
15132
 
+   to include their own personal scripts or site-wide scripts.
15133
 
+
15134
 
+Change History (to be removed prior to publication as an RFC)
15135
 
+
15136
 
+   Changes from ietf-00 to ietf-01:
15137
 
+   a.  Replaced import/export with global.
15138
 
+   b.  Added :once modifier to include.
15139
 
+   c.  Added global namespace to see if it holds water.
15140
 
+
15141
 
+   Changes from daboo-06 to ietf-00:
15142
 
+   a.  None
15143
 
+
15144
 
+   Changes from -05 to -06:
15145
 
+   a.  Aaron Stone joins as author.
15146
 
+   b.  Removed | characters from the script examples.
15147
 
+   c.  Updated draft references to published RFCs.
15148
 
+
15149
 
+   Changes from -04 to -05:
15150
 
+   a.  Fixed examples.
15151
 
+   b.  Relaxed requirement that imported/exported variables be set
15152
 
+       before being used.
15153
 
+
15154
 
+   Changes from -03 to -04:
15155
 
+   a.  Fixed missing 2119 definitions.
15156
 
+   b.  Defined interaction with variables through use of import and
15157
 
+       export commands.
15158
 
+
15159
 
+   Changes from -02 to -03:
15160
 
+   a.  Refreshing expired draft (updated for nits).
15161
 
+   b.  Syntax -> Usage.
15162
 
+   c.  Updated to 3028bis reference.
15163
 
+
15164
 
+   Changes from -01 to -02:
15165
 
+   a.  Minor formatting changes only - refreshing expired draft.
15166
 
+
15167
 
+   Changes from -00 to -01:
15168
 
+
15169
 
+
15170
 
+
15171
 
+
15172
 
+
15173
 
+Daboo & Stone          Expires September 30, 2009               [Page 2]
15174
 
+
15175
 
+Internet-Draft          Sieve Extension: Include              March 2009
15176
 
+
15177
 
+
15178
 
+   a.  Added IPR boiler plate.
15179
 
+   b.  Re-ordered sections at start to conform to RFC style.
15180
 
+   c.  Moved recursion comment into General Considerations section.
15181
 
+   d.  Switched to using optional parameter to indicate personal vs
15182
 
+       global.
15183
 
+   e.  Explicitly state that an error occurs when a missing script is
15184
 
+       included.
15185
 
+
15186
 
+Open Issues (to be resolved prior to publication as an RFC)
15187
 
+
15188
 
+   a.  Interaction with variables (scoping).  Idea 1: use a "global"
15189
 
+       command to make a variable shared between scripts.  Idea 2: use a
15190
 
+       "global" variable namespace and no additional commands.
15191
 
+
15192
 
+
15193
 
+Table of Contents
15194
 
+
15195
 
+   1.  Introduction and Overview  . . . . . . . . . . . . . . . . . .  4
15196
 
+   2.  Conventions Used in This Document  . . . . . . . . . . . . . .  4
15197
 
+   3.  Include Extension  . . . . . . . . . . . . . . . . . . . . . .  4
15198
 
+     3.1.  General Considerations . . . . . . . . . . . . . . . . . .  4
15199
 
+     3.2.  Control Structure include  . . . . . . . . . . . . . . . .  5
15200
 
+     3.3.  Control Structure return . . . . . . . . . . . . . . . . .  8
15201
 
+     3.4.  Interaction with Variables . . . . . . . . . . . . . . . .  8
15202
 
+       3.4.1.  Control Structure global . . . . . . . . . . . . . . .  9
15203
 
+       3.4.2.  Variables Namespace global . . . . . . . . . . . . . . 10
15204
 
+   4.  Security Considerations  . . . . . . . . . . . . . . . . . . . 10
15205
 
+   5.  IANA Considerations  . . . . . . . . . . . . . . . . . . . . . 11
15206
 
+     5.1.  "include" Extension Registration . . . . . . . . . . . . . 11
15207
 
+   6.  Normative References . . . . . . . . . . . . . . . . . . . . . 11
15208
 
+   Appendix A.  Acknowledgments . . . . . . . . . . . . . . . . . . . 11
15209
 
+   Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . . 11
15210
 
+
15211
 
+
15212
 
+
15213
 
+
15214
 
+
15215
 
+
15216
 
+
15217
 
+
15218
 
+
15219
 
+
15220
 
+
15221
 
+
15222
 
+
15223
 
+
15224
 
+
15225
 
+
15226
 
+
15227
 
+
15228
 
+
15229
 
+Daboo & Stone          Expires September 30, 2009               [Page 3]
15230
 
+
15231
 
+Internet-Draft          Sieve Extension: Include              March 2009
15232
 
+
15233
 
+
15234
 
+1.  Introduction and Overview
15235
 
+
15236
 
+   It's convenient to be able to break SIEVE [RFC5228] scripts down into
15237
 
+   smaller components which can be reused in a variety of different
15238
 
+   circumstances.  For example, users may want to have a default script
15239
 
+   and a special 'vacation' script, the latter being activated when the
15240
 
+   user goes on vacation.  In that case the default actions should
15241
 
+   continue to be run, but a vacation command should be executed first.
15242
 
+   One option is to edit the default script to add or remove the
15243
 
+   vacation command as needed.  Another is to have a vacation script
15244
 
+   that simply has a vacation command and then includes the default
15245
 
+   script.
15246
 
+
15247
 
+
15248
 
+2.  Conventions Used in This Document
15249
 
+
15250
 
+   The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
15251
 
+   "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
15252
 
+   document are to be interpreted as described in [RFC2119].
15253
 
+
15254
 
+   Conventions for notations are as in SIEVE [RFC5228] Section 1.1.
15255
 
+
15256
 
+
15257
 
+3.  Include Extension
15258
 
+
15259
 
+3.1.  General Considerations
15260
 
+
15261
 
+   Sieve implementations that implement the "include", "return", and
15262
 
+   "global" commands described below have an identifier of "include" for
15263
 
+   use with the capability mechanism.  If any of the "include",
15264
 
+   "return", or "global" commands are used in a script, the "include"
15265
 
+   capability MUST be listed in the "require" statement in that script.
15266
 
+
15267
 
+   Sieve implementations must track the use of actions in included
15268
 
+   scripts so that implicit "keep" behavior can be properly determined
15269
 
+   based on whether any actions have executed in any script.
15270
 
+
15271
 
+   Sieve implementations are allowed to limit the total number of nested
15272
 
+   included scripts, but MUST provide for a total of at least three
15273
 
+   levels of nested scripts including the top-level script.  An error
15274
 
+   MUST be generated either when the script is uploaded to the Sieve
15275
 
+   repository, or when the script is executed, if any nesting limit is
15276
 
+   exceeded.  If such an error is detected whilst processing a Sieve
15277
 
+   script, an implicit "keep" action MUST be executed to prevent loss of
15278
 
+   any messages.
15279
 
+
15280
 
+   Sieve implementations MUST ensure that recursive includes are not
15281
 
+   possible.  For example, if script "A" includes script "B", and script
15282
 
+
15283
 
+
15284
 
+
15285
 
+Daboo & Stone          Expires September 30, 2009               [Page 4]
15286
 
+
15287
 
+Internet-Draft          Sieve Extension: Include              March 2009
15288
 
+
15289
 
+
15290
 
+   "B" includes script "A" an error MUST be generated either when the
15291
 
+   script is uploaded to the Sieve repository, or when the script is
15292
 
+   executed.  If such an error is detected whilst processing a Sieve
15293
 
+   script, an implicit "keep" action MUST be executed to prevent loss of
15294
 
+   any messages.
15295
 
+
15296
 
+   Sieve implementations MUST handle missing scripts being referenced
15297
 
+   via an includes in an existing script.  An error MUST be generated
15298
 
+   when a missing included script is discovered during execution.  If
15299
 
+   such an error is detected an implicit "keep" action MUST be executed
15300
 
+   to prevent loss of any messages.
15301
 
+
15302
 
+   If the Sieve "variables" extension [RFC5229] is present, an issue
15303
 
+   arises with the "scope" of variables defined in scripts that may
15304
 
+   include each other.  For example, if a script defines the variable
15305
 
+   "${status}" with one particular meaning or usage, and another defines
15306
 
+   "${status}" with a different meaning, then if one script includes the
15307
 
+   other there is an issue as to which "${status}" is being referenced.
15308
 
+   To solve this problem, Sieve implementations MUST follow the scoping
15309
 
+   rules defined in Section 3.4 and support the "global" command defined
15310
 
+   there.
15311
 
+
15312
 
+3.2.  Control Structure include
15313
 
+
15314
 
+      Usage:   include [LOCATION] [ONCE] <value: string>
15315
 
+
15316
 
+               LOCATION = ":personal" / ":global"
15317
 
+
15318
 
+               ONCE = ":once"
15319
 
+
15320
 
+   The "include" command takes an optional "location" parameter, an
15321
 
+   optional ":once" parameter, and a single string argument representing
15322
 
+   the name of the script to include for processing at that point.
15323
 
+
15324
 
+   The "location" parameter MUST default to ":personal" if not
15325
 
+   specified.  The "location" has the following meanings:
15326
 
+
15327
 
+   :personal
15328
 
+      Indicates that the named script is stored in the user's own
15329
 
+      personal (private) Sieve repository.
15330
 
+   :global
15331
 
+      Indicates that the named script is stored in a site-wide Sieve
15332
 
+      repository, accessible to all users of the Sieve system.
15333
 
+
15334
 
+   The ":once" parameter tells the interpreter only to include the Sieve
15335
 
+   script if it has not already been included at any other point during
15336
 
+   the script execution.  If the script has already been included,
15337
 
+   processing continues immediately following the include command.
15338
 
+
15339
 
+
15340
 
+
15341
 
+Daboo & Stone          Expires September 30, 2009               [Page 5]
15342
 
+
15343
 
+Internet-Draft          Sieve Extension: Include              March 2009
15344
 
+
15345
 
+
15346
 
+   Implementations MUST NOT generate an error if an "include :once"
15347
 
+   command names a script whose inclusion would be recursive; in this
15348
 
+   case, the script MUST be considered previously included and therefore
15349
 
+   "include :once" will not include it again.
15350
 
+
15351
 
+   Note: It is RECOMMENDED that script authors / generators use this
15352
 
+   parameter only when including a script that performs general duties
15353
 
+   such as declaring global variables and making sanity checks of the
15354
 
+   environment.
15355
 
+
15356
 
+   The included script MUST be a valid Sieve script, including having
15357
 
+   necessary "require" statements for all optional capabilities used by
15358
 
+   the script.  The scope of a "require" statement in an included script
15359
 
+   is for that script only, not the including script.  For example, if
15360
 
+   script "A" includes script "B", and script "B" uses the "fileinto"
15361
 
+   extension, script "B" must have a "require" statement for "fileinto",
15362
 
+   irrespective of whether script "A" has one.  In addition, if script
15363
 
+   "A" does not have a "require" statement for "fileinto", "fileinto"
15364
 
+   cannot be used anywhere in script "A", even after inclusion of script
15365
 
+   "B".
15366
 
+
15367
 
+   A "stop" command in an included script MUST stop all script
15368
 
+   processing, including the processing of the scripts that include the
15369
 
+   current one.  The "return" command (described below) stops processing
15370
 
+   of the current script only, and allows the scripts that include it to
15371
 
+   continue.
15372
 
+
15373
 
+   Examples:
15374
 
+
15375
 
+   The user has four scripts stored in their personal repository:
15376
 
+
15377
 
+   "default"
15378
 
+
15379
 
+      This is the default active script that includes several others.
15380
 
+
15381
 
+      require ["include"];
15382
 
+
15383
 
+      include :personal "always_allow";
15384
 
+      include :global "spam_tests";
15385
 
+      include :personal "spam_tests";
15386
 
+      include :personal "mailing_lists";
15387
 
+
15388
 
+   Personal script "always_allow"
15389
 
+
15390
 
+      This script special cases some correspondent email addresses and
15391
 
+      makes sure any message containing those addresses are always kept.
15392
 
+
15393
 
+
15394
 
+
15395
 
+
15396
 
+
15397
 
+Daboo & Stone          Expires September 30, 2009               [Page 6]
15398
 
+
15399
 
+Internet-Draft          Sieve Extension: Include              March 2009
15400
 
+
15401
 
+
15402
 
+      if header :is "From" "boss@example.com"
15403
 
+      {
15404
 
+          keep;
15405
 
+      }
15406
 
+      elsif header :is "From" "ceo@example.com"
15407
 
+      {
15408
 
+          keep;
15409
 
+      }
15410
 
+
15411
 
+   Personal script "spam_tests"
15412
 
+
15413
 
+      This script does some user-specific spam tests to catch spam
15414
 
+      messages not caught by the site-wide spam tests.
15415
 
+
15416
 
+      require ["reject"];
15417
 
+
15418
 
+      if header :contains "Subject" "XXXX"
15419
 
+      {
15420
 
+          reject;
15421
 
+      }
15422
 
+      elsif header :is "From" "money@example.com"
15423
 
+      {
15424
 
+          reject;
15425
 
+      }
15426
 
+
15427
 
+   Personal script "mailing_lists"
15428
 
+
15429
 
+      This script looks for messages from different mailing lists and
15430
 
+      files each into a mailbox specific to the mailing list.
15431
 
+
15432
 
+      require ["fileinto"];
15433
 
+
15434
 
+      if header :is "Sender" "owner-ietf-mta-filters@imc.org"
15435
 
+      {
15436
 
+          fileinto "lists.sieve";
15437
 
+      }
15438
 
+      elsif header :is "Sender" "owner-ietf-imapext@imc.org"
15439
 
+      {
15440
 
+          fileinto "lists.imapext";
15441
 
+      }
15442
 
+
15443
 
+   There is one script stored in the global repository:
15444
 
+
15445
 
+   Site script "spam_tests"
15446
 
+
15447
 
+      This script does some site-wide spam tests which any user at the
15448
 
+      site can include in their own scripts at a suitable point.  The
15449
 
+      script content is kept up to date by the site administrator.
15450
 
+
15451
 
+
15452
 
+
15453
 
+Daboo & Stone          Expires September 30, 2009               [Page 7]
15454
 
+
15455
 
+Internet-Draft          Sieve Extension: Include              March 2009
15456
 
+
15457
 
+
15458
 
+      require ["reject"];
15459
 
+
15460
 
+      if anyof (header :contains "Subject" "$$",
15461
 
+                header :contains "Subject" "Make money")
15462
 
+      {
15463
 
+          reject;
15464
 
+      }
15465
 
+
15466
 
+   The "include" command may appear anywhere in the script where a
15467
 
+   control structure is legal.
15468
 
+
15469
 
+   Example:
15470
 
+
15471
 
+      require ["include"];
15472
 
+
15473
 
+      if anyof (header :contains "Subject" "$$",
15474
 
+                header :contains "Subject" "Make money")
15475
 
+      {
15476
 
+          include "my_reject_script";
15477
 
+      }
15478
 
+
15479
 
+3.3.  Control Structure return
15480
 
+
15481
 
+      Usage: return
15482
 
+
15483
 
+   The "return" command stops processing of the currently included
15484
 
+   script only and returns processing control to the script which
15485
 
+   includes it.  If used in the main script (i.e. not in an included
15486
 
+   script), it has the same effect as the "stop" command, including the
15487
 
+   appropriate "keep" action if no other actions have been executed up
15488
 
+   to that point.
15489
 
+
15490
 
+3.4.  Interaction with Variables
15491
 
+
15492
 
+   In order to avoid problems of variables in an included script
15493
 
+   "overwriting" those from the script that includes it, this
15494
 
+   specification requires that all variables defined in a script MUST be
15495
 
+   kept "private" to that script by default - i.e. they are not
15496
 
+   "visible" to other scripts.  This ensures that two script authors
15497
 
+   cannot inadvertently cause problems by choosing the same name for a
15498
 
+   variable.
15499
 
+
15500
 
+   However, sometimes there is a need to make a variable defined in one
15501
 
+   script available to others.  This specification defines the new
15502
 
+   command "global" to declare that a variable is shared among scripts.
15503
 
+   Effectively, two namespaces are defined: one local to the current
15504
 
+   script, and another shared among all scripts.  Implementations MUST
15505
 
+   allow a non-global variable to have the same name as a global
15506
 
+
15507
 
+
15508
 
+
15509
 
+Daboo & Stone          Expires September 30, 2009               [Page 8]
15510
 
+
15511
 
+Internet-Draft          Sieve Extension: Include              March 2009
15512
 
+
15513
 
+
15514
 
+   variable but have no interaction between them.
15515
 
+
15516
 
+3.4.1.  Control Structure global
15517
 
+
15518
 
+      Usage:   global <value: string-list>
15519
 
+
15520
 
+   The "global" command contains a string list argument that defines one
15521
 
+   or more names of variables to be stored in the global variable space.
15522
 
+
15523
 
+   The "global" command, if present, MUST be used immediately after any
15524
 
+   "require" commands (at least one of which will be present listing the
15525
 
+   "include" extension).  Multiple "global" commands are allowed.  An
15526
 
+   error occurs if an "global" command appears after a command other
15527
 
+   than "require" or "global".  Use of the "global" command makes the
15528
 
+   listed variables immediately available for use in the body of the
15529
 
+   script that uses it.
15530
 
+
15531
 
+   If a "global" command lists a variable that has not been defined in
15532
 
+   the global namespace, the name of the variable is nonetheless marked
15533
 
+   as global, and any subsequent "set" command will set the value of the
15534
 
+   variable in global scope.
15535
 
+
15536
 
+   Interpretation of a string containing a variable marked as global,
15537
 
+   but without any value set, SHALL behave as any other access to an
15538
 
+   unknown variable, as specified in Section 3 of [RFC5229] (that is,
15539
 
+   the unknown variable reference evaltuates to an empty string).
15540
 
+
15541
 
+   Example:
15542
 
+
15543
 
+      require ["variables", "include"];
15544
 
+      global "test";
15545
 
+      global "test-mailbox";
15546
 
+
15547
 
+      # The included script may contain repetitive code that is
15548
 
+      # effectively a subroutine that can be factored out.
15549
 
+      set "test" "$$"
15550
 
+      include "spam_filter_script";
15551
 
+
15552
 
+      set "test" "Make money"
15553
 
+      include "spam_filter_script";
15554
 
+
15555
 
+      # Message will be filed according to the test that matched last.
15556
 
+      if string :count "${test-mailbox}" "1"
15557
 
+      {
15558
 
+          fileinto "INBOX${test-mailbox}";
15559
 
+          stop;
15560
 
+      }
15561
 
+
15562
 
+
15563
 
+
15564
 
+
15565
 
+Daboo & Stone          Expires September 30, 2009               [Page 9]
15566
 
+
15567
 
+Internet-Draft          Sieve Extension: Include              March 2009
15568
 
+
15569
 
+
15570
 
+      # If nothing matched, the message is implicitly kept.
15571
 
+
15572
 
+                               Active script
15573
 
+
15574
 
+
15575
 
+      require ["variables", "include"];
15576
 
+      global ["test", "test-mailbox"];
15577
 
+
15578
 
+      if header :contains "Subject" "${test}"
15579
 
+      {
15580
 
+          set "test-mailbox" "spam-${test};
15581
 
+      }
15582
 
+
15583
 
+                            spam_filter_script
15584
 
+
15585
 
+3.4.2.  Variables Namespace global
15586
 
+
15587
 
+   In addition to the "global" command, this document defines the
15588
 
+   variables namespace "global", per [RFC5229], Section 3.
15589
 
+
15590
 
+   Example:
15591
 
+
15592
 
+      require ["variables", "include"];
15593
 
+
15594
 
+      set "global.i_am_on_vacation" "1";
15595
 
+
15596
 
+   [[[ Does it make sense to have this form instead of the "global"
15597
 
+   command?  Does it make sense to have both?  If both, it would make
15598
 
+   sense that the two syntaxes reference the same set of variables.  By
15599
 
+   way of example:
15600
 
+
15601
 
+      require ["variables", "include"];
15602
 
+      global "i_am_on_vacation";
15603
 
+
15604
 
+      set "global.i_am_on_vacation" "1";
15605
 
+
15606
 
+      if string :is "${i_am_on_vacation}" "1"
15607
 
+      {
15608
 
+          vacation "It's true, I am on vacation."
15609
 
+      }
15610
 
+
15611
 
+   ]]]
15612
 
+
15613
 
+
15614
 
+4.  Security Considerations
15615
 
+
15616
 
+   Sieve implementations MUST ensure adequate security for the global
15617
 
+   script repository to prevent unauthorized changes to global scripts.
15618
 
+
15619
 
+
15620
 
+
15621
 
+Daboo & Stone          Expires September 30, 2009              [Page 10]
15622
 
+
15623
 
+Internet-Draft          Sieve Extension: Include              March 2009
15624
 
+
15625
 
+
15626
 
+   Beyond that, the "include" extension does not raise any security
15627
 
+   considerations that are not present in the base Sieve protocol, and
15628
 
+   these issues are discussed in Sieve.
15629
 
+
15630
 
+
15631
 
+5.  IANA Considerations
15632
 
+
15633
 
+   The following template specifies the IANA registration of the Sieve
15634
 
+   extension specified in this document:
15635
 
+
15636
 
+5.1.  "include" Extension Registration
15637
 
+
15638
 
+   Capability name: include
15639
 
+   Description:     add the "include" command to execute other Sieve
15640
 
+                    scripts.
15641
 
+   RFC number:      this RFC
15642
 
+   Contact address: the Sieve discussion list <ietf-mta-filters@imc.org>
15643
 
+
15644
 
+
15645
 
+6.  Normative References
15646
 
+
15647
 
+   [RFC2119]  Bradner, S., "Key words for use in RFCs to Indicate
15648
 
+              Requirement Levels", BCP 14, RFC 2119, March 1997.
15649
 
+
15650
 
+   [RFC5228]  Guenther, P. and T. Showalter, "Sieve: An Email Filtering
15651
 
+              Language", RFC 5228, January 2008.
15652
 
+
15653
 
+   [RFC5229]  Homme, K., "Sieve Email Filtering: Variables Extension",
15654
 
+              RFC 5229, January 2008.
15655
 
+
15656
 
+
15657
 
+Appendix A.  Acknowledgments
15658
 
+
15659
 
+   Thanks to Ken Murchison, Rob Siemborski, Alexey Melnikov, Marc Mutz
15660
 
+   and Kjetil Torgrim Homme for comments and corrections.
15661
 
+
15662
 
+
15663
 
+Authors' Addresses
15664
 
+
15665
 
+   Cyrus Daboo
15666
 
+
15667
 
+   Email: cyrus@daboo.name
15668
 
+
15669
 
+
15670
 
+   Aaron Stone
15671
 
+
15672
 
+   Email: aaron@serendipity.palo-alto.ca.us
15673
 
+
15674
 
+
15675
 
+
15676
 
+
15677
 
+Daboo & Stone          Expires September 30, 2009              [Page 11]
15678
 
+
15679
 
diff -urN dovecot-1.2.4/dovecot-libsieve/doc/rfc/draft-murchison-sieve-regex-07.txt dovecot-1.2.4.debian/dovecot-libsieve/doc/rfc/draft-murchison-sieve-regex-07.txt
15680
 
--- dovecot-1.2.4/dovecot-libsieve/doc/rfc/draft-murchison-sieve-regex-07.txt   1970-01-01 01:00:00.000000000 +0100
15681
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/doc/rfc/draft-murchison-sieve-regex-07.txt    2008-08-25 10:25:08.000000000 +0200
15682
 
@@ -0,0 +1,451 @@
15683
 
+
15684
 
+
15685
 
+
15686
 
+
15687
 
+
15688
 
+
15689
 
+
15690
 
+Internet Draft                                               K. Murchison
15691
 
+Category: Standards Track                              Oceana Matrix Ltd.
15692
 
+Expires: May 23, 2004                                    18 November 2003
15693
 
+
15694
 
+
15695
 
+            Sieve Email Filtering -- Regular Expression Extension
15696
 
+
15697
 
+                    <draft-murchison-sieve-regex-07.txt>
15698
 
+
15699
 
+Status of this Memo
15700
 
+
15701
 
+    This document is an Internet-Draft and is subject to all provisions
15702
 
+    of Section 10 of RFC2026.
15703
 
+
15704
 
+    Internet-Drafts are working documents of the Internet Engineering
15705
 
+    Task Force (IETF), its areas, and its working groups.  Note that
15706
 
+    other groups may also distribute working documents as
15707
 
+    Internet-Drafts.
15708
 
+
15709
 
+    Internet-Drafts are draft documents valid for a maximum of six months
15710
 
+    and may be updated, replaced, or obsoleted by other documents at any
15711
 
+    time.  It is inappropriate to use Internet-Drafts as reference
15712
 
+    material or to cite them other than as "work in progress."
15713
 
+
15714
 
+    The list of current Internet-Drafts can be accessed at
15715
 
+    http://www.ietf.org/1id-abstracts.html
15716
 
+
15717
 
+    The list of Internet-Draft Shadow Directories can be accessed at
15718
 
+    http://www.ietf.org/shadow.html
15719
 
+
15720
 
+Copyright Notice
15721
 
+
15722
 
+    Copyright (C) The Internet Society (2003). All Rights Reserved.
15723
 
+
15724
 
+
15725
 
+Abstract
15726
 
+
15727
 
+    In some cases, it is desirable to have a string matching mechanism
15728
 
+    which is more powerful than a simple exact match, a substring match
15729
 
+    or a glob-style wildcard match.  The regular expression matching
15730
 
+    mechanism defined in this draft should allow users to isolate just
15731
 
+    about any string or address in a message header or envelope.
15732
 
+
15733
 
+
15734
 
+
15735
 
+
15736
 
+
15737
 
+
15738
 
+
15739
 
+
15740
 
+
15741
 
+Expires: May 23, 2004         Murchison                         [Page 1]
15742
 
+
15743
 
+Internet Draft          Sieve -- Regex Extension       November 18, 2004
15744
 
+
15745
 
+
15746
 
+                           Table of Contents
15747
 
+
15748
 
+
15749
 
+
15750
 
+0.     Meta-information on this draft  . . . . . . . . . . . . . . .   3
15751
 
+
15752
 
+0.1.   Discussion  . . . . . . . . . . . . . . . . . . . . . . . . .   3
15753
 
+
15754
 
+0.2.   Noted Changes Since -06 . . . . . . . . . . . . . . . . . . .   3
15755
 
+
15756
 
+0.3.   Open Issues . . . . . . . . . . . . . . . . . . . . . . . . .   3
15757
 
+
15758
 
+1.     Introduction  . . . . . . . . . . . . . . . . . . . . . . . .   4
15759
 
+
15760
 
+2.     Capability Identifier . . . . . . . . . . . . . . . . . . . .   4
15761
 
+
15762
 
+3.     Regex Match Type  . . . . . . . . . . . . . . . . . . . . . .   4
15763
 
+
15764
 
+4.     Security Considerations . . . . . . . . . . . . . . . . . . .   6
15765
 
+
15766
 
+5.     IANA Considerations . . . . . . . . . . . . . . . . . . . . .   6
15767
 
+
15768
 
+6.     Normative References  . . . . . . . . . . . . . . . . . . . .   7
15769
 
+
15770
 
+7.     Acknowledgments . . . . . . . . . . . . . . . . . . . . . . .   7
15771
 
+
15772
 
+8.     Intellectual Property Statement . . . . . . . . . . . . . . .   7
15773
 
+
15774
 
+9.     Author's Address  . . . . . . . . . . . . . . . . . . . . . .   8
15775
 
+
15776
 
+10.    Full Copyright Statement  . . . . . . . . . . . . . . . . . .   8
15777
 
+
15778
 
+
15779
 
+
15780
 
+
15781
 
+
15782
 
+
15783
 
+
15784
 
+
15785
 
+
15786
 
+
15787
 
+
15788
 
+
15789
 
+
15790
 
+
15791
 
+
15792
 
+
15793
 
+
15794
 
+
15795
 
+
15796
 
+
15797
 
+Expires: May 23, 2004         Murchison                         [Page 2]
15798
 
+
15799
 
+Internet Draft          Sieve -- Regex Extension       November 18, 2004
15800
 
+
15801
 
+
15802
 
+
15803
 
+0.     Meta-information on this draft
15804
 
+
15805
 
+    This information is intended to facilitate discussion.  It will be
15806
 
+    removed when this document leaves the Internet-Draft stage.
15807
 
+
15808
 
+
15809
 
+0.1.   Discussion
15810
 
+
15811
 
+    This draft is intended to be an extension to the Sieve mail filtering
15812
 
+    language, available from the RFC repository as
15813
 
+    <ftp://ftp.ietf.org/rfc/rfc3028.txt>.
15814
 
+
15815
 
+    This draft and the Sieve language itself are being discussed on the
15816
 
+    MTA Filters mailing list at <ietf-mta-filters@imc.org>.  Subscription
15817
 
+    requests can be sent to <ietf-mta-filters-request@imc.org> (send an
15818
 
+    email message with the word "subscribe" in the body).  More
15819
 
+    information on the mailing list along with a WWW archive of back
15820
 
+    messages is available at <http://www.imc.org/ietf-mta-filters/>.
15821
 
+
15822
 
+
15823
 
+0.2.   Noted Changes Since -06
15824
 
+
15825
 
+    Added more open issues.
15826
 
+
15827
 
+    Added IANA considerations.
15828
 
+
15829
 
+    Editorial changes.
15830
 
+
15831
 
+
15832
 
+0.3.   Open Issues
15833
 
+
15834
 
+    The major open issue with this draft is what to do, if anything,
15835
 
+    about localization/internationalization.  Are [POSIX.2] collating
15836
 
+    sequences and character equivalents sufficient?  Should we reference
15837
 
+    the unicode technical specification?  Should we punt and publish the
15838
 
+    document as experimental?
15839
 
+
15840
 
+    Should we allow shorthands such as \b (word boundary) and \w (word
15841
 
+    character)?
15842
 
+
15843
 
+    Should we allow backreferences (useful for matching double words,
15844
 
+    etc.)?
15845
 
+
15846
 
+    Should we integrate with variables, so that $1, $2, ...  correspond
15847
 
+    to the first, second, ... groups within the regex?
15848
 
+
15849
 
+
15850
 
+
15851
 
+
15852
 
+
15853
 
+Expires: May 23, 2004         Murchison                         [Page 3]
15854
 
+
15855
 
+Internet Draft          Sieve -- Regex Extension       November 18, 2004
15856
 
+
15857
 
+
15858
 
+1.  Introduction
15859
 
+
15860
 
+    This is an extension to the Sieve language defined by [SIEVE] for
15861
 
+    comparing strings to regular expressions.
15862
 
+
15863
 
+    Conventions for notations are as in [SIEVE] section 1.1, including
15864
 
+    use of [KEYWORDS].
15865
 
+
15866
 
+
15867
 
+2.  Capability Identifier
15868
 
+
15869
 
+    The capability string associated with the extension defined in this
15870
 
+    document is "regex".
15871
 
+
15872
 
+
15873
 
+3.  Regex Match Type
15874
 
+
15875
 
+    Commands that support matching may take the optional tagged argument
15876
 
+    ":regex" to specify that a regular expression match should be
15877
 
+    performed.  The ":regex" match type is subject to the same rules and
15878
 
+    restrictions as the standard match types defined in [SIEVE].  For
15879
 
+    convenience, the "MATCH-TYPE" syntax element defined in [SIEVE] is
15880
 
+    augmented here as follows:
15881
 
+
15882
 
+         MATCH-TYPE  =/  ":regex"
15883
 
+
15884
 
+    Example:
15885
 
+
15886
 
+          require "regex";
15887
 
+
15888
 
+          # Try to catch unsolicited email.
15889
 
+          if anyof (
15890
 
+            # if a message is not to me (with optional +detail),
15891
 
+            not address :regex ["to", "cc", "bcc"]
15892
 
+              "me(\\+.*)?@company\\.com",
15893
 
+
15894
 
+            # or the subject is all uppercase (no lowercase)
15895
 
+            header :regex :comparator "i;octet" "subject"
15896
 
+              "^[^[:lower:]]+$" ) {
15897
 
+
15898
 
+            discard;     # junk it
15899
 
+          }
15900
 
+
15901
 
+    The ":regex" match type is compatible with both the "i;octet" and
15902
 
+    "i;ascii-casemap" comparators and may be used with them.
15903
 
+
15904
 
+    Implementations MUST support extended regular expressions (EREs) as
15905
 
+    defined by [POSIX.2].  Any regular expression not defined by
15906
 
+
15907
 
+
15908
 
+
15909
 
+Expires: May 23, 2004         Murchison                         [Page 4]
15910
 
+
15911
 
+Internet Draft          Sieve -- Regex Extension       November 18, 2004
15912
 
+
15913
 
+
15914
 
+    [POSIX.2], as well as [POSIX.2] basic regular expressions, word
15915
 
+    boundaries and backreferences are not supported by this extension.
15916
 
+    Implementations SHOULD reject regular expressions that are
15917
 
+    unsupported by this specification as a syntax error.
15918
 
+
15919
 
+    The following table provides a brief summary of the regular
15920
 
+    expressions that MUST be supported.  This table is presented here
15921
 
+    only as a guideline.  [POSIX.2] should be used as the definitive
15922
 
+    reference.
15923
 
+
15924
 
+
15925
 
+    +------------+-----------------------------------------------------+
15926
 
+    | Expression |  Pattern                                            |
15927
 
+    +------------+-----------------------------------------------------+
15928
 
+    |                Items to match a single character                 |
15929
 
+    +------------+-----------------------------------------------------+
15930
 
+    |     .      |  Match any single character except newline.         |
15931
 
+    |    [ ]     |  Bracket expression.  Match any one of the enclosed |
15932
 
+    |            |  characters.  A hypen (-) indicates a range of      |
15933
 
+    |            |  consecutive characters.                            |
15934
 
+    |   [^  ]    |  Negated bracket expression.  Match any one         |
15935
 
+    |            |  character NOT in the enclosed list.  A hypen (-)   |
15936
 
+    |            |  indicates a range of consecutive characters.       |
15937
 
+    |    \\      |  Escape the following special character (match      |
15938
 
+    |            |  the literal character).  Undefined for other       |
15939
 
+    |            |  characters.                                        |
15940
 
+    |            |  NOTE: Unlike [POSIX.2], a double-backslash is      |
15941
 
+    |            |  required as per section 2.4.2 of [SIEVE].          |
15942
 
+    +------------+-----------------------------------------------------+
15943
 
+    |   Items to be used within a bracket expression (localization)    |
15944
 
+    +------------+-----------------------------------------------------+
15945
 
+    |   [: :]    |  Character class (alnum, alpha, blank, cntrl,       |
15946
 
+    |            |  digit, graph, lower, print, punct, space,          |
15947
 
+    |            |  upper, xdigit).                                    |
15948
 
+    |   [= =]    |  Character equivalents.                             |
15949
 
+    |   [. .]    |  Collating sequence.                                |
15950
 
+    +------------+-----------------------------------------------------+
15951
 
+    |  Quantifiers - Items to count the preceding regular expression   |
15952
 
+    +------------+-----------------------------------------------------+
15953
 
+    |     ?      |  Match zero or one instances.                       |
15954
 
+    |     *      |  Match zero or more instances.                      |
15955
 
+    |     +      |  Match one or more instances.                       |
15956
 
+    |   {n,m}    |  Match any number of instances between              |
15957
 
+    |            |  n and m (inclusive).  {n} matches exactly n        |
15958
 
+    |            |  instances.  {n,} matches n or more instances.      |
15959
 
+    +------------+-----------------------------------------------------+
15960
 
+
15961
 
+
15962
 
+
15963
 
+
15964
 
+
15965
 
+Expires: May 23, 2004         Murchison                         [Page 5]
15966
 
+
15967
 
+Internet Draft          Sieve -- Regex Extension       November 18, 2004
15968
 
+
15969
 
+
15970
 
+    +------------+-----------------------------------------------------+
15971
 
+    | Expression |  Pattern                                            |
15972
 
+    +------------+-----------------------------------------------------+
15973
 
+    |              Anchoring - Items to match positions                |
15974
 
+    +------------+-----------------------------------------------------+
15975
 
+    |     ^      |  Match the beginning of the line or string.         |
15976
 
+    |     $      |  Match the end of the line or string.               |
15977
 
+    +------------+-----------------------------------------------------+
15978
 
+    |                        Other constructs                          |
15979
 
+    +------------+-----------------------------------------------------+
15980
 
+    |     |      |  Alternation.  Match either of the separated        |
15981
 
+    |            |  regular expressions.                               |
15982
 
+    |    ( )     |  Group the enclosed regular expression(s).          |
15983
 
+    +------------+-----------------------------------------------------+
15984
 
+
15985
 
+
15986
 
+4.  Security Considerations
15987
 
+
15988
 
+    Security considerations are discussed in [SIEVE].  It is believed
15989
 
+    that this extension doesn't introduce any additional security
15990
 
+    concerns.
15991
 
+
15992
 
+    However, a poor implementation COULD introduce security problems
15993
 
+    ranging from degradation of performance to denial of service.  If an
15994
 
+    implementation uses a third-party regular expression library, that
15995
 
+    library should be checked for potentially problematic regular
15996
 
+    expressions, such as "(.*)*".
15997
 
+
15998
 
+
15999
 
+5.  IANA Considerations
16000
 
+
16001
 
+    The following template specifies the IANA registration of the Sieve
16002
 
+    extension specified in this document:
16003
 
+
16004
 
+    To: iana@iana.org
16005
 
+    Subject: Registration of new Sieve extension
16006
 
+
16007
 
+    Capability name: regex
16008
 
+    Capability keyword: regex
16009
 
+    Capability arguments: N/A
16010
 
+    Standards Track/IESG-approved experimental RFC number: this RFC
16011
 
+    Person and email address to contact for further information:
16012
 
+
16013
 
+    Kenneth Murchison
16014
 
+    ken@oceana.com
16015
 
+
16016
 
+    This information should be added to the list of sieve extensions
16017
 
+    given on http://www.iana.org/assignments/sieve-extensions.
16018
 
+
16019
 
+
16020
 
+
16021
 
+Expires: May 23, 2004         Murchison                         [Page 6]
16022
 
+
16023
 
+Internet Draft          Sieve -- Regex Extension       November 18, 2004
16024
 
+
16025
 
+
16026
 
+6.
16027
 
+    Normative References
16028
 
+
16029
 
+     [KEYWORDS] Bradner, S., "Key words for use in RFCs to Indicate
16030
 
+         Requirement Levels", RFC 2119, March 1997.
16031
 
+
16032
 
+
16033
 
+     [SIEVE] Showalter, T., "Sieve: A Mail Filtering Language",
16034
 
+         RFC 3028, January 2001.
16035
 
+
16036
 
+
16037
 
+     [POSIX.2], "Portable Operating System Interface (POSIX). Part 2,
16038
 
+         Shell and utilities", National Institute of Standards and
16039
 
+         Technology (U.S.).
16040
 
+
16041
 
+
16042
 
+
16043
 
+7.  Acknowledgments
16044
 
+
16045
 
+    Thanks to Tim Showalter, Alexey Melnikov, Tony Hansen, Phil Pennock,
16046
 
+    Jutta Degener and Ned Freed for their help with this document.
16047
 
+
16048
 
+
16049
 
+8.  Intellectual Property Statement
16050
 
+
16051
 
+    The IETF takes no position regarding the validity or scope of any
16052
 
+    intellectual property or other rights that might be claimed to per�
16053
 
+    tain to the implementation or use of the technology described in
16054
 
+    this document or the extent to which any license under such rights
16055
 
+    might or might not be available; neither does it represent that it
16056
 
+    has made any effort to identify any such rights.  Information on the
16057
 
+    IETF's procedures with respect to rights in standards-track and
16058
 
+    standards-related documentation can be found in BCP-11.  Copies of
16059
 
+    claims of rights made available for publication and any assurances
16060
 
+    of licenses to be made available, or the result of an attempt made
16061
 
+    to obtain a general license or permission for the use of such pro�
16062
 
+    prietary rights by implementors or users of this specification can
16063
 
+    be obtained from the IETF Secretariat.
16064
 
+
16065
 
+    The IETF invites any interested party to bring to its attention any
16066
 
+    copyrights, patents or patent applications, or other proprietary
16067
 
+    rights which may cover technology that may be required to practice
16068
 
+    this standard.  Please address the information to the IETF Executive
16069
 
+    Director.
16070
 
+
16071
 
+
16072
 
+
16073
 
+
16074
 
+
16075
 
+
16076
 
+
16077
 
+Expires: May 23, 2004         Murchison                         [Page 7]
16078
 
+
16079
 
+Internet Draft          Sieve -- Regex Extension       November 18, 2004
16080
 
+
16081
 
+
16082
 
+9.  Author's Address
16083
 
+
16084
 
+    Kenneth Murchison
16085
 
+    Oceana Matrix Ltd.
16086
 
+    21 Princeton Place
16087
 
+    Orchard Park, NY  14127
16088
 
+
16089
 
+    Phone: (716) 662-8973
16090
 
+
16091
 
+    EMail: ken@oceana.com
16092
 
+
16093
 
+
16094
 
+10.
16095
 
+    Full Copyright Statement
16096
 
+
16097
 
+    Copyright (C) The Internet Society (2003). All Rights Reserved.
16098
 
+
16099
 
+    This document and translations of it may be copied and furnished to
16100
 
+    others, and derivative works that comment on or otherwise explain it
16101
 
+    or assist in its implmentation may be prepared, copied, published and
16102
 
+    distributed, in whole or in part, without restriction of any kind,
16103
 
+    provided that the above copyright notice and this paragraph are
16104
 
+    included on all such copies and derivative works.  However, this
16105
 
+    document itself may not be modified in any way, such as by removing
16106
 
+    the copyright notice or references to the Internet Society or other
16107
 
+    Internet organizations, except as needed for the  purpose of
16108
 
+    developing Internet standards in which case the procedures for
16109
 
+    copyrights defined in the Internet Standards process must be followed,
16110
 
+    or as required to translate it into languages other than English.
16111
 
+
16112
 
+    The limited permissions granted above are perpetual and will not be
16113
 
+    revoked by the Internet Society or its successors or assigns.
16114
 
+
16115
 
+    This document and the information contained herein is provided on an
16116
 
+    "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET
16117
 
+    ENGINEERING TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED,
16118
 
+    INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE
16119
 
+    INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
16120
 
+    WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
16121
 
+
16122
 
+
16123
 
+
16124
 
+
16125
 
+
16126
 
+
16127
 
+
16128
 
+
16129
 
+
16130
 
+
16131
 
+
16132
 
+
16133
 
+Expires: May 23, 2004         Murchison                         [Page 8]
16134
 
diff -urN dovecot-1.2.4/dovecot-libsieve/doc/rfc/environment.rfc5183.txt dovecot-1.2.4.debian/dovecot-libsieve/doc/rfc/environment.rfc5183.txt
16135
 
--- dovecot-1.2.4/dovecot-libsieve/doc/rfc/environment.rfc5183.txt      1970-01-01 01:00:00.000000000 +0100
16136
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/doc/rfc/environment.rfc5183.txt       2009-04-13 21:35:39.000000000 +0200
16137
 
@@ -0,0 +1,563 @@
16138
 
+
16139
 
+
16140
 
+
16141
 
+
16142
 
+
16143
 
+
16144
 
+Network Working Group                                           N. Freed
16145
 
+Request for Comments: 5183                              Sun Microsystems
16146
 
+Category: Standards Track                                       May 2008
16147
 
+
16148
 
+
16149
 
+              Sieve Email Filtering: Environment Extension
16150
 
+
16151
 
+Status of This Memo
16152
 
+
16153
 
+   This document specifies an Internet standards track protocol for the
16154
 
+   Internet community, and requests discussion and suggestions for
16155
 
+   improvements.  Please refer to the current edition of the "Internet
16156
 
+   Official Protocol Standards" (STD 1) for the standardization state
16157
 
+   and status of this protocol.  Distribution of this memo is unlimited.
16158
 
+
16159
 
+Abstract
16160
 
+
16161
 
+   This document describes the "environment" extension to the Sieve
16162
 
+   email filtering language.  The "environment" extension gives a Sieve
16163
 
+   script access to information about the Sieve interpreter itself,
16164
 
+   where it is running, and about any transport connection currently
16165
 
+   involved in transferring the message.
16166
 
+
16167
 
+1.  Introduction
16168
 
+
16169
 
+   Sieve [RFC5228] is a language for filtering email messages at or
16170
 
+   around the time of final delivery.  It is designed to be
16171
 
+   implementable on either a mail client or mail server.  It is suitable
16172
 
+   for running on a mail server where users may not be allowed to
16173
 
+   execute arbitrary programs, such as on black box Internet Message
16174
 
+   Access Protocol [RFC3501] servers, as it has no user-controlled loops
16175
 
+   or the ability to run external programs.
16176
 
+
16177
 
+   Although Sieve is intended to be independent of access protocol, mail
16178
 
+   architecture, and operating system, in some cases it is useful to
16179
 
+   allow scripts to access information about their execution context.
16180
 
+   The "environment" extension provides a new environment test that can
16181
 
+   be used to implement scripts that behave differently when moved from
16182
 
+   one system to another, when messages arrive from different remote
16183
 
+   sources or when otherwise operated in different contexts.
16184
 
+
16185
 
+2.  Conventions Used in This Document
16186
 
+
16187
 
+   The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
16188
 
+   "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
16189
 
+   document are to be interpreted as described in [RFC2119].
16190
 
+
16191
 
+
16192
 
+
16193
 
+
16194
 
+
16195
 
+Freed                       Standards Track                     [Page 1]
16196
 
+
16197
 
+RFC 5183              Sieve Environment Extension               May 2008
16198
 
+
16199
 
+
16200
 
+   The terms used to describe the various components of the Sieve
16201
 
+   language are taken from Section 1.1 of [RFC5228].
16202
 
+
16203
 
+   This document refers to the ABNF productions IPv4-address-literal,
16204
 
+   IPv6-address-literal, and General-address-literal defined in Section
16205
 
+   4.1.3 of [RFC2821].
16206
 
+
16207
 
+   The location item makes use of standard terms for email service
16208
 
+   components.  Additional information and background on these terms can
16209
 
+   be found in [EMAIL-ARCH].
16210
 
+
16211
 
+3.  Capability Identifiers
16212
 
+
16213
 
+   The capability string associated with the extension defined in this
16214
 
+   document is "environment".
16215
 
+
16216
 
+4.  Environment Test
16217
 
+
16218
 
+   Usage:   environment [COMPARATOR] [MATCH-TYPE]
16219
 
+                        <name: string>
16220
 
+                        <key-list: string-list>
16221
 
+
16222
 
+   The environment test retrieves the item of environment information
16223
 
+   specified by the name string and matches it to the values specified
16224
 
+   in the key-list argument.  The test succeeds if a match occurs.  The
16225
 
+   type of match defaults to ":is" and the default comparator is
16226
 
+   "i;ascii-casemap".
16227
 
+
16228
 
+   The current message is not a direct source of information for the
16229
 
+   environment test; the item of information specified by the name
16230
 
+   string is extracted from the script's operating environment and the
16231
 
+   key-list argument comes from the script.
16232
 
+
16233
 
+   The environment test MUST fail unconditionally if the specified
16234
 
+   information item does not exist.  A script MUST NOT fail with an
16235
 
+   error if the item does not exist.  This allows scripts to be written
16236
 
+   that handle nonexistent items gracefully.  In particular, the test:
16237
 
+
16238
 
+     if environment :contains "item" "" { ... }
16239
 
+
16240
 
+   only succeeds if "item" is known to the implementation, and always
16241
 
+   succeeds if it is.
16242
 
+
16243
 
+   The "relational" extension [RFC5231] adds a match type called
16244
 
+   ":count".  The count of an environment test is 0 if the environment
16245
 
+   information returned is the empty string, or 1 otherwise.
16246
 
+
16247
 
+
16248
 
+
16249
 
+
16250
 
+
16251
 
+Freed                       Standards Track                     [Page 2]
16252
 
+
16253
 
+RFC 5183              Sieve Environment Extension               May 2008
16254
 
+
16255
 
+
16256
 
+   Environment items can be standardized or vendor-defined.  An IANA
16257
 
+   registry is defined for both types of items.  Extensions designed for
16258
 
+   interoperable use SHOULD be defined in standards track or
16259
 
+   experimental RFCs.
16260
 
+
16261
 
+4.1.  Initial Standard Environment Items
16262
 
+
16263
 
+   The initial set of standardized environment items is as follows:
16264
 
+
16265
 
+    "domain"  => The primary DNS domain associated with the Sieve
16266
 
+                 execution context, usually but not always a proper
16267
 
+                 suffix of the host name.
16268
 
+
16269
 
+    "host"    => The fully-qualified domain name of the host where
16270
 
+                 the Sieve script is executing.
16271
 
+
16272
 
+    "location"
16273
 
+              => Sieve evaluation can be performed at various
16274
 
+                 different points as messages are processed.  This item
16275
 
+                 provides additional information about the type of
16276
 
+                 service that is evaluating the script.  Possible values
16277
 
+                 are "MTA", meaning the Sieve is being evaluated by a
16278
 
+                 Message Transfer Agent, "MDA", meaning evaluation is
16279
 
+                 being performed by a Mail Delivery Agent, "MUA",
16280
 
+                 meaning evaluation is being performed by a Mail User
16281
 
+                 Agent, and "MS", meaning evaluation is being performed
16282
 
+                 by a Message Store.  Additional information and
16283
 
+                 background on these terms can be found in
16284
 
+                 [EMAIL-ARCH].
16285
 
+
16286
 
+    "name"    => The product name associated with the Sieve interpreter.
16287
 
+
16288
 
+    "phase"   => The point relative to final delivery where the
16289
 
+                 Sieve script is being evaluated.  Possible values are
16290
 
+                 "pre", "during", and "post", referring respectively to
16291
 
+                 processing before, during, and after final delivery
16292
 
+                 has taken place.
16293
 
+
16294
 
+    "remote-host"
16295
 
+              => Host name of remote SMTP/LMTP/Submission client
16296
 
+                 expressed as a Fully Qualified Domain Name (FQDN),
16297
 
+                 if applicable and available.  The empty string will be
16298
 
+                 returned if for some reason this information cannot be
16299
 
+                 obtained for the current client.
16300
 
+
16301
 
+
16302
 
+
16303
 
+
16304
 
+
16305
 
+
16306
 
+
16307
 
+Freed                       Standards Track                     [Page 3]
16308
 
+
16309
 
+RFC 5183              Sieve Environment Extension               May 2008
16310
 
+
16311
 
+
16312
 
+    "remote-ip"
16313
 
+              => IP address of remote SMTP/LMTP/Submission client, if
16314
 
+                 applicable and available.  IPv4, IPv6, and other types
16315
 
+                 of addresses are respectively represented in the
16316
 
+                 formats defined by the IPv4-address-literal,
16317
 
+                 IPv6-address-literal, and General-address-literal
16318
 
+                 productions defined in Section 4.1.3 of [RFC2821].
16319
 
+
16320
 
+    "version" => The product version associated with the Sieve
16321
 
+                 interpreter.  The meaning of the product version string
16322
 
+                 is product-specific and should always be considered
16323
 
+                 in the context of the product name given by the
16324
 
+                 "name" item.
16325
 
+
16326
 
+   Implementations SHOULD support as many of the items on this initial
16327
 
+   list as possible.  Additional standardized items can only be defined
16328
 
+   in standards-track or experimental RFCs.
16329
 
+
16330
 
+4.2.  Vendor-defined Environment Items
16331
 
+
16332
 
+   Environment item names beginning with "vnd." represent vendor-defined
16333
 
+   extensions.  Such extensions are not defined by Internet standards or
16334
 
+   RFCs, but are still registered with IANA in order to prevent
16335
 
+   conflicts.
16336
 
+
16337
 
+4.3.  IANA Registration of Environment Items
16338
 
+
16339
 
+   A registry of environment items is provided by IANA.  Item names may
16340
 
+   be registered on a first-come, first-served basis.
16341
 
+
16342
 
+   Groups of items defined in a standards track or experimental RFC MAY
16343
 
+   choose to use a common name prefix of the form "name.", where "name"
16344
 
+   is a string that identifies the group of related items.
16345
 
+
16346
 
+   Items not defined in a standards track or experimental RFC MUST have
16347
 
+   a name that begins with the "vnd." prefix, and this prefix is
16348
 
+   followed by the name of the vendor or product, such as
16349
 
+   "vnd.acme.rocket-sled-status".
16350
 
+
16351
 
+
16352
 
+
16353
 
+
16354
 
+
16355
 
+
16356
 
+
16357
 
+
16358
 
+
16359
 
+
16360
 
+
16361
 
+
16362
 
+
16363
 
+Freed                       Standards Track                     [Page 4]
16364
 
+
16365
 
+RFC 5183              Sieve Environment Extension               May 2008
16366
 
+
16367
 
+
16368
 
+4.3.1.  Template for Environment Registrations
16369
 
+
16370
 
+   The following template is to be used for registering new Sieve
16371
 
+   environment item names with IANA.
16372
 
+
16373
 
+      To: iana@iana.org
16374
 
+      Subject: Registration of new Sieve environment item
16375
 
+
16376
 
+      Item name: [the string for use in the 'environment' test]
16377
 
+      Description:     [a brief description of the semantics of the
16378
 
+                        value the item returns]
16379
 
+
16380
 
+      RFC number:      [for extensions published as RFCs]
16381
 
+      Contact address: [email and/or physical address to contact for
16382
 
+                        additional information]
16383
 
+
16384
 
+   Multiple items and descriptions MAY be specified in a single
16385
 
+   registration request.  Both standardized and vendor-defined items use
16386
 
+   this form.
16387
 
+
16388
 
+5.  Security Considerations
16389
 
+
16390
 
+   The environment extension may be used to obtain information about the
16391
 
+   system the Sieve implementation is running on.  This information in
16392
 
+   turn may reveal details about service provider or enterprise
16393
 
+   infrastructure.
16394
 
+
16395
 
+   An implementation can use any technique to determine the remote-host
16396
 
+   environment item defined in this specification, and the
16397
 
+   trustworthiness of the result will vary.  One common method will be
16398
 
+   to perform a PTR DNS lookup on the client IP address.  This
16399
 
+   information may come from an untrusted source.  For example, the
16400
 
+   test:
16401
 
+
16402
 
+     if environment :matches "remote-host" "*.example.com" { ... }
16403
 
+
16404
 
+   is not a good way to test whether the message came from "outside"
16405
 
+   because anyone who can create a PTR record can create one that refers
16406
 
+   to whatever domain they choose.
16407
 
+
16408
 
+   All of the security considerations given in the base Sieve
16409
 
+   specification also apply to this extension.
16410
 
+
16411
 
+
16412
 
+
16413
 
+
16414
 
+
16415
 
+
16416
 
+
16417
 
+
16418
 
+
16419
 
+Freed                       Standards Track                     [Page 5]
16420
 
+
16421
 
+RFC 5183              Sieve Environment Extension               May 2008
16422
 
+
16423
 
+
16424
 
+6.  IANA Considerations
16425
 
+
16426
 
+   The following template specifies the IANA registration of the Sieve
16427
 
+   extension specified in this document:
16428
 
+
16429
 
+      To: iana@iana.org
16430
 
+      Subject: Registration of new Sieve extension
16431
 
+
16432
 
+      Capability name: environment
16433
 
+      Description:     The "environment" extension provides a new
16434
 
+                       environment test that can be used to implement
16435
 
+                       scripts that behave differently when moved
16436
 
+                       from one system to another or otherwise
16437
 
+                       operated in different contexts.
16438
 
+      RFC number:      RFC 5183
16439
 
+      Contact address: Sieve discussion list <ietf-mta-filters@imc.org>
16440
 
+
16441
 
+   This specification also defines a new IANA registry for Sieve
16442
 
+   environment item names.  The specifics of this registry are given in
16443
 
+   Section 4.3.  The initial contents of the registry are given in the
16444
 
+   following section.
16445
 
+
16446
 
+
16447
 
+
16448
 
+
16449
 
+
16450
 
+
16451
 
+
16452
 
+
16453
 
+
16454
 
+
16455
 
+
16456
 
+
16457
 
+
16458
 
+
16459
 
+
16460
 
+
16461
 
+
16462
 
+
16463
 
+
16464
 
+
16465
 
+
16466
 
+
16467
 
+
16468
 
+
16469
 
+
16470
 
+
16471
 
+
16472
 
+
16473
 
+
16474
 
+
16475
 
+Freed                       Standards Track                     [Page 6]
16476
 
+
16477
 
+RFC 5183              Sieve Environment Extension               May 2008
16478
 
+
16479
 
+
16480
 
+6.1.  Initial Environment Item Registrations
16481
 
+
16482
 
+   The following template specifies the initial IANA registrations for
16483
 
+   the environment items defined in this document:
16484
 
+
16485
 
+      To: iana@iana.org
16486
 
+      Subject: Registration of new Sieve environment items
16487
 
+
16488
 
+      Capability name: domain
16489
 
+      Description:     The primary DNS domain associated with the Sieve
16490
 
+                       execution context, usually but not always a
16491
 
+                       proper suffix of the host name.
16492
 
+
16493
 
+      Capability name: host
16494
 
+      Description:     The fully-qualified domain name of the host
16495
 
+                       where the Sieve script is executing.
16496
 
+
16497
 
+      Capability name: location
16498
 
+      Description:     Type of service executing the Sieve script.
16499
 
+
16500
 
+      Capability name: name
16501
 
+      Description:     The product name associated with the Sieve
16502
 
+                       interpreter.
16503
 
+
16504
 
+      Capability name: phase
16505
 
+      Description:     Point relative to final delivery at which the
16506
 
+                       Sieve script is being evaluated.
16507
 
+
16508
 
+      Capability name: remote-host
16509
 
+      Description:     Host name of remote SMTP client, if applicable
16510
 
+                       and available.
16511
 
+
16512
 
+      Capability name: remote-ip
16513
 
+      Description:     IP address of remote SMTP client, if applicable
16514
 
+                       and available.
16515
 
+
16516
 
+      Capability name: version
16517
 
+      Description:     The product version associated with the Sieve
16518
 
+                       interpreter.
16519
 
+
16520
 
+      RFC number:      RFC 5183
16521
 
+      Contact address: Sieve discussion list <ietf-mta-filters@imc.org>
16522
 
+
16523
 
+
16524
 
+
16525
 
+
16526
 
+
16527
 
+
16528
 
+
16529
 
+
16530
 
+
16531
 
+Freed                       Standards Track                     [Page 7]
16532
 
+
16533
 
+RFC 5183              Sieve Environment Extension               May 2008
16534
 
+
16535
 
+
16536
 
+7.  References
16537
 
+
16538
 
+7.1.  Normative references
16539
 
+
16540
 
+   [RFC2119]     Bradner, S., "Key words for use in RFCs to Indicate
16541
 
+                 Requirement Levels", BCP 14, RFC 2119, March 1997.
16542
 
+
16543
 
+   [RFC2821]     Klensin, J., "Simple Mail Transfer Protocol", RFC 2821,
16544
 
+                 April 2001.
16545
 
+
16546
 
+   [RFC5228]     Guenther, P. and T. Showalter, "Sieve: An Email
16547
 
+                 Filtering Language", RFC 5228, January 2008.
16548
 
+
16549
 
+   [RFC5231]     Segmuller, W. and B. Leiba, "Sieve Email Filtering:
16550
 
+                 Relational Extension", RFC 5231, January 2008.
16551
 
+
16552
 
+7.2.  Informative references
16553
 
+
16554
 
+   [EMAIL-ARCH]  Crocker, D., "Internet Mail Architecture", Work
16555
 
+                 in Progress, February 2008.
16556
 
+
16557
 
+   [RFC3501]     Crispin, M., "INTERNET MESSAGE ACCESS PROTOCOL -
16558
 
+                 VERSION 4rev1", RFC 3501, March 2003.
16559
 
+
16560
 
+
16561
 
+
16562
 
+
16563
 
+
16564
 
+
16565
 
+
16566
 
+
16567
 
+
16568
 
+
16569
 
+
16570
 
+
16571
 
+
16572
 
+
16573
 
+
16574
 
+
16575
 
+
16576
 
+
16577
 
+
16578
 
+
16579
 
+
16580
 
+
16581
 
+
16582
 
+
16583
 
+
16584
 
+
16585
 
+
16586
 
+
16587
 
+Freed                       Standards Track                     [Page 8]
16588
 
+
16589
 
+RFC 5183              Sieve Environment Extension               May 2008
16590
 
+
16591
 
+
16592
 
+Appendix A.  Acknowledgements
16593
 
+
16594
 
+   Brian Carpenter, Dave Crocker, Cyrus Daboo, Philip Guenther, Kjetil
16595
 
+   Torgrim Homme, John Klensin, Mark Mallett, Alexey Melnikov, and
16596
 
+   Dilyan Palauzo provided helpful suggestions and corrections.
16597
 
+
16598
 
+Author's Address
16599
 
+
16600
 
+   Ned Freed
16601
 
+   Sun Microsystems
16602
 
+   3401 Centrelake Drive, Suite 410
16603
 
+   Ontario, CA  92761-1205
16604
 
+   USA
16605
 
+
16606
 
+   Phone: +1 909 457 4293
16607
 
+   EMail: ned.freed@mrochek.com
16608
 
+
16609
 
+
16610
 
+
16611
 
+
16612
 
+
16613
 
+
16614
 
+
16615
 
+
16616
 
+
16617
 
+
16618
 
+
16619
 
+
16620
 
+
16621
 
+
16622
 
+
16623
 
+
16624
 
+
16625
 
+
16626
 
+
16627
 
+
16628
 
+
16629
 
+
16630
 
+
16631
 
+
16632
 
+
16633
 
+
16634
 
+
16635
 
+
16636
 
+
16637
 
+
16638
 
+
16639
 
+
16640
 
+
16641
 
+
16642
 
+
16643
 
+Freed                       Standards Track                     [Page 9]
16644
 
+
16645
 
+RFC 5183              Sieve Environment Extension               May 2008
16646
 
+
16647
 
+
16648
 
+Full Copyright Statement
16649
 
+
16650
 
+   Copyright (C) The IETF Trust (2008).
16651
 
+
16652
 
+   This document is subject to the rights, licenses and restrictions
16653
 
+   contained in BCP 78, and except as set forth therein, the authors
16654
 
+   retain all their rights.
16655
 
+
16656
 
+   This document and the information contained herein are provided on an
16657
 
+   "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS
16658
 
+   OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY, THE IETF TRUST AND
16659
 
+   THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS
16660
 
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF
16661
 
+   THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
16662
 
+   WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
16663
 
+
16664
 
+Intellectual Property
16665
 
+
16666
 
+   The IETF takes no position regarding the validity or scope of any
16667
 
+   Intellectual Property Rights or other rights that might be claimed to
16668
 
+   pertain to the implementation or use of the technology described in
16669
 
+   this document or the extent to which any license under such rights
16670
 
+   might or might not be available; nor does it represent that it has
16671
 
+   made any independent effort to identify any such rights.  Information
16672
 
+   on the procedures with respect to rights in RFC documents can be
16673
 
+   found in BCP 78 and BCP 79.
16674
 
+
16675
 
+   Copies of IPR disclosures made to the IETF Secretariat and any
16676
 
+   assurances of licenses to be made available, or the result of an
16677
 
+   attempt made to obtain a general license or permission for the use of
16678
 
+   such proprietary rights by implementers or users of this
16679
 
+   specification can be obtained from the IETF on-line IPR repository at
16680
 
+   http://www.ietf.org/ipr.
16681
 
+
16682
 
+   The IETF invites any interested party to bring to its attention any
16683
 
+   copyrights, patents or patent applications, or other proprietary
16684
 
+   rights that may cover technology that may be required to implement
16685
 
+   this standard.  Please address the information to the IETF at
16686
 
+   ietf-ipr@ietf.org.
16687
 
+
16688
 
+
16689
 
+
16690
 
+
16691
 
+
16692
 
+
16693
 
+
16694
 
+
16695
 
+
16696
 
+
16697
 
+
16698
 
+
16699
 
+Freed                       Standards Track                    [Page 10]
16700
 
+
16701
 
diff -urN dovecot-1.2.4/dovecot-libsieve/doc/rfc/imail.rfc2822.txt dovecot-1.2.4.debian/dovecot-libsieve/doc/rfc/imail.rfc2822.txt
16702
 
--- dovecot-1.2.4/dovecot-libsieve/doc/rfc/imail.rfc2822.txt    1970-01-01 01:00:00.000000000 +0100
16703
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/doc/rfc/imail.rfc2822.txt     2008-07-18 12:11:28.000000000 +0200
16704
 
@@ -0,0 +1,2859 @@
16705
 
+
16706
 
+
16707
 
+
16708
 
+
16709
 
+
16710
 
+
16711
 
+Network Working Group                                 P. Resnick, Editor
16712
 
+Request for Comments: 2822                         QUALCOMM Incorporated
16713
 
+Obsoletes: 822                                                April 2001
16714
 
+Category: Standards Track
16715
 
+
16716
 
+
16717
 
+                        Internet Message Format
16718
 
+
16719
 
+Status of this Memo
16720
 
+
16721
 
+   This document specifies an Internet standards track protocol for the
16722
 
+   Internet community, and requests discussion and suggestions for
16723
 
+   improvements.  Please refer to the current edition of the "Internet
16724
 
+   Official Protocol Standards" (STD 1) for the standardization state
16725
 
+   and status of this protocol.  Distribution of this memo is unlimited.
16726
 
+
16727
 
+Copyright Notice
16728
 
+
16729
 
+   Copyright (C) The Internet Society (2001).  All Rights Reserved.
16730
 
+
16731
 
+Abstract
16732
 
+
16733
 
+   This standard specifies a syntax for text messages that are sent
16734
 
+   between computer users, within the framework of "electronic mail"
16735
 
+   messages.  This standard supersedes the one specified in Request For
16736
 
+   Comments (RFC) 822, "Standard for the Format of ARPA Internet Text
16737
 
+   Messages", updating it to reflect current practice and incorporating
16738
 
+   incremental changes that were specified in other RFCs.
16739
 
+
16740
 
+Table of Contents
16741
 
+
16742
 
+   1. Introduction ............................................... 3
16743
 
+   1.1. Scope .................................................... 3
16744
 
+   1.2. Notational conventions ................................... 4
16745
 
+   1.2.1. Requirements notation .................................. 4
16746
 
+   1.2.2. Syntactic notation ..................................... 4
16747
 
+   1.3. Structure of this document ............................... 4
16748
 
+   2. Lexical Analysis of Messages ............................... 5
16749
 
+   2.1. General Description ...................................... 5
16750
 
+   2.1.1. Line Length Limits ..................................... 6
16751
 
+   2.2. Header Fields ............................................ 7
16752
 
+   2.2.1. Unstructured Header Field Bodies ....................... 7
16753
 
+   2.2.2. Structured Header Field Bodies ......................... 7
16754
 
+   2.2.3. Long Header Fields ..................................... 7
16755
 
+   2.3. Body ..................................................... 8
16756
 
+   3. Syntax ..................................................... 9
16757
 
+   3.1. Introduction ............................................. 9
16758
 
+   3.2. Lexical Tokens ........................................... 9
16759
 
+
16760
 
+
16761
 
+
16762
 
+Resnick                     Standards Track                     [Page 1]
16763
 
+
16764
 
+RFC 2822                Internet Message Format               April 2001
16765
 
+
16766
 
+
16767
 
+   3.2.1. Primitive Tokens ....................................... 9
16768
 
+   3.2.2. Quoted characters ......................................10
16769
 
+   3.2.3. Folding white space and comments .......................11
16770
 
+   3.2.4. Atom ...................................................12
16771
 
+   3.2.5. Quoted strings .........................................13
16772
 
+   3.2.6. Miscellaneous tokens ...................................13
16773
 
+   3.3. Date and Time Specification ..............................14
16774
 
+   3.4. Address Specification ....................................15
16775
 
+   3.4.1. Addr-spec specification ................................16
16776
 
+   3.5 Overall message syntax ....................................17
16777
 
+   3.6. Field definitions ........................................18
16778
 
+   3.6.1. The origination date field .............................20
16779
 
+   3.6.2. Originator fields ......................................21
16780
 
+   3.6.3. Destination address fields .............................22
16781
 
+   3.6.4. Identification fields ..................................23
16782
 
+   3.6.5. Informational fields ...................................26
16783
 
+   3.6.6. Resent fields ..........................................26
16784
 
+   3.6.7. Trace fields ...........................................28
16785
 
+   3.6.8. Optional fields ........................................29
16786
 
+   4. Obsolete Syntax ............................................29
16787
 
+   4.1. Miscellaneous obsolete tokens ............................30
16788
 
+   4.2. Obsolete folding white space .............................31
16789
 
+   4.3. Obsolete Date and Time ...................................31
16790
 
+   4.4. Obsolete Addressing ......................................33
16791
 
+   4.5. Obsolete header fields ...................................33
16792
 
+   4.5.1. Obsolete origination date field ........................34
16793
 
+   4.5.2. Obsolete originator fields .............................34
16794
 
+   4.5.3. Obsolete destination address fields ....................34
16795
 
+   4.5.4. Obsolete identification fields .........................35
16796
 
+   4.5.5. Obsolete informational fields ..........................35
16797
 
+   4.5.6. Obsolete resent fields .................................35
16798
 
+   4.5.7. Obsolete trace fields ..................................36
16799
 
+   4.5.8. Obsolete optional fields ...............................36
16800
 
+   5. Security Considerations ....................................36
16801
 
+   6. Bibliography ...............................................37
16802
 
+   7. Editor's Address ...........................................38
16803
 
+   8. Acknowledgements ...........................................39
16804
 
+   Appendix A. Example messages ..................................41
16805
 
+   A.1. Addressing examples ......................................41
16806
 
+   A.1.1. A message from one person to another with simple
16807
 
+          addressing .............................................41
16808
 
+   A.1.2. Different types of mailboxes ...........................42
16809
 
+   A.1.3. Group addresses ........................................43
16810
 
+   A.2. Reply messages ...........................................43
16811
 
+   A.3. Resent messages ..........................................44
16812
 
+   A.4. Messages with trace fields ...............................46
16813
 
+   A.5. White space, comments, and other oddities ................47
16814
 
+   A.6. Obsoleted forms ..........................................47
16815
 
+
16816
 
+
16817
 
+
16818
 
+Resnick                     Standards Track                     [Page 2]
16819
 
+
16820
 
+RFC 2822                Internet Message Format               April 2001
16821
 
+
16822
 
+
16823
 
+   A.6.1. Obsolete addressing ....................................48
16824
 
+   A.6.2. Obsolete dates .........................................48
16825
 
+   A.6.3. Obsolete white space and comments ......................48
16826
 
+   Appendix B. Differences from earlier standards ................49
16827
 
+   Appendix C. Notices ...........................................50
16828
 
+   Full Copyright Statement ......................................51
16829
 
+
16830
 
+1. Introduction
16831
 
+
16832
 
+1.1. Scope
16833
 
+
16834
 
+   This standard specifies a syntax for text messages that are sent
16835
 
+   between computer users, within the framework of "electronic mail"
16836
 
+   messages.  This standard supersedes the one specified in Request For
16837
 
+   Comments (RFC) 822, "Standard for the Format of ARPA Internet Text
16838
 
+   Messages" [RFC822], updating it to reflect current practice and
16839
 
+   incorporating incremental changes that were specified in other RFCs
16840
 
+   [STD3].
16841
 
+
16842
 
+   This standard specifies a syntax only for text messages.  In
16843
 
+   particular, it makes no provision for the transmission of images,
16844
 
+   audio, or other sorts of structured data in electronic mail messages.
16845
 
+   There are several extensions published, such as the MIME document
16846
 
+   series [RFC2045, RFC2046, RFC2049], which describe mechanisms for the
16847
 
+   transmission of such data through electronic mail, either by
16848
 
+   extending the syntax provided here or by structuring such messages to
16849
 
+   conform to this syntax.  Those mechanisms are outside of the scope of
16850
 
+   this standard.
16851
 
+
16852
 
+   In the context of electronic mail, messages are viewed as having an
16853
 
+   envelope and contents.  The envelope contains whatever information is
16854
 
+   needed to accomplish transmission and delivery.  (See [RFC2821] for a
16855
 
+   discussion of the envelope.)  The contents comprise the object to be
16856
 
+   delivered to the recipient.  This standard applies only to the format
16857
 
+   and some of the semantics of message contents.  It contains no
16858
 
+   specification of the information in the envelope.
16859
 
+
16860
 
+   However, some message systems may use information from the contents
16861
 
+   to create the envelope.  It is intended that this standard facilitate
16862
 
+   the acquisition of such information by programs.
16863
 
+
16864
 
+   This specification is intended as a definition of what message
16865
 
+   content format is to be passed between systems.  Though some message
16866
 
+   systems locally store messages in this format (which eliminates the
16867
 
+   need for translation between formats) and others use formats that
16868
 
+   differ from the one specified in this standard, local storage is
16869
 
+   outside of the scope of this standard.
16870
 
+
16871
 
+
16872
 
+
16873
 
+
16874
 
+Resnick                     Standards Track                     [Page 3]
16875
 
+
16876
 
+RFC 2822                Internet Message Format               April 2001
16877
 
+
16878
 
+
16879
 
+   Note: This standard is not intended to dictate the internal formats
16880
 
+   used by sites, the specific message system features that they are
16881
 
+   expected to support, or any of the characteristics of user interface
16882
 
+   programs that create or read messages.  In addition, this standard
16883
 
+   does not specify an encoding of the characters for either transport
16884
 
+   or storage; that is, it does not specify the number of bits used or
16885
 
+   how those bits are specifically transferred over the wire or stored
16886
 
+   on disk.
16887
 
+
16888
 
+1.2. Notational conventions
16889
 
+
16890
 
+1.2.1. Requirements notation
16891
 
+
16892
 
+   This document occasionally uses terms that appear in capital letters.
16893
 
+   When the terms "MUST", "SHOULD", "RECOMMENDED", "MUST NOT", "SHOULD
16894
 
+   NOT", and "MAY" appear capitalized, they are being used to indicate
16895
 
+   particular requirements of this specification.  A discussion of the
16896
 
+   meanings of these terms appears in [RFC2119].
16897
 
+
16898
 
+1.2.2. Syntactic notation
16899
 
+
16900
 
+   This standard uses the Augmented Backus-Naur Form (ABNF) notation
16901
 
+   specified in [RFC2234] for the formal definitions of the syntax of
16902
 
+   messages.  Characters will be specified either by a decimal value
16903
 
+   (e.g., the value %d65 for uppercase A and %d97 for lowercase A) or by
16904
 
+   a case-insensitive literal value enclosed in quotation marks (e.g.,
16905
 
+   "A" for either uppercase or lowercase A).  See [RFC2234] for the full
16906
 
+   description of the notation.
16907
 
+
16908
 
+1.3. Structure of this document
16909
 
+
16910
 
+   This document is divided into several sections.
16911
 
+
16912
 
+   This section, section 1, is a short introduction to the document.
16913
 
+
16914
 
+   Section 2 lays out the general description of a message and its
16915
 
+   constituent parts.  This is an overview to help the reader understand
16916
 
+   some of the general principles used in the later portions of this
16917
 
+   document.  Any examples in this section MUST NOT be taken as
16918
 
+   specification of the formal syntax of any part of a message.
16919
 
+
16920
 
+   Section 3 specifies formal ABNF rules for the structure of each part
16921
 
+   of a message (the syntax) and describes the relationship between
16922
 
+   those parts and their meaning in the context of a message (the
16923
 
+   semantics).  That is, it describes the actual rules for the structure
16924
 
+   of each part of a message (the syntax) as well as a description of
16925
 
+   the parts and instructions on how they ought to be interpreted (the
16926
 
+   semantics).  This includes analysis of the syntax and semantics of
16927
 
+
16928
 
+
16929
 
+
16930
 
+Resnick                     Standards Track                     [Page 4]
16931
 
+
16932
 
+RFC 2822                Internet Message Format               April 2001
16933
 
+
16934
 
+
16935
 
+   subparts of messages that have specific structure.  The syntax
16936
 
+   included in section 3 represents messages as they MUST be created.
16937
 
+   There are also notes in section 3 to indicate if any of the options
16938
 
+   specified in the syntax SHOULD be used over any of the others.
16939
 
+
16940
 
+   Both sections 2 and 3 describe messages that are legal to generate
16941
 
+   for purposes of this standard.
16942
 
+
16943
 
+   Section 4 of this document specifies an "obsolete" syntax.  There are
16944
 
+   references in section 3 to these obsolete syntactic elements.  The
16945
 
+   rules of the obsolete syntax are elements that have appeared in
16946
 
+   earlier revisions of this standard or have previously been widely
16947
 
+   used in Internet messages.  As such, these elements MUST be
16948
 
+   interpreted by parsers of messages in order to be conformant to this
16949
 
+   standard.  However, since items in this syntax have been determined
16950
 
+   to be non-interoperable or to cause significant problems for
16951
 
+   recipients of messages, they MUST NOT be generated by creators of
16952
 
+   conformant messages.
16953
 
+
16954
 
+   Section 5 details security considerations to take into account when
16955
 
+   implementing this standard.
16956
 
+
16957
 
+   Section 6 is a bibliography of references in this document.
16958
 
+
16959
 
+   Section 7 contains the editor's address.
16960
 
+
16961
 
+   Section 8 contains acknowledgements.
16962
 
+
16963
 
+   Appendix A lists examples of different sorts of messages.  These
16964
 
+   examples are not exhaustive of the types of messages that appear on
16965
 
+   the Internet, but give a broad overview of certain syntactic forms.
16966
 
+
16967
 
+   Appendix B lists the differences between this standard and earlier
16968
 
+   standards for Internet messages.
16969
 
+
16970
 
+   Appendix C has copyright and intellectual property notices.
16971
 
+
16972
 
+2. Lexical Analysis of Messages
16973
 
+
16974
 
+2.1. General Description
16975
 
+
16976
 
+   At the most basic level, a message is a series of characters.  A
16977
 
+   message that is conformant with this standard is comprised of
16978
 
+   characters with values in the range 1 through 127 and interpreted as
16979
 
+   US-ASCII characters [ASCII].  For brevity, this document sometimes
16980
 
+   refers to this range of characters as simply "US-ASCII characters".
16981
 
+
16982
 
+
16983
 
+
16984
 
+
16985
 
+
16986
 
+Resnick                     Standards Track                     [Page 5]
16987
 
+
16988
 
+RFC 2822                Internet Message Format               April 2001
16989
 
+
16990
 
+
16991
 
+   Note: This standard specifies that messages are made up of characters
16992
 
+   in the US-ASCII range of 1 through 127.  There are other documents,
16993
 
+   specifically the MIME document series [RFC2045, RFC2046, RFC2047,
16994
 
+   RFC2048, RFC2049], that extend this standard to allow for values
16995
 
+   outside of that range.  Discussion of those mechanisms is not within
16996
 
+   the scope of this standard.
16997
 
+
16998
 
+   Messages are divided into lines of characters.  A line is a series of
16999
 
+   characters that is delimited with the two characters carriage-return
17000
 
+   and line-feed; that is, the carriage return (CR) character (ASCII
17001
 
+   value 13) followed immediately by the line feed (LF) character (ASCII
17002
 
+   value 10).  (The carriage-return/line-feed pair is usually written in
17003
 
+   this document as "CRLF".)
17004
 
+
17005
 
+   A message consists of header fields (collectively called "the header
17006
 
+   of the message") followed, optionally, by a body.  The header is a
17007
 
+   sequence of lines of characters with special syntax as defined in
17008
 
+   this standard. The body is simply a sequence of characters that
17009
 
+   follows the header and is separated from the header by an empty line
17010
 
+   (i.e., a line with nothing preceding the CRLF).
17011
 
+
17012
 
+2.1.1. Line Length Limits
17013
 
+
17014
 
+   There are two limits that this standard places on the number of
17015
 
+   characters in a line. Each line of characters MUST be no more than
17016
 
+   998 characters, and SHOULD be no more than 78 characters, excluding
17017
 
+   the CRLF.
17018
 
+
17019
 
+   The 998 character limit is due to limitations in many implementations
17020
 
+   which send, receive, or store Internet Message Format messages that
17021
 
+   simply cannot handle more than 998 characters on a line. Receiving
17022
 
+   implementations would do well to handle an arbitrarily large number
17023
 
+   of characters in a line for robustness sake. However, there are so
17024
 
+   many implementations which (in compliance with the transport
17025
 
+   requirements of [RFC2821]) do not accept messages containing more
17026
 
+   than 1000 character including the CR and LF per line, it is important
17027
 
+   for implementations not to create such messages.
17028
 
+
17029
 
+   The more conservative 78 character recommendation is to accommodate
17030
 
+   the many implementations of user interfaces that display these
17031
 
+   messages which may truncate, or disastrously wrap, the display of
17032
 
+   more than 78 characters per line, in spite of the fact that such
17033
 
+   implementations are non-conformant to the intent of this
17034
 
+   specification (and that of [RFC2821] if they actually cause
17035
 
+   information to be lost). Again, even though this limitation is put on
17036
 
+   messages, it is encumbant upon implementations which display messages
17037
 
+
17038
 
+
17039
 
+
17040
 
+
17041
 
+
17042
 
+Resnick                     Standards Track                     [Page 6]
17043
 
+
17044
 
+RFC 2822                Internet Message Format               April 2001
17045
 
+
17046
 
+
17047
 
+   to handle an arbitrarily large number of characters in a line
17048
 
+   (certainly at least up to the 998 character limit) for the sake of
17049
 
+   robustness.
17050
 
+
17051
 
+2.2. Header Fields
17052
 
+
17053
 
+   Header fields are lines composed of a field name, followed by a colon
17054
 
+   (":"), followed by a field body, and terminated by CRLF.  A field
17055
 
+   name MUST be composed of printable US-ASCII characters (i.e.,
17056
 
+   characters that have values between 33 and 126, inclusive), except
17057
 
+   colon.  A field body may be composed of any US-ASCII characters,
17058
 
+   except for CR and LF.  However, a field body may contain CRLF when
17059
 
+   used in header "folding" and  "unfolding" as described in section
17060
 
+   2.2.3.  All field bodies MUST conform to the syntax described in
17061
 
+   sections 3 and 4 of this standard.
17062
 
+
17063
 
+2.2.1. Unstructured Header Field Bodies
17064
 
+
17065
 
+   Some field bodies in this standard are defined simply as
17066
 
+   "unstructured" (which is specified below as any US-ASCII characters,
17067
 
+   except for CR and LF) with no further restrictions.  These are
17068
 
+   referred to as unstructured field bodies.  Semantically, unstructured
17069
 
+   field bodies are simply to be treated as a single line of characters
17070
 
+   with no further processing (except for header "folding" and
17071
 
+   "unfolding" as described in section 2.2.3).
17072
 
+
17073
 
+2.2.2. Structured Header Field Bodies
17074
 
+
17075
 
+   Some field bodies in this standard have specific syntactical
17076
 
+   structure more restrictive than the unstructured field bodies
17077
 
+   described above. These are referred to as "structured" field bodies.
17078
 
+   Structured field bodies are sequences of specific lexical tokens as
17079
 
+   described in sections 3 and 4 of this standard.  Many of these tokens
17080
 
+   are allowed (according to their syntax) to be introduced or end with
17081
 
+   comments (as described in section 3.2.3) as well as the space (SP,
17082
 
+   ASCII value 32) and horizontal tab (HTAB, ASCII value 9) characters
17083
 
+   (together known as the white space characters, WSP), and those WSP
17084
 
+   characters are subject to header "folding" and "unfolding" as
17085
 
+   described in section 2.2.3.  Semantic analysis of structured field
17086
 
+   bodies is given along with their syntax.
17087
 
+
17088
 
+2.2.3. Long Header Fields
17089
 
+
17090
 
+   Each header field is logically a single line of characters comprising
17091
 
+   the field name, the colon, and the field body.  For convenience
17092
 
+   however, and to deal with the 998/78 character limitations per line,
17093
 
+   the field body portion of a header field can be split into a multiple
17094
 
+   line representation; this is called "folding".  The general rule is
17095
 
+
17096
 
+
17097
 
+
17098
 
+Resnick                     Standards Track                     [Page 7]
17099
 
+
17100
 
+RFC 2822                Internet Message Format               April 2001
17101
 
+
17102
 
+
17103
 
+   that wherever this standard allows for folding white space (not
17104
 
+   simply WSP characters), a CRLF may be inserted before any WSP.  For
17105
 
+   example, the header field:
17106
 
+
17107
 
+           Subject: This is a test
17108
 
+
17109
 
+   can be represented as:
17110
 
+
17111
 
+           Subject: This
17112
 
+            is a test
17113
 
+
17114
 
+   Note: Though structured field bodies are defined in such a way that
17115
 
+   folding can take place between many of the lexical tokens (and even
17116
 
+   within some of the lexical tokens), folding SHOULD be limited to
17117
 
+   placing the CRLF at higher-level syntactic breaks.  For instance, if
17118
 
+   a field body is defined as comma-separated values, it is recommended
17119
 
+   that folding occur after the comma separating the structured items in
17120
 
+   preference to other places where the field could be folded, even if
17121
 
+   it is allowed elsewhere.
17122
 
+
17123
 
+   The process of moving from this folded multiple-line representation
17124
 
+   of a header field to its single line representation is called
17125
 
+   "unfolding". Unfolding is accomplished by simply removing any CRLF
17126
 
+   that is immediately followed by WSP.  Each header field should be
17127
 
+   treated in its unfolded form for further syntactic and semantic
17128
 
+   evaluation.
17129
 
+
17130
 
+2.3. Body
17131
 
+
17132
 
+   The body of a message is simply lines of US-ASCII characters.  The
17133
 
+   only two limitations on the body are as follows:
17134
 
+
17135
 
+   - CR and LF MUST only occur together as CRLF; they MUST NOT appear
17136
 
+     independently in the body.
17137
 
+
17138
 
+   - Lines of characters in the body MUST be limited to 998 characters,
17139
 
+     and SHOULD be limited to 78 characters, excluding the CRLF.
17140
 
+
17141
 
+   Note: As was stated earlier, there are other standards documents,
17142
 
+   specifically the MIME documents [RFC2045, RFC2046, RFC2048, RFC2049]
17143
 
+   that extend this standard to allow for different sorts of message
17144
 
+   bodies.  Again, these mechanisms are beyond the scope of this
17145
 
+   document.
17146
 
+
17147
 
+
17148
 
+
17149
 
+
17150
 
+
17151
 
+
17152
 
+
17153
 
+
17154
 
+Resnick                     Standards Track                     [Page 8]
17155
 
+
17156
 
+RFC 2822                Internet Message Format               April 2001
17157
 
+
17158
 
+
17159
 
+3. Syntax
17160
 
+
17161
 
+3.1. Introduction
17162
 
+
17163
 
+   The syntax as given in this section defines the legal syntax of
17164
 
+   Internet messages.  Messages that are conformant to this standard
17165
 
+   MUST conform to the syntax in this section.  If there are options in
17166
 
+   this section where one option SHOULD be generated, that is indicated
17167
 
+   either in the prose or in a comment next to the syntax.
17168
 
+
17169
 
+   For the defined expressions, a short description of the syntax and
17170
 
+   use is given, followed by the syntax in ABNF, followed by a semantic
17171
 
+   analysis.  Primitive tokens that are used but otherwise unspecified
17172
 
+   come from [RFC2234].
17173
 
+
17174
 
+   In some of the definitions, there will be nonterminals whose names
17175
 
+   start with "obs-".  These "obs-" elements refer to tokens defined in
17176
 
+   the obsolete syntax in section 4.  In all cases, these productions
17177
 
+   are to be ignored for the purposes of generating legal Internet
17178
 
+   messages and MUST NOT be used as part of such a message.  However,
17179
 
+   when interpreting messages, these tokens MUST be honored as part of
17180
 
+   the legal syntax.  In this sense, section 3 defines a grammar for
17181
 
+   generation of messages, with "obs-" elements that are to be ignored,
17182
 
+   while section 4 adds grammar for interpretation of messages.
17183
 
+
17184
 
+3.2. Lexical Tokens
17185
 
+
17186
 
+   The following rules are used to define an underlying lexical
17187
 
+   analyzer, which feeds tokens to the higher-level parsers.  This
17188
 
+   section defines the tokens used in structured header field bodies.
17189
 
+
17190
 
+   Note: Readers of this standard need to pay special attention to how
17191
 
+   these lexical tokens are used in both the lower-level and
17192
 
+   higher-level syntax later in the document.  Particularly, the white
17193
 
+   space tokens and the comment tokens defined in section 3.2.3 get used
17194
 
+   in the lower-level tokens defined here, and those lower-level tokens
17195
 
+   are in turn used as parts of the higher-level tokens defined later.
17196
 
+   Therefore, the white space and comments may be allowed in the
17197
 
+   higher-level tokens even though they may not explicitly appear in a
17198
 
+   particular definition.
17199
 
+
17200
 
+3.2.1. Primitive Tokens
17201
 
+
17202
 
+   The following are primitive tokens referred to elsewhere in this
17203
 
+   standard, but not otherwise defined in [RFC2234].  Some of them will
17204
 
+   not appear anywhere else in the syntax, but they are convenient to
17205
 
+   refer to in other parts of this document.
17206
 
+
17207
 
+
17208
 
+
17209
 
+
17210
 
+Resnick                     Standards Track                     [Page 9]
17211
 
+
17212
 
+RFC 2822                Internet Message Format               April 2001
17213
 
+
17214
 
+
17215
 
+   Note: The "specials" below are just such an example.  Though the
17216
 
+   specials token does not appear anywhere else in this standard, it is
17217
 
+   useful for implementers who use tools that lexically analyze
17218
 
+   messages.  Each of the characters in specials can be used to indicate
17219
 
+   a tokenization point in lexical analysis.
17220
 
+
17221
 
+NO-WS-CTL       =       %d1-8 /         ; US-ASCII control characters
17222
 
+                        %d11 /          ;  that do not include the
17223
 
+                        %d12 /          ;  carriage return, line feed,
17224
 
+                        %d14-31 /       ;  and white space characters
17225
 
+                        %d127
17226
 
+
17227
 
+text            =       %d1-9 /         ; Characters excluding CR and LF
17228
 
+                        %d11 /
17229
 
+                        %d12 /
17230
 
+                        %d14-127 /
17231
 
+                        obs-text
17232
 
+
17233
 
+specials        =       "(" / ")" /     ; Special characters used in
17234
 
+                        "<" / ">" /     ;  other parts of the syntax
17235
 
+                        "[" / "]" /
17236
 
+                        ":" / ";" /
17237
 
+                        "@" / "\" /
17238
 
+                        "," / "." /
17239
 
+                        DQUOTE
17240
 
+
17241
 
+   No special semantics are attached to these tokens.  They are simply
17242
 
+   single characters.
17243
 
+
17244
 
+3.2.2. Quoted characters
17245
 
+
17246
 
+   Some characters are reserved for special interpretation, such as
17247
 
+   delimiting lexical tokens.  To permit use of these characters as
17248
 
+   uninterpreted data, a quoting mechanism is provided.
17249
 
+
17250
 
+quoted-pair     =       ("\" text) / obs-qp
17251
 
+
17252
 
+   Where any quoted-pair appears, it is to be interpreted as the text
17253
 
+   character alone.  That is to say, the "\" character that appears as
17254
 
+   part of a quoted-pair is semantically "invisible".
17255
 
+
17256
 
+   Note: The "\" character may appear in a message where it is not part
17257
 
+   of a quoted-pair.  A "\" character that does not appear in a
17258
 
+   quoted-pair is not semantically invisible.  The only places in this
17259
 
+   standard where quoted-pair currently appears are ccontent, qcontent,
17260
 
+   dcontent, no-fold-quote, and no-fold-literal.
17261
 
+
17262
 
+
17263
 
+
17264
 
+
17265
 
+
17266
 
+Resnick                     Standards Track                    [Page 10]
17267
 
+
17268
 
+RFC 2822                Internet Message Format               April 2001
17269
 
+
17270
 
+
17271
 
+3.2.3. Folding white space and comments
17272
 
+
17273
 
+   White space characters, including white space used in folding
17274
 
+   (described in section 2.2.3), may appear between many elements in
17275
 
+   header field bodies.  Also, strings of characters that are treated as
17276
 
+   comments may be included in structured field bodies as characters
17277
 
+   enclosed in parentheses.  The following defines the folding white
17278
 
+   space (FWS) and comment constructs.
17279
 
+
17280
 
+   Strings of characters enclosed in parentheses are considered comments
17281
 
+   so long as they do not appear within a "quoted-string", as defined in
17282
 
+   section 3.2.5.  Comments may nest.
17283
 
+
17284
 
+   There are several places in this standard where comments and FWS may
17285
 
+   be freely inserted.  To accommodate that syntax, an additional token
17286
 
+   for "CFWS" is defined for places where comments and/or FWS can occur.
17287
 
+   However, where CFWS occurs in this standard, it MUST NOT be inserted
17288
 
+   in such a way that any line of a folded header field is made up
17289
 
+   entirely of WSP characters and nothing else.
17290
 
+
17291
 
+FWS             =       ([*WSP CRLF] 1*WSP) /   ; Folding white space
17292
 
+                        obs-FWS
17293
 
+
17294
 
+ctext           =       NO-WS-CTL /     ; Non white space controls
17295
 
+
17296
 
+                        %d33-39 /       ; The rest of the US-ASCII
17297
 
+                        %d42-91 /       ;  characters not including "(",
17298
 
+                        %d93-126        ;  ")", or "\"
17299
 
+
17300
 
+ccontent        =       ctext / quoted-pair / comment
17301
 
+
17302
 
+comment         =       "(" *([FWS] ccontent) [FWS] ")"
17303
 
+
17304
 
+CFWS            =       *([FWS] comment) (([FWS] comment) / FWS)
17305
 
+
17306
 
+   Throughout this standard, where FWS (the folding white space token)
17307
 
+   appears, it indicates a place where header folding, as discussed in
17308
 
+   section 2.2.3, may take place.  Wherever header folding appears in a
17309
 
+   message (that is, a header field body containing a CRLF followed by
17310
 
+   any WSP), header unfolding (removal of the CRLF) is performed before
17311
 
+   any further lexical analysis is performed on that header field
17312
 
+   according to this standard.  That is to say, any CRLF that appears in
17313
 
+   FWS is semantically "invisible."
17314
 
+
17315
 
+   A comment is normally used in a structured field body to provide some
17316
 
+   human readable informational text.  Since a comment is allowed to
17317
 
+   contain FWS, folding is permitted within the comment.  Also note that
17318
 
+   since quoted-pair is allowed in a comment, the parentheses and
17319
 
+
17320
 
+
17321
 
+
17322
 
+Resnick                     Standards Track                    [Page 11]
17323
 
+
17324
 
+RFC 2822                Internet Message Format               April 2001
17325
 
+
17326
 
+
17327
 
+   backslash characters may appear in a comment so long as they appear
17328
 
+   as a quoted-pair.  Semantically, the enclosing parentheses are not
17329
 
+   part of the comment; the comment is what is contained between the two
17330
 
+   parentheses.  As stated earlier, the "\" in any quoted-pair and the
17331
 
+   CRLF in any FWS that appears within the comment are semantically
17332
 
+   "invisible" and therefore not part of the comment either.
17333
 
+
17334
 
+   Runs of FWS, comment or CFWS that occur between lexical tokens in a
17335
 
+   structured field header are semantically interpreted as a single
17336
 
+   space character.
17337
 
+
17338
 
+3.2.4. Atom
17339
 
+
17340
 
+   Several productions in structured header field bodies are simply
17341
 
+   strings of certain basic characters.  Such productions are called
17342
 
+   atoms.
17343
 
+
17344
 
+   Some of the structured header field bodies also allow the period
17345
 
+   character (".", ASCII value 46) within runs of atext.  An additional
17346
 
+   "dot-atom" token is defined for those purposes.
17347
 
+
17348
 
+atext           =       ALPHA / DIGIT / ; Any character except controls,
17349
 
+                        "!" / "#" /     ;  SP, and specials.
17350
 
+                        "$" / "%" /     ;  Used for atoms
17351
 
+                        "&" / "'" /
17352
 
+                        "*" / "+" /
17353
 
+                        "-" / "/" /
17354
 
+                        "=" / "?" /
17355
 
+                        "^" / "_" /
17356
 
+                        "`" / "{" /
17357
 
+                        "|" / "}" /
17358
 
+                        "~"
17359
 
+
17360
 
+atom            =       [CFWS] 1*atext [CFWS]
17361
 
+
17362
 
+dot-atom        =       [CFWS] dot-atom-text [CFWS]
17363
 
+
17364
 
+dot-atom-text   =       1*atext *("." 1*atext)
17365
 
+
17366
 
+   Both atom and dot-atom are interpreted as a single unit, comprised of
17367
 
+   the string of characters that make it up.  Semantically, the optional
17368
 
+   comments and FWS surrounding the rest of the characters are not part
17369
 
+   of the atom; the atom is only the run of atext characters in an atom,
17370
 
+   or the atext and "." characters in a dot-atom.
17371
 
+
17372
 
+
17373
 
+
17374
 
+
17375
 
+
17376
 
+
17377
 
+
17378
 
+Resnick                     Standards Track                    [Page 12]
17379
 
+
17380
 
+RFC 2822                Internet Message Format               April 2001
17381
 
+
17382
 
+
17383
 
+3.2.5. Quoted strings
17384
 
+
17385
 
+   Strings of characters that include characters other than those
17386
 
+   allowed in atoms may be represented in a quoted string format, where
17387
 
+   the characters are surrounded by quote (DQUOTE, ASCII value 34)
17388
 
+   characters.
17389
 
+
17390
 
+qtext           =       NO-WS-CTL /     ; Non white space controls
17391
 
+
17392
 
+                        %d33 /          ; The rest of the US-ASCII
17393
 
+                        %d35-91 /       ;  characters not including "\"
17394
 
+                        %d93-126        ;  or the quote character
17395
 
+
17396
 
+qcontent        =       qtext / quoted-pair
17397
 
+
17398
 
+quoted-string   =       [CFWS]
17399
 
+                        DQUOTE *([FWS] qcontent) [FWS] DQUOTE
17400
 
+                        [CFWS]
17401
 
+
17402
 
+   A quoted-string is treated as a unit.  That is, quoted-string is
17403
 
+   identical to atom, semantically.  Since a quoted-string is allowed to
17404
 
+   contain FWS, folding is permitted.  Also note that since quoted-pair
17405
 
+   is allowed in a quoted-string, the quote and backslash characters may
17406
 
+   appear in a quoted-string so long as they appear as a quoted-pair.
17407
 
+
17408
 
+   Semantically, neither the optional CFWS outside of the quote
17409
 
+   characters nor the quote characters themselves are part of the
17410
 
+   quoted-string; the quoted-string is what is contained between the two
17411
 
+   quote characters.  As stated earlier, the "\" in any quoted-pair and
17412
 
+   the CRLF in any FWS/CFWS that appears within the quoted-string are
17413
 
+   semantically "invisible" and therefore not part of the quoted-string
17414
 
+   either.
17415
 
+
17416
 
+3.2.6. Miscellaneous tokens
17417
 
+
17418
 
+   Three additional tokens are defined, word and phrase for combinations
17419
 
+   of atoms and/or quoted-strings, and unstructured for use in
17420
 
+   unstructured header fields and in some places within structured
17421
 
+   header fields.
17422
 
+
17423
 
+word            =       atom / quoted-string
17424
 
+
17425
 
+phrase          =       1*word / obs-phrase
17426
 
+
17427
 
+
17428
 
+
17429
 
+
17430
 
+
17431
 
+
17432
 
+
17433
 
+
17434
 
+Resnick                     Standards Track                    [Page 13]
17435
 
+
17436
 
+RFC 2822                Internet Message Format               April 2001
17437
 
+
17438
 
+
17439
 
+utext           =       NO-WS-CTL /     ; Non white space controls
17440
 
+                        %d33-126 /      ; The rest of US-ASCII
17441
 
+                        obs-utext
17442
 
+
17443
 
+unstructured    =       *([FWS] utext) [FWS]
17444
 
+
17445
 
+3.3. Date and Time Specification
17446
 
+
17447
 
+   Date and time occur in several header fields.  This section specifies
17448
 
+   the syntax for a full date and time specification.  Though folding
17449
 
+   white space is permitted throughout the date-time specification, it
17450
 
+   is RECOMMENDED that a single space be used in each place that FWS
17451
 
+   appears (whether it is required or optional); some older
17452
 
+   implementations may not interpret other occurrences of folding white
17453
 
+   space correctly.
17454
 
+
17455
 
+date-time       =       [ day-of-week "," ] date FWS time [CFWS]
17456
 
+
17457
 
+day-of-week     =       ([FWS] day-name) / obs-day-of-week
17458
 
+
17459
 
+day-name        =       "Mon" / "Tue" / "Wed" / "Thu" /
17460
 
+                        "Fri" / "Sat" / "Sun"
17461
 
+
17462
 
+date            =       day month year
17463
 
+
17464
 
+year            =       4*DIGIT / obs-year
17465
 
+
17466
 
+month           =       (FWS month-name FWS) / obs-month
17467
 
+
17468
 
+month-name      =       "Jan" / "Feb" / "Mar" / "Apr" /
17469
 
+                        "May" / "Jun" / "Jul" / "Aug" /
17470
 
+                        "Sep" / "Oct" / "Nov" / "Dec"
17471
 
+
17472
 
+day             =       ([FWS] 1*2DIGIT) / obs-day
17473
 
+
17474
 
+time            =       time-of-day FWS zone
17475
 
+
17476
 
+time-of-day     =       hour ":" minute [ ":" second ]
17477
 
+
17478
 
+hour            =       2DIGIT / obs-hour
17479
 
+
17480
 
+minute          =       2DIGIT / obs-minute
17481
 
+
17482
 
+second          =       2DIGIT / obs-second
17483
 
+
17484
 
+zone            =       (( "+" / "-" ) 4DIGIT) / obs-zone
17485
 
+
17486
 
+
17487
 
+
17488
 
+
17489
 
+
17490
 
+Resnick                     Standards Track                    [Page 14]
17491
 
+
17492
 
+RFC 2822                Internet Message Format               April 2001
17493
 
+
17494
 
+
17495
 
+   The day is the numeric day of the month.  The year is any numeric
17496
 
+   year 1900 or later.
17497
 
+
17498
 
+   The time-of-day specifies the number of hours, minutes, and
17499
 
+   optionally seconds since midnight of the date indicated.
17500
 
+
17501
 
+   The date and time-of-day SHOULD express local time.
17502
 
+
17503
 
+   The zone specifies the offset from Coordinated Universal Time (UTC,
17504
 
+   formerly referred to as "Greenwich Mean Time") that the date and
17505
 
+   time-of-day represent.  The "+" or "-" indicates whether the
17506
 
+   time-of-day is ahead of (i.e., east of) or behind (i.e., west of)
17507
 
+   Universal Time.  The first two digits indicate the number of hours
17508
 
+   difference from Universal Time, and the last two digits indicate the
17509
 
+   number of minutes difference from Universal Time.  (Hence, +hhmm
17510
 
+   means +(hh * 60 + mm) minutes, and -hhmm means -(hh * 60 + mm)
17511
 
+   minutes).  The form "+0000" SHOULD be used to indicate a time zone at
17512
 
+   Universal Time.  Though "-0000" also indicates Universal Time, it is
17513
 
+   used to indicate that the time was generated on a system that may be
17514
 
+   in a local time zone other than Universal Time and therefore
17515
 
+   indicates that the date-time contains no information about the local
17516
 
+   time zone.
17517
 
+
17518
 
+   A date-time specification MUST be semantically valid.  That is, the
17519
 
+   day-of-the-week (if included) MUST be the day implied by the date,
17520
 
+   the numeric day-of-month MUST be between 1 and the number of days
17521
 
+   allowed for the specified month (in the specified year), the
17522
 
+   time-of-day MUST be in the range 00:00:00 through 23:59:60 (the
17523
 
+   number of seconds allowing for a leap second; see [STD12]), and the
17524
 
+   zone MUST be within the range -9959 through +9959.
17525
 
+
17526
 
+3.4. Address Specification
17527
 
+
17528
 
+   Addresses occur in several message header fields to indicate senders
17529
 
+   and recipients of messages.  An address may either be an individual
17530
 
+   mailbox, or a group of mailboxes.
17531
 
+
17532
 
+address         =       mailbox / group
17533
 
+
17534
 
+mailbox         =       name-addr / addr-spec
17535
 
+
17536
 
+name-addr       =       [display-name] angle-addr
17537
 
+
17538
 
+angle-addr      =       [CFWS] "<" addr-spec ">" [CFWS] / obs-angle-addr
17539
 
+
17540
 
+group           =       display-name ":" [mailbox-list / CFWS] ";"
17541
 
+                        [CFWS]
17542
 
+
17543
 
+
17544
 
+
17545
 
+
17546
 
+Resnick                     Standards Track                    [Page 15]
17547
 
+
17548
 
+RFC 2822                Internet Message Format               April 2001
17549
 
+
17550
 
+
17551
 
+display-name    =       phrase
17552
 
+
17553
 
+mailbox-list    =       (mailbox *("," mailbox)) / obs-mbox-list
17554
 
+
17555
 
+address-list    =       (address *("," address)) / obs-addr-list
17556
 
+
17557
 
+   A mailbox receives mail.  It is a conceptual entity which does not
17558
 
+   necessarily pertain to file storage.  For example, some sites may
17559
 
+   choose to print mail on a printer and deliver the output to the
17560
 
+   addressee's desk.  Normally, a mailbox is comprised of two parts: (1)
17561
 
+   an optional display name that indicates the name of the recipient
17562
 
+   (which could be a person or a system) that could be displayed to the
17563
 
+   user of a mail application, and (2) an addr-spec address enclosed in
17564
 
+   angle brackets ("<" and ">").  There is also an alternate simple form
17565
 
+   of a mailbox where the addr-spec address appears alone, without the
17566
 
+   recipient's name or the angle brackets.  The Internet addr-spec
17567
 
+   address is described in section 3.4.1.
17568
 
+
17569
 
+   Note: Some legacy implementations used the simple form where the
17570
 
+   addr-spec appears without the angle brackets, but included the name
17571
 
+   of the recipient in parentheses as a comment following the addr-spec.
17572
 
+   Since the meaning of the information in a comment is unspecified,
17573
 
+   implementations SHOULD use the full name-addr form of the mailbox,
17574
 
+   instead of the legacy form, to specify the display name associated
17575
 
+   with a mailbox.  Also, because some legacy implementations interpret
17576
 
+   the comment, comments generally SHOULD NOT be used in address fields
17577
 
+   to avoid confusing such implementations.
17578
 
+
17579
 
+   When it is desirable to treat several mailboxes as a single unit
17580
 
+   (i.e., in a distribution list), the group construct can be used.  The
17581
 
+   group construct allows the sender to indicate a named group of
17582
 
+   recipients. This is done by giving a display name for the group,
17583
 
+   followed by a colon, followed by a comma separated list of any number
17584
 
+   of mailboxes (including zero and one), and ending with a semicolon.
17585
 
+   Because the list of mailboxes can be empty, using the group construct
17586
 
+   is also a simple way to communicate to recipients that the message
17587
 
+   was sent to one or more named sets of recipients, without actually
17588
 
+   providing the individual mailbox address for each of those
17589
 
+   recipients.
17590
 
+
17591
 
+3.4.1. Addr-spec specification
17592
 
+
17593
 
+   An addr-spec is a specific Internet identifier that contains a
17594
 
+   locally interpreted string followed by the at-sign character ("@",
17595
 
+   ASCII value 64) followed by an Internet domain.  The locally
17596
 
+   interpreted string is either a quoted-string or a dot-atom.  If the
17597
 
+   string can be represented as a dot-atom (that is, it contains no
17598
 
+   characters other than atext characters or "." surrounded by atext
17599
 
+
17600
 
+
17601
 
+
17602
 
+Resnick                     Standards Track                    [Page 16]
17603
 
+
17604
 
+RFC 2822                Internet Message Format               April 2001
17605
 
+
17606
 
+
17607
 
+   characters), then the dot-atom form SHOULD be used and the
17608
 
+   quoted-string form SHOULD NOT be used. Comments and folding white
17609
 
+   space SHOULD NOT be used around the "@" in the addr-spec.
17610
 
+
17611
 
+addr-spec       =       local-part "@" domain
17612
 
+
17613
 
+local-part      =       dot-atom / quoted-string / obs-local-part
17614
 
+
17615
 
+domain          =       dot-atom / domain-literal / obs-domain
17616
 
+
17617
 
+domain-literal  =       [CFWS] "[" *([FWS] dcontent) [FWS] "]" [CFWS]
17618
 
+
17619
 
+dcontent        =       dtext / quoted-pair
17620
 
+
17621
 
+dtext           =       NO-WS-CTL /     ; Non white space controls
17622
 
+
17623
 
+                        %d33-90 /       ; The rest of the US-ASCII
17624
 
+                        %d94-126        ;  characters not including "[",
17625
 
+                                        ;  "]", or "\"
17626
 
+
17627
 
+   The domain portion identifies the point to which the mail is
17628
 
+   delivered. In the dot-atom form, this is interpreted as an Internet
17629
 
+   domain name (either a host name or a mail exchanger name) as
17630
 
+   described in [STD3, STD13, STD14].  In the domain-literal form, the
17631
 
+   domain is interpreted as the literal Internet address of the
17632
 
+   particular host.  In both cases, how addressing is used and how
17633
 
+   messages are transported to a particular host is covered in the mail
17634
 
+   transport document [RFC2821].  These mechanisms are outside of the
17635
 
+   scope of this document.
17636
 
+
17637
 
+   The local-part portion is a domain dependent string.  In addresses,
17638
 
+   it is simply interpreted on the particular host as a name of a
17639
 
+   particular mailbox.
17640
 
+
17641
 
+3.5 Overall message syntax
17642
 
+
17643
 
+   A message consists of header fields, optionally followed by a message
17644
 
+   body.  Lines in a message MUST be a maximum of 998 characters
17645
 
+   excluding the CRLF, but it is RECOMMENDED that lines be limited to 78
17646
 
+   characters excluding the CRLF.  (See section 2.1.1 for explanation.)
17647
 
+   In a message body, though all of the characters listed in the text
17648
 
+   rule MAY be used, the use of US-ASCII control characters (values 1
17649
 
+   through 8, 11, 12, and 14 through 31) is discouraged since their
17650
 
+   interpretation by receivers for display is not guaranteed.
17651
 
+
17652
 
+
17653
 
+
17654
 
+
17655
 
+
17656
 
+
17657
 
+
17658
 
+Resnick                     Standards Track                    [Page 17]
17659
 
+
17660
 
+RFC 2822                Internet Message Format               April 2001
17661
 
+
17662
 
+
17663
 
+message         =       (fields / obs-fields)
17664
 
+                        [CRLF body]
17665
 
+
17666
 
+body            =       *(*998text CRLF) *998text
17667
 
+
17668
 
+   The header fields carry most of the semantic information and are
17669
 
+   defined in section 3.6.  The body is simply a series of lines of text
17670
 
+   which are uninterpreted for the purposes of this standard.
17671
 
+
17672
 
+3.6. Field definitions
17673
 
+
17674
 
+   The header fields of a message are defined here.  All header fields
17675
 
+   have the same general syntactic structure: A field name, followed by
17676
 
+   a colon, followed by the field body.  The specific syntax for each
17677
 
+   header field is defined in the subsequent sections.
17678
 
+
17679
 
+   Note: In the ABNF syntax for each field in subsequent sections, each
17680
 
+   field name is followed by the required colon.  However, for brevity
17681
 
+   sometimes the colon is not referred to in the textual description of
17682
 
+   the syntax.  It is, nonetheless, required.
17683
 
+
17684
 
+   It is important to note that the header fields are not guaranteed to
17685
 
+   be in a particular order.  They may appear in any order, and they
17686
 
+   have been known to be reordered occasionally when transported over
17687
 
+   the Internet.  However, for the purposes of this standard, header
17688
 
+   fields SHOULD NOT be reordered when a message is transported or
17689
 
+   transformed.  More importantly, the trace header fields and resent
17690
 
+   header fields MUST NOT be reordered, and SHOULD be kept in blocks
17691
 
+   prepended to the message.  See sections 3.6.6 and 3.6.7 for more
17692
 
+   information.
17693
 
+
17694
 
+   The only required header fields are the origination date field and
17695
 
+   the originator address field(s).  All other header fields are
17696
 
+   syntactically optional.  More information is contained in the table
17697
 
+   following this definition.
17698
 
+
17699
 
+fields          =       *(trace
17700
 
+                          *(resent-date /
17701
 
+                           resent-from /
17702
 
+                           resent-sender /
17703
 
+                           resent-to /
17704
 
+                           resent-cc /
17705
 
+                           resent-bcc /
17706
 
+                           resent-msg-id))
17707
 
+                        *(orig-date /
17708
 
+                        from /
17709
 
+                        sender /
17710
 
+                        reply-to /
17711
 
+
17712
 
+
17713
 
+
17714
 
+Resnick                     Standards Track                    [Page 18]
17715
 
+
17716
 
+RFC 2822                Internet Message Format               April 2001
17717
 
+
17718
 
+
17719
 
+                        to /
17720
 
+                        cc /
17721
 
+                        bcc /
17722
 
+                        message-id /
17723
 
+                        in-reply-to /
17724
 
+                        references /
17725
 
+                        subject /
17726
 
+                        comments /
17727
 
+                        keywords /
17728
 
+                        optional-field)
17729
 
+
17730
 
+   The following table indicates limits on the number of times each
17731
 
+   field may occur in a message header as well as any special
17732
 
+   limitations on the use of those fields.  An asterisk next to a value
17733
 
+   in the minimum or maximum column indicates that a special restriction
17734
 
+   appears in the Notes column.
17735
 
+
17736
 
+Field           Min number      Max number      Notes
17737
 
+
17738
 
+trace           0               unlimited       Block prepended - see
17739
 
+                                                3.6.7
17740
 
+
17741
 
+resent-date     0*              unlimited*      One per block, required
17742
 
+                                                if other resent fields
17743
 
+                                                present - see 3.6.6
17744
 
+
17745
 
+resent-from     0               unlimited*      One per block - see
17746
 
+                                                3.6.6
17747
 
+
17748
 
+resent-sender   0*              unlimited*      One per block, MUST
17749
 
+                                                occur with multi-address
17750
 
+                                                resent-from - see 3.6.6
17751
 
+
17752
 
+resent-to       0               unlimited*      One per block - see
17753
 
+                                                3.6.6
17754
 
+
17755
 
+resent-cc       0               unlimited*      One per block - see
17756
 
+                                                3.6.6
17757
 
+
17758
 
+resent-bcc      0               unlimited*      One per block - see
17759
 
+                                                3.6.6
17760
 
+
17761
 
+resent-msg-id   0               unlimited*      One per block - see
17762
 
+                                                3.6.6
17763
 
+
17764
 
+orig-date       1               1
17765
 
+
17766
 
+from            1               1               See sender and 3.6.2
17767
 
+
17768
 
+
17769
 
+
17770
 
+Resnick                     Standards Track                    [Page 19]
17771
 
+
17772
 
+RFC 2822                Internet Message Format               April 2001
17773
 
+
17774
 
+
17775
 
+sender          0*              1               MUST occur with multi-
17776
 
+                                                address from - see 3.6.2
17777
 
+
17778
 
+reply-to        0               1
17779
 
+
17780
 
+to              0               1
17781
 
+
17782
 
+cc              0               1
17783
 
+
17784
 
+bcc             0               1
17785
 
+
17786
 
+message-id      0*              1               SHOULD be present - see
17787
 
+                                                3.6.4
17788
 
+
17789
 
+in-reply-to     0*              1               SHOULD occur in some
17790
 
+                                                replies - see 3.6.4
17791
 
+
17792
 
+references      0*              1               SHOULD occur in some
17793
 
+                                                replies - see 3.6.4
17794
 
+
17795
 
+subject         0               1
17796
 
+
17797
 
+comments        0               unlimited
17798
 
+
17799
 
+keywords        0               unlimited
17800
 
+
17801
 
+optional-field  0               unlimited
17802
 
+
17803
 
+   The exact interpretation of each field is described in subsequent
17804
 
+   sections.
17805
 
+
17806
 
+3.6.1. The origination date field
17807
 
+
17808
 
+   The origination date field consists of the field name "Date" followed
17809
 
+   by a date-time specification.
17810
 
+
17811
 
+orig-date       =       "Date:" date-time CRLF
17812
 
+
17813
 
+   The origination date specifies the date and time at which the creator
17814
 
+   of the message indicated that the message was complete and ready to
17815
 
+   enter the mail delivery system.  For instance, this might be the time
17816
 
+   that a user pushes the "send" or "submit" button in an application
17817
 
+   program.  In any case, it is specifically not intended to convey the
17818
 
+   time that the message is actually transported, but rather the time at
17819
 
+   which the human or other creator of the message has put the message
17820
 
+   into its final form, ready for transport.  (For example, a portable
17821
 
+   computer user who is not connected to a network might queue a message
17822
 
+
17823
 
+
17824
 
+
17825
 
+
17826
 
+Resnick                     Standards Track                    [Page 20]
17827
 
+
17828
 
+RFC 2822                Internet Message Format               April 2001
17829
 
+
17830
 
+
17831
 
+   for delivery.  The origination date is intended to contain the date
17832
 
+   and time that the user queued the message, not the time when the user
17833
 
+   connected to the network to send the message.)
17834
 
+
17835
 
+3.6.2. Originator fields
17836
 
+
17837
 
+   The originator fields of a message consist of the from field, the
17838
 
+   sender field (when applicable), and optionally the reply-to field.
17839
 
+   The from field consists of the field name "From" and a
17840
 
+   comma-separated list of one or more mailbox specifications.  If the
17841
 
+   from field contains more than one mailbox specification in the
17842
 
+   mailbox-list, then the sender field, containing the field name
17843
 
+   "Sender" and a single mailbox specification, MUST appear in the
17844
 
+   message.  In either case, an optional reply-to field MAY also be
17845
 
+   included, which contains the field name "Reply-To" and a
17846
 
+   comma-separated list of one or more addresses.
17847
 
+
17848
 
+from            =       "From:" mailbox-list CRLF
17849
 
+
17850
 
+sender          =       "Sender:" mailbox CRLF
17851
 
+
17852
 
+reply-to        =       "Reply-To:" address-list CRLF
17853
 
+
17854
 
+   The originator fields indicate the mailbox(es) of the source of the
17855
 
+   message.  The "From:" field specifies the author(s) of the message,
17856
 
+   that is, the mailbox(es) of the person(s) or system(s) responsible
17857
 
+   for the writing of the message.  The "Sender:" field specifies the
17858
 
+   mailbox of the agent responsible for the actual transmission of the
17859
 
+   message.  For example, if a secretary were to send a message for
17860
 
+   another person, the mailbox of the secretary would appear in the
17861
 
+   "Sender:" field and the mailbox of the actual author would appear in
17862
 
+   the "From:" field.  If the originator of the message can be indicated
17863
 
+   by a single mailbox and the author and transmitter are identical, the
17864
 
+   "Sender:" field SHOULD NOT be used.  Otherwise, both fields SHOULD
17865
 
+   appear.
17866
 
+
17867
 
+   The originator fields also provide the information required when
17868
 
+   replying to a message.  When the "Reply-To:" field is present, it
17869
 
+   indicates the mailbox(es) to which the author of the message suggests
17870
 
+   that replies be sent.  In the absence of the "Reply-To:" field,
17871
 
+   replies SHOULD by default be sent to the mailbox(es) specified in the
17872
 
+   "From:" field unless otherwise specified by the person composing the
17873
 
+   reply.
17874
 
+
17875
 
+   In all cases, the "From:" field SHOULD NOT contain any mailbox that
17876
 
+   does not belong to the author(s) of the message.  See also section
17877
 
+   3.6.3 for more information on forming the destination addresses for a
17878
 
+   reply.
17879
 
+
17880
 
+
17881
 
+
17882
 
+Resnick                     Standards Track                    [Page 21]
17883
 
+
17884
 
+RFC 2822                Internet Message Format               April 2001
17885
 
+
17886
 
+
17887
 
+3.6.3. Destination address fields
17888
 
+
17889
 
+   The destination fields of a message consist of three possible fields,
17890
 
+   each of the same form: The field name, which is either "To", "Cc", or
17891
 
+   "Bcc", followed by a comma-separated list of one or more addresses
17892
 
+   (either mailbox or group syntax).
17893
 
+
17894
 
+to              =       "To:" address-list CRLF
17895
 
+
17896
 
+cc              =       "Cc:" address-list CRLF
17897
 
+
17898
 
+bcc             =       "Bcc:" (address-list / [CFWS]) CRLF
17899
 
+
17900
 
+   The destination fields specify the recipients of the message.  Each
17901
 
+   destination field may have one or more addresses, and each of the
17902
 
+   addresses indicate the intended recipients of the message.  The only
17903
 
+   difference between the three fields is how each is used.
17904
 
+
17905
 
+   The "To:" field contains the address(es) of the primary recipient(s)
17906
 
+   of the message.
17907
 
+
17908
 
+   The "Cc:" field (where the "Cc" means "Carbon Copy" in the sense of
17909
 
+   making a copy on a typewriter using carbon paper) contains the
17910
 
+   addresses of others who are to receive the message, though the
17911
 
+   content of the message may not be directed at them.
17912
 
+
17913
 
+   The "Bcc:" field (where the "Bcc" means "Blind Carbon Copy") contains
17914
 
+   addresses of recipients of the message whose addresses are not to be
17915
 
+   revealed to other recipients of the message.  There are three ways in
17916
 
+   which the "Bcc:" field is used.  In the first case, when a message
17917
 
+   containing a "Bcc:" field is prepared to be sent, the "Bcc:" line is
17918
 
+   removed even though all of the recipients (including those specified
17919
 
+   in the "Bcc:" field) are sent a copy of the message.  In the second
17920
 
+   case, recipients specified in the "To:" and "Cc:" lines each are sent
17921
 
+   a copy of the message with the "Bcc:" line removed as above, but the
17922
 
+   recipients on the "Bcc:" line get a separate copy of the message
17923
 
+   containing a "Bcc:" line.  (When there are multiple recipient
17924
 
+   addresses in the "Bcc:" field, some implementations actually send a
17925
 
+   separate copy of the message to each recipient with a "Bcc:"
17926
 
+   containing only the address of that particular recipient.) Finally,
17927
 
+   since a "Bcc:" field may contain no addresses, a "Bcc:" field can be
17928
 
+   sent without any addresses indicating to the recipients that blind
17929
 
+   copies were sent to someone.  Which method to use with "Bcc:" fields
17930
 
+   is implementation dependent, but refer to the "Security
17931
 
+   Considerations" section of this document for a discussion of each.
17932
 
+
17933
 
+
17934
 
+
17935
 
+
17936
 
+
17937
 
+
17938
 
+Resnick                     Standards Track                    [Page 22]
17939
 
+
17940
 
+RFC 2822                Internet Message Format               April 2001
17941
 
+
17942
 
+
17943
 
+   When a message is a reply to another message, the mailboxes of the
17944
 
+   authors of the original message (the mailboxes in the "From:" field)
17945
 
+   or mailboxes specified in the "Reply-To:" field (if it exists) MAY
17946
 
+   appear in the "To:" field of the reply since these would normally be
17947
 
+   the primary recipients of the reply.  If a reply is sent to a message
17948
 
+   that has destination fields, it is often desirable to send a copy of
17949
 
+   the reply to all of the recipients of the message, in addition to the
17950
 
+   author.  When such a reply is formed, addresses in the "To:" and
17951
 
+   "Cc:" fields of the original message MAY appear in the "Cc:" field of
17952
 
+   the reply, since these are normally secondary recipients of the
17953
 
+   reply.  If a "Bcc:" field is present in the original message,
17954
 
+   addresses in that field MAY appear in the "Bcc:" field of the reply,
17955
 
+   but SHOULD NOT appear in the "To:" or "Cc:" fields.
17956
 
+
17957
 
+   Note: Some mail applications have automatic reply commands that
17958
 
+   include the destination addresses of the original message in the
17959
 
+   destination addresses of the reply.  How those reply commands behave
17960
 
+   is implementation dependent and is beyond the scope of this document.
17961
 
+   In particular, whether or not to include the original destination
17962
 
+   addresses when the original message had a "Reply-To:" field is not
17963
 
+   addressed here.
17964
 
+
17965
 
+3.6.4. Identification fields
17966
 
+
17967
 
+   Though optional, every message SHOULD have a "Message-ID:" field.
17968
 
+   Furthermore, reply messages SHOULD have "In-Reply-To:" and
17969
 
+   "References:" fields as appropriate, as described below.
17970
 
+
17971
 
+   The "Message-ID:" field contains a single unique message identifier.
17972
 
+   The "References:" and "In-Reply-To:" field each contain one or more
17973
 
+   unique message identifiers, optionally separated by CFWS.
17974
 
+
17975
 
+   The message identifier (msg-id) is similar in syntax to an angle-addr
17976
 
+   construct without the internal CFWS.
17977
 
+
17978
 
+message-id      =       "Message-ID:" msg-id CRLF
17979
 
+
17980
 
+in-reply-to     =       "In-Reply-To:" 1*msg-id CRLF
17981
 
+
17982
 
+references      =       "References:" 1*msg-id CRLF
17983
 
+
17984
 
+msg-id          =       [CFWS] "<" id-left "@" id-right ">" [CFWS]
17985
 
+
17986
 
+id-left         =       dot-atom-text / no-fold-quote / obs-id-left
17987
 
+
17988
 
+id-right        =       dot-atom-text / no-fold-literal / obs-id-right
17989
 
+
17990
 
+no-fold-quote   =       DQUOTE *(qtext / quoted-pair) DQUOTE
17991
 
+
17992
 
+
17993
 
+
17994
 
+Resnick                     Standards Track                    [Page 23]
17995
 
+
17996
 
+RFC 2822                Internet Message Format               April 2001
17997
 
+
17998
 
+
17999
 
+no-fold-literal =       "[" *(dtext / quoted-pair) "]"
18000
 
+
18001
 
+   The "Message-ID:" field provides a unique message identifier that
18002
 
+   refers to a particular version of a particular message.  The
18003
 
+   uniqueness of the message identifier is guaranteed by the host that
18004
 
+   generates it (see below).  This message identifier is intended to be
18005
 
+   machine readable and not necessarily meaningful to humans.  A message
18006
 
+   identifier pertains to exactly one instantiation of a particular
18007
 
+   message; subsequent revisions to the message each receive new message
18008
 
+   identifiers.
18009
 
+
18010
 
+   Note: There are many instances when messages are "changed", but those
18011
 
+   changes do not constitute a new instantiation of that message, and
18012
 
+   therefore the message would not get a new message identifier.  For
18013
 
+   example, when messages are introduced into the transport system, they
18014
 
+   are often prepended with additional header fields such as trace
18015
 
+   fields (described in section 3.6.7) and resent fields (described in
18016
 
+   section 3.6.6).  The addition of such header fields does not change
18017
 
+   the identity of the message and therefore the original "Message-ID:"
18018
 
+   field is retained.  In all cases, it is the meaning that the sender
18019
 
+   of the message wishes to convey (i.e., whether this is the same
18020
 
+   message or a different message) that determines whether or not the
18021
 
+   "Message-ID:" field changes, not any particular syntactic difference
18022
 
+   that appears (or does not appear) in the message.
18023
 
+
18024
 
+   The "In-Reply-To:" and "References:" fields are used when creating a
18025
 
+   reply to a message.  They hold the message identifier of the original
18026
 
+   message and the message identifiers of other messages (for example,
18027
 
+   in the case of a reply to a message which was itself a reply).  The
18028
 
+   "In-Reply-To:" field may be used to identify the message (or
18029
 
+   messages) to which the new message is a reply, while the
18030
 
+   "References:" field may be used to identify a "thread" of
18031
 
+   conversation.
18032
 
+
18033
 
+   When creating a reply to a message, the "In-Reply-To:" and
18034
 
+   "References:" fields of the resultant message are constructed as
18035
 
+   follows:
18036
 
+
18037
 
+   The "In-Reply-To:" field will contain the contents of the "Message-
18038
 
+   ID:" field of the message to which this one is a reply (the "parent
18039
 
+   message").  If there is more than one parent message, then the "In-
18040
 
+   Reply-To:" field will contain the contents of all of the parents'
18041
 
+   "Message-ID:" fields.  If there is no "Message-ID:" field in any of
18042
 
+   the parent messages, then the new message will have no "In-Reply-To:"
18043
 
+   field.
18044
 
+
18045
 
+
18046
 
+
18047
 
+
18048
 
+
18049
 
+
18050
 
+Resnick                     Standards Track                    [Page 24]
18051
 
+
18052
 
+RFC 2822                Internet Message Format               April 2001
18053
 
+
18054
 
+
18055
 
+   The "References:" field will contain the contents of the parent's
18056
 
+   "References:" field (if any) followed by the contents of the parent's
18057
 
+   "Message-ID:" field (if any).  If the parent message does not contain
18058
 
+   a "References:" field but does have an "In-Reply-To:" field
18059
 
+   containing a single message identifier, then the "References:" field
18060
 
+   will contain the contents of the parent's "In-Reply-To:" field
18061
 
+   followed by the contents of the parent's "Message-ID:" field (if
18062
 
+   any).  If the parent has none of the "References:", "In-Reply-To:",
18063
 
+   or "Message-ID:" fields, then the new message will have no
18064
 
+   "References:" field.
18065
 
+
18066
 
+   Note: Some implementations parse the "References:" field to display
18067
 
+   the "thread of the discussion".  These implementations assume that
18068
 
+   each new message is a reply to a single parent and hence that they
18069
 
+   can walk backwards through the "References:" field to find the parent
18070
 
+   of each message listed there.  Therefore, trying to form a
18071
 
+   "References:" field for a reply that has multiple parents is
18072
 
+   discouraged and how to do so is not defined in this document.
18073
 
+
18074
 
+   The message identifier (msg-id) itself MUST be a globally unique
18075
 
+   identifier for a message.  The generator of the message identifier
18076
 
+   MUST guarantee that the msg-id is unique.  There are several
18077
 
+   algorithms that can be used to accomplish this.  Since the msg-id has
18078
 
+   a similar syntax to angle-addr (identical except that comments and
18079
 
+   folding white space are not allowed), a good method is to put the
18080
 
+   domain name (or a domain literal IP address) of the host on which the
18081
 
+   message identifier was created on the right hand side of the "@", and
18082
 
+   put a combination of the current absolute date and time along with
18083
 
+   some other currently unique (perhaps sequential) identifier available
18084
 
+   on the system (for example, a process id number) on the left hand
18085
 
+   side.  Using a date on the left hand side and a domain name or domain
18086
 
+   literal on the right hand side makes it possible to guarantee
18087
 
+   uniqueness since no two hosts use the same domain name or IP address
18088
 
+   at the same time.  Though other algorithms will work, it is
18089
 
+   RECOMMENDED that the right hand side contain some domain identifier
18090
 
+   (either of the host itself or otherwise) such that the generator of
18091
 
+   the message identifier can guarantee the uniqueness of the left hand
18092
 
+   side within the scope of that domain.
18093
 
+
18094
 
+   Semantically, the angle bracket characters are not part of the
18095
 
+   msg-id; the msg-id is what is contained between the two angle bracket
18096
 
+   characters.
18097
 
+
18098
 
+
18099
 
+
18100
 
+
18101
 
+
18102
 
+
18103
 
+
18104
 
+
18105
 
+
18106
 
+Resnick                     Standards Track                    [Page 25]
18107
 
+
18108
 
+RFC 2822                Internet Message Format               April 2001
18109
 
+
18110
 
+
18111
 
+3.6.5. Informational fields
18112
 
+
18113
 
+   The informational fields are all optional.  The "Keywords:" field
18114
 
+   contains a comma-separated list of one or more words or
18115
 
+   quoted-strings. The "Subject:" and "Comments:" fields are
18116
 
+   unstructured fields as defined in section 2.2.1, and therefore may
18117
 
+   contain text or folding white space.
18118
 
+
18119
 
+subject         =       "Subject:" unstructured CRLF
18120
 
+
18121
 
+comments        =       "Comments:" unstructured CRLF
18122
 
+
18123
 
+keywords        =       "Keywords:" phrase *("," phrase) CRLF
18124
 
+
18125
 
+   These three fields are intended to have only human-readable content
18126
 
+   with information about the message.  The "Subject:" field is the most
18127
 
+   common and contains a short string identifying the topic of the
18128
 
+   message.  When used in a reply, the field body MAY start with the
18129
 
+   string "Re: " (from the Latin "res", in the matter of) followed by
18130
 
+   the contents of the "Subject:" field body of the original message.
18131
 
+   If this is done, only one instance of the literal string "Re: " ought
18132
 
+   to be used since use of other strings or more than one instance can
18133
 
+   lead to undesirable consequences.  The "Comments:" field contains any
18134
 
+   additional comments on the text of the body of the message.  The
18135
 
+   "Keywords:" field contains a comma-separated list of important words
18136
 
+   and phrases that might be useful for the recipient.
18137
 
+
18138
 
+3.6.6. Resent fields
18139
 
+
18140
 
+   Resent fields SHOULD be added to any message that is reintroduced by
18141
 
+   a user into the transport system.  A separate set of resent fields
18142
 
+   SHOULD be added each time this is done.  All of the resent fields
18143
 
+   corresponding to a particular resending of the message SHOULD be
18144
 
+   together.  Each new set of resent fields is prepended to the message;
18145
 
+   that is, the most recent set of resent fields appear earlier in the
18146
 
+   message.  No other fields in the message are changed when resent
18147
 
+   fields are added.
18148
 
+
18149
 
+   Each of the resent fields corresponds to a particular field elsewhere
18150
 
+   in the syntax.  For instance, the "Resent-Date:" field corresponds to
18151
 
+   the "Date:" field and the "Resent-To:" field corresponds to the "To:"
18152
 
+   field.  In each case, the syntax for the field body is identical to
18153
 
+   the syntax given previously for the corresponding field.
18154
 
+
18155
 
+   When resent fields are used, the "Resent-From:" and "Resent-Date:"
18156
 
+   fields MUST be sent.  The "Resent-Message-ID:" field SHOULD be sent.
18157
 
+   "Resent-Sender:" SHOULD NOT be used if "Resent-Sender:" would be
18158
 
+   identical to "Resent-From:".
18159
 
+
18160
 
+
18161
 
+
18162
 
+Resnick                     Standards Track                    [Page 26]
18163
 
+
18164
 
+RFC 2822                Internet Message Format               April 2001
18165
 
+
18166
 
+
18167
 
+resent-date     =       "Resent-Date:" date-time CRLF
18168
 
+
18169
 
+resent-from     =       "Resent-From:" mailbox-list CRLF
18170
 
+
18171
 
+resent-sender   =       "Resent-Sender:" mailbox CRLF
18172
 
+
18173
 
+resent-to       =       "Resent-To:" address-list CRLF
18174
 
+
18175
 
+resent-cc       =       "Resent-Cc:" address-list CRLF
18176
 
+
18177
 
+resent-bcc      =       "Resent-Bcc:" (address-list / [CFWS]) CRLF
18178
 
+
18179
 
+resent-msg-id   =       "Resent-Message-ID:" msg-id CRLF
18180
 
+
18181
 
+   Resent fields are used to identify a message as having been
18182
 
+   reintroduced into the transport system by a user.  The purpose of
18183
 
+   using resent fields is to have the message appear to the final
18184
 
+   recipient as if it were sent directly by the original sender, with
18185
 
+   all of the original fields remaining the same.  Each set of resent
18186
 
+   fields correspond to a particular resending event.  That is, if a
18187
 
+   message is resent multiple times, each set of resent fields gives
18188
 
+   identifying information for each individual time.  Resent fields are
18189
 
+   strictly informational.  They MUST NOT be used in the normal
18190
 
+   processing of replies or other such automatic actions on messages.
18191
 
+
18192
 
+   Note: Reintroducing a message into the transport system and using
18193
 
+   resent fields is a different operation from "forwarding".
18194
 
+   "Forwarding" has two meanings: One sense of forwarding is that a mail
18195
 
+   reading program can be told by a user to forward a copy of a message
18196
 
+   to another person, making the forwarded message the body of the new
18197
 
+   message.  A forwarded message in this sense does not appear to have
18198
 
+   come from the original sender, but is an entirely new message from
18199
 
+   the forwarder of the message.  On the other hand, forwarding is also
18200
 
+   used to mean when a mail transport program gets a message and
18201
 
+   forwards it on to a different destination for final delivery.  Resent
18202
 
+   header fields are not intended for use with either type of
18203
 
+   forwarding.
18204
 
+
18205
 
+   The resent originator fields indicate the mailbox of the person(s) or
18206
 
+   system(s) that resent the message.  As with the regular originator
18207
 
+   fields, there are two forms: a simple "Resent-From:" form which
18208
 
+   contains the mailbox of the individual doing the resending, and the
18209
 
+   more complex form, when one individual (identified in the
18210
 
+   "Resent-Sender:" field) resends a message on behalf of one or more
18211
 
+   others (identified in the "Resent-From:" field).
18212
 
+
18213
 
+   Note: When replying to a resent message, replies behave just as they
18214
 
+   would with any other message, using the original "From:",
18215
 
+
18216
 
+
18217
 
+
18218
 
+Resnick                     Standards Track                    [Page 27]
18219
 
+
18220
 
+RFC 2822                Internet Message Format               April 2001
18221
 
+
18222
 
+
18223
 
+   "Reply-To:", "Message-ID:", and other fields.  The resent fields are
18224
 
+   only informational and MUST NOT be used in the normal processing of
18225
 
+   replies.
18226
 
+
18227
 
+   The "Resent-Date:" indicates the date and time at which the resent
18228
 
+   message is dispatched by the resender of the message.  Like the
18229
 
+   "Date:" field, it is not the date and time that the message was
18230
 
+   actually transported.
18231
 
+
18232
 
+   The "Resent-To:", "Resent-Cc:", and "Resent-Bcc:" fields function
18233
 
+   identically to the "To:", "Cc:", and "Bcc:" fields respectively,
18234
 
+   except that they indicate the recipients of the resent message, not
18235
 
+   the recipients of the original message.
18236
 
+
18237
 
+   The "Resent-Message-ID:" field provides a unique identifier for the
18238
 
+   resent message.
18239
 
+
18240
 
+3.6.7. Trace fields
18241
 
+
18242
 
+   The trace fields are a group of header fields consisting of an
18243
 
+   optional "Return-Path:" field, and one or more "Received:" fields.
18244
 
+   The "Return-Path:" header field contains a pair of angle brackets
18245
 
+   that enclose an optional addr-spec.  The "Received:" field contains a
18246
 
+   (possibly empty) list of name/value pairs followed by a semicolon and
18247
 
+   a date-time specification.  The first item of the name/value pair is
18248
 
+   defined by item-name, and the second item is either an addr-spec, an
18249
 
+   atom, a domain, or a msg-id.  Further restrictions may be applied to
18250
 
+   the syntax of the trace fields by standards that provide for their
18251
 
+   use, such as [RFC2821].
18252
 
+
18253
 
+trace           =       [return]
18254
 
+                        1*received
18255
 
+
18256
 
+return          =       "Return-Path:" path CRLF
18257
 
+
18258
 
+path            =       ([CFWS] "<" ([CFWS] / addr-spec) ">" [CFWS]) /
18259
 
+                        obs-path
18260
 
+
18261
 
+received        =       "Received:" name-val-list ";" date-time CRLF
18262
 
+
18263
 
+name-val-list   =       [CFWS] [name-val-pair *(CFWS name-val-pair)]
18264
 
+
18265
 
+name-val-pair   =       item-name CFWS item-value
18266
 
+
18267
 
+item-name       =       ALPHA *(["-"] (ALPHA / DIGIT))
18268
 
+
18269
 
+item-value      =       1*angle-addr / addr-spec /
18270
 
+                         atom / domain / msg-id
18271
 
+
18272
 
+
18273
 
+
18274
 
+Resnick                     Standards Track                    [Page 28]
18275
 
+
18276
 
+RFC 2822                Internet Message Format               April 2001
18277
 
+
18278
 
+
18279
 
+   A full discussion of the Internet mail use of trace fields is
18280
 
+   contained in [RFC2821].  For the purposes of this standard, the trace
18281
 
+   fields are strictly informational, and any formal interpretation of
18282
 
+   them is outside of the scope of this document.
18283
 
+
18284
 
+3.6.8. Optional fields
18285
 
+
18286
 
+   Fields may appear in messages that are otherwise unspecified in this
18287
 
+   standard.  They MUST conform to the syntax of an optional-field.
18288
 
+   This is a field name, made up of the printable US-ASCII characters
18289
 
+   except SP and colon, followed by a colon, followed by any text which
18290
 
+   conforms to unstructured.
18291
 
+
18292
 
+   The field names of any optional-field MUST NOT be identical to any
18293
 
+   field name specified elsewhere in this standard.
18294
 
+
18295
 
+optional-field  =       field-name ":" unstructured CRLF
18296
 
+
18297
 
+field-name      =       1*ftext
18298
 
+
18299
 
+ftext           =       %d33-57 /               ; Any character except
18300
 
+                        %d59-126                ;  controls, SP, and
18301
 
+                                                ;  ":".
18302
 
+
18303
 
+   For the purposes of this standard, any optional field is
18304
 
+   uninterpreted.
18305
 
+
18306
 
+4. Obsolete Syntax
18307
 
+
18308
 
+   Earlier versions of this standard allowed for different (usually more
18309
 
+   liberal) syntax than is allowed in this version.  Also, there have
18310
 
+   been syntactic elements used in messages on the Internet whose
18311
 
+   interpretation have never been documented.  Though some of these
18312
 
+   syntactic forms MUST NOT be generated according to the grammar in
18313
 
+   section 3, they MUST be accepted and parsed by a conformant receiver.
18314
 
+   This section documents many of these syntactic elements.  Taking the
18315
 
+   grammar in section 3 and adding the definitions presented in this
18316
 
+   section will result in the grammar to use for interpretation of
18317
 
+   messages.
18318
 
+
18319
 
+   Note: This section identifies syntactic forms that any implementation
18320
 
+   MUST reasonably interpret.  However, there are certainly Internet
18321
 
+   messages which do not conform to even the additional syntax given in
18322
 
+   this section.  The fact that a particular form does not appear in any
18323
 
+   section of this document is not justification for computer programs
18324
 
+   to crash or for malformed data to be irretrievably lost by any
18325
 
+   implementation.  To repeat an example, though this document requires
18326
 
+   lines in messages to be no longer than 998 characters, silently
18327
 
+
18328
 
+
18329
 
+
18330
 
+Resnick                     Standards Track                    [Page 29]
18331
 
+
18332
 
+RFC 2822                Internet Message Format               April 2001
18333
 
+
18334
 
+
18335
 
+   discarding the 999th and subsequent characters in a line without
18336
 
+   warning would still be bad behavior for an implementation.  It is up
18337
 
+   to the implementation to deal with messages robustly.
18338
 
+
18339
 
+   One important difference between the obsolete (interpreting) and the
18340
 
+   current (generating) syntax is that in structured header field bodies
18341
 
+   (i.e., between the colon and the CRLF of any structured header
18342
 
+   field), white space characters, including folding white space, and
18343
 
+   comments can be freely inserted between any syntactic tokens.  This
18344
 
+   allows many complex forms that have proven difficult for some
18345
 
+   implementations to parse.
18346
 
+
18347
 
+   Another key difference between the obsolete and the current syntax is
18348
 
+   that the rule in section 3.2.3 regarding lines composed entirely of
18349
 
+   white space in comments and folding white space does not apply.  See
18350
 
+   the discussion of folding white space in section 4.2 below.
18351
 
+
18352
 
+   Finally, certain characters that were formerly allowed in messages
18353
 
+   appear in this section.  The NUL character (ASCII value 0) was once
18354
 
+   allowed, but is no longer for compatibility reasons.  CR and LF were
18355
 
+   allowed to appear in messages other than as CRLF; this use is also
18356
 
+   shown here.
18357
 
+
18358
 
+   Other differences in syntax and semantics are noted in the following
18359
 
+   sections.
18360
 
+
18361
 
+4.1. Miscellaneous obsolete tokens
18362
 
+
18363
 
+   These syntactic elements are used elsewhere in the obsolete syntax or
18364
 
+   in the main syntax.  The obs-char and obs-qp elements each add ASCII
18365
 
+   value 0. Bare CR and bare LF are added to obs-text and obs-utext.
18366
 
+   The period character is added to obs-phrase. The obs-phrase-list
18367
 
+   provides for "empty" elements in a comma-separated list of phrases.
18368
 
+
18369
 
+   Note: The "period" (or "full stop") character (".") in obs-phrase is
18370
 
+   not a form that was allowed in earlier versions of this or any other
18371
 
+   standard.  Period (nor any other character from specials) was not
18372
 
+   allowed in phrase because it introduced a parsing difficulty
18373
 
+   distinguishing between phrases and portions of an addr-spec (see
18374
 
+   section 4.4).  It appears here because the period character is
18375
 
+   currently used in many messages in the display-name portion of
18376
 
+   addresses, especially for initials in names, and therefore must be
18377
 
+   interpreted properly.  In the future, period may appear in the
18378
 
+   regular syntax of phrase.
18379
 
+
18380
 
+obs-qp          =       "\" (%d0-127)
18381
 
+
18382
 
+obs-text        =       *LF *CR *(obs-char *LF *CR)
18383
 
+
18384
 
+
18385
 
+
18386
 
+Resnick                     Standards Track                    [Page 30]
18387
 
+
18388
 
+RFC 2822                Internet Message Format               April 2001
18389
 
+
18390
 
+
18391
 
+obs-char        =       %d0-9 / %d11 /          ; %d0-127 except CR and
18392
 
+                        %d12 / %d14-127         ;  LF
18393
 
+
18394
 
+obs-utext       =       obs-text
18395
 
+
18396
 
+obs-phrase      =       word *(word / "." / CFWS)
18397
 
+
18398
 
+obs-phrase-list =       phrase / 1*([phrase] [CFWS] "," [CFWS]) [phrase]
18399
 
+
18400
 
+   Bare CR and bare LF appear in messages with two different meanings.
18401
 
+   In many cases, bare CR or bare LF are used improperly instead of CRLF
18402
 
+   to indicate line separators.  In other cases, bare CR and bare LF are
18403
 
+   used simply as ASCII control characters with their traditional ASCII
18404
 
+   meanings.
18405
 
+
18406
 
+4.2. Obsolete folding white space
18407
 
+
18408
 
+   In the obsolete syntax, any amount of folding white space MAY be
18409
 
+   inserted where the obs-FWS rule is allowed.  This creates the
18410
 
+   possibility of having two consecutive "folds" in a line, and
18411
 
+   therefore the possibility that a line which makes up a folded header
18412
 
+   field could be composed entirely of white space.
18413
 
+
18414
 
+   obs-FWS         =       1*WSP *(CRLF 1*WSP)
18415
 
+
18416
 
+4.3. Obsolete Date and Time
18417
 
+
18418
 
+   The syntax for the obsolete date format allows a 2 digit year in the
18419
 
+   date field and allows for a list of alphabetic time zone
18420
 
+   specifications that were used in earlier versions of this standard.
18421
 
+   It also permits comments and folding white space between many of the
18422
 
+   tokens.
18423
 
+
18424
 
+obs-day-of-week =       [CFWS] day-name [CFWS]
18425
 
+
18426
 
+obs-year        =       [CFWS] 2*DIGIT [CFWS]
18427
 
+
18428
 
+obs-month       =       CFWS month-name CFWS
18429
 
+
18430
 
+obs-day         =       [CFWS] 1*2DIGIT [CFWS]
18431
 
+
18432
 
+obs-hour        =       [CFWS] 2DIGIT [CFWS]
18433
 
+
18434
 
+obs-minute      =       [CFWS] 2DIGIT [CFWS]
18435
 
+
18436
 
+obs-second      =       [CFWS] 2DIGIT [CFWS]
18437
 
+
18438
 
+obs-zone        =       "UT" / "GMT" /          ; Universal Time
18439
 
+
18440
 
+
18441
 
+
18442
 
+Resnick                     Standards Track                    [Page 31]
18443
 
+
18444
 
+RFC 2822                Internet Message Format               April 2001
18445
 
+
18446
 
+
18447
 
+                                                ; North American UT
18448
 
+                                                ; offsets
18449
 
+                        "EST" / "EDT" /         ; Eastern:  - 5/ - 4
18450
 
+                        "CST" / "CDT" /         ; Central:  - 6/ - 5
18451
 
+                        "MST" / "MDT" /         ; Mountain: - 7/ - 6
18452
 
+                        "PST" / "PDT" /         ; Pacific:  - 8/ - 7
18453
 
+
18454
 
+                        %d65-73 /               ; Military zones - "A"
18455
 
+                        %d75-90 /               ; through "I" and "K"
18456
 
+                        %d97-105 /              ; through "Z", both
18457
 
+                        %d107-122               ; upper and lower case
18458
 
+
18459
 
+   Where a two or three digit year occurs in a date, the year is to be
18460
 
+   interpreted as follows: If a two digit year is encountered whose
18461
 
+   value is between 00 and 49, the year is interpreted by adding 2000,
18462
 
+   ending up with a value between 2000 and 2049.  If a two digit year is
18463
 
+   encountered with a value between 50 and 99, or any three digit year
18464
 
+   is encountered, the year is interpreted by adding 1900.
18465
 
+
18466
 
+   In the obsolete time zone, "UT" and "GMT" are indications of
18467
 
+   "Universal Time" and "Greenwich Mean Time" respectively and are both
18468
 
+   semantically identical to "+0000".
18469
 
+
18470
 
+   The remaining three character zones are the US time zones.  The first
18471
 
+   letter, "E", "C", "M", or "P" stands for "Eastern", "Central",
18472
 
+   "Mountain" and "Pacific".  The second letter is either "S" for
18473
 
+   "Standard" time, or "D" for "Daylight" (or summer) time.  Their
18474
 
+   interpretations are as follows:
18475
 
+
18476
 
+   EDT is semantically equivalent to -0400
18477
 
+   EST is semantically equivalent to -0500
18478
 
+   CDT is semantically equivalent to -0500
18479
 
+   CST is semantically equivalent to -0600
18480
 
+   MDT is semantically equivalent to -0600
18481
 
+   MST is semantically equivalent to -0700
18482
 
+   PDT is semantically equivalent to -0700
18483
 
+   PST is semantically equivalent to -0800
18484
 
+
18485
 
+   The 1 character military time zones were defined in a non-standard
18486
 
+   way in [RFC822] and are therefore unpredictable in their meaning.
18487
 
+   The original definitions of the military zones "A" through "I" are
18488
 
+   equivalent to "+0100" through "+0900" respectively; "K", "L", and "M"
18489
 
+   are equivalent to  "+1000", "+1100", and "+1200" respectively; "N"
18490
 
+   through "Y" are equivalent to "-0100" through "-1200" respectively;
18491
 
+   and "Z" is equivalent to "+0000".  However, because of the error in
18492
 
+   [RFC822], they SHOULD all be considered equivalent to "-0000" unless
18493
 
+   there is out-of-band information confirming their meaning.
18494
 
+
18495
 
+
18496
 
+
18497
 
+
18498
 
+Resnick                     Standards Track                    [Page 32]
18499
 
+
18500
 
+RFC 2822                Internet Message Format               April 2001
18501
 
+
18502
 
+
18503
 
+   Other multi-character (usually between 3 and 5) alphabetic time zones
18504
 
+   have been used in Internet messages.  Any such time zone whose
18505
 
+   meaning is not known SHOULD be considered equivalent to "-0000"
18506
 
+   unless there is out-of-band information confirming their meaning.
18507
 
+
18508
 
+4.4. Obsolete Addressing
18509
 
+
18510
 
+   There are three primary differences in addressing.  First, mailbox
18511
 
+   addresses were allowed to have a route portion before the addr-spec
18512
 
+   when enclosed in "<" and ">".  The route is simply a comma-separated
18513
 
+   list of domain names, each preceded by "@", and the list terminated
18514
 
+   by a colon.  Second, CFWS were allowed between the period-separated
18515
 
+   elements of local-part and domain (i.e., dot-atom was not used).  In
18516
 
+   addition, local-part is allowed to contain quoted-string in addition
18517
 
+   to just atom.  Finally, mailbox-list and address-list were allowed to
18518
 
+   have "null" members.  That is, there could be two or more commas in
18519
 
+   such a list with nothing in between them.
18520
 
+
18521
 
+obs-angle-addr  =       [CFWS] "<" [obs-route] addr-spec ">" [CFWS]
18522
 
+
18523
 
+obs-route       =       [CFWS] obs-domain-list ":" [CFWS]
18524
 
+
18525
 
+obs-domain-list =       "@" domain *(*(CFWS / "," ) [CFWS] "@" domain)
18526
 
+
18527
 
+obs-local-part  =       word *("." word)
18528
 
+
18529
 
+obs-domain      =       atom *("." atom)
18530
 
+
18531
 
+obs-mbox-list   =       1*([mailbox] [CFWS] "," [CFWS]) [mailbox]
18532
 
+
18533
 
+obs-addr-list   =       1*([address] [CFWS] "," [CFWS]) [address]
18534
 
+
18535
 
+   When interpreting addresses, the route portion SHOULD be ignored.
18536
 
+
18537
 
+4.5. Obsolete header fields
18538
 
+
18539
 
+   Syntactically, the primary difference in the obsolete field syntax is
18540
 
+   that it allows multiple occurrences of any of the fields and they may
18541
 
+   occur in any order.  Also, any amount of white space is allowed
18542
 
+   before the ":" at the end of the field name.
18543
 
+
18544
 
+obs-fields      =       *(obs-return /
18545
 
+                        obs-received /
18546
 
+                        obs-orig-date /
18547
 
+                        obs-from /
18548
 
+                        obs-sender /
18549
 
+                        obs-reply-to /
18550
 
+                        obs-to /
18551
 
+
18552
 
+
18553
 
+
18554
 
+Resnick                     Standards Track                    [Page 33]
18555
 
+
18556
 
+RFC 2822                Internet Message Format               April 2001
18557
 
+
18558
 
+
18559
 
+                        obs-cc /
18560
 
+                        obs-bcc /
18561
 
+                        obs-message-id /
18562
 
+                        obs-in-reply-to /
18563
 
+                        obs-references /
18564
 
+                        obs-subject /
18565
 
+                        obs-comments /
18566
 
+                        obs-keywords /
18567
 
+                        obs-resent-date /
18568
 
+                        obs-resent-from /
18569
 
+                        obs-resent-send /
18570
 
+                        obs-resent-rply /
18571
 
+                        obs-resent-to /
18572
 
+                        obs-resent-cc /
18573
 
+                        obs-resent-bcc /
18574
 
+                        obs-resent-mid /
18575
 
+                        obs-optional)
18576
 
+
18577
 
+   Except for destination address fields (described in section 4.5.3),
18578
 
+   the interpretation of multiple occurrences of fields is unspecified.
18579
 
+   Also, the interpretation of trace fields and resent fields which do
18580
 
+   not occur in blocks prepended to the message is unspecified as well.
18581
 
+   Unless otherwise noted in the following sections, interpretation of
18582
 
+   other fields is identical to the interpretation of their non-obsolete
18583
 
+   counterparts in section 3.
18584
 
+
18585
 
+4.5.1. Obsolete origination date field
18586
 
+
18587
 
+obs-orig-date   =       "Date" *WSP ":" date-time CRLF
18588
 
+
18589
 
+4.5.2. Obsolete originator fields
18590
 
+
18591
 
+obs-from        =       "From" *WSP ":" mailbox-list CRLF
18592
 
+
18593
 
+obs-sender      =       "Sender" *WSP ":" mailbox CRLF
18594
 
+
18595
 
+obs-reply-to    =       "Reply-To" *WSP ":" mailbox-list CRLF
18596
 
+
18597
 
+4.5.3. Obsolete destination address fields
18598
 
+
18599
 
+obs-to          =       "To" *WSP ":" address-list CRLF
18600
 
+
18601
 
+obs-cc          =       "Cc" *WSP ":" address-list CRLF
18602
 
+
18603
 
+obs-bcc         =       "Bcc" *WSP ":" (address-list / [CFWS]) CRLF
18604
 
+
18605
 
+
18606
 
+
18607
 
+
18608
 
+
18609
 
+
18610
 
+Resnick                     Standards Track                    [Page 34]
18611
 
+
18612
 
+RFC 2822                Internet Message Format               April 2001
18613
 
+
18614
 
+
18615
 
+   When multiple occurrences of destination address fields occur in a
18616
 
+   message, they SHOULD be treated as if the address-list in the first
18617
 
+   occurrence of the field is combined with the address lists of the
18618
 
+   subsequent occurrences by adding a comma and concatenating.
18619
 
+
18620
 
+4.5.4. Obsolete identification fields
18621
 
+
18622
 
+   The obsolete "In-Reply-To:" and "References:" fields differ from the
18623
 
+   current syntax in that they allow phrase (words or quoted strings) to
18624
 
+   appear.  The obsolete forms of the left and right sides of msg-id
18625
 
+   allow interspersed CFWS, making them syntactically identical to
18626
 
+   local-part and domain respectively.
18627
 
+
18628
 
+obs-message-id  =       "Message-ID" *WSP ":" msg-id CRLF
18629
 
+
18630
 
+obs-in-reply-to =       "In-Reply-To" *WSP ":" *(phrase / msg-id) CRLF
18631
 
+
18632
 
+obs-references  =       "References" *WSP ":" *(phrase / msg-id) CRLF
18633
 
+
18634
 
+obs-id-left     =       local-part
18635
 
+
18636
 
+obs-id-right    =       domain
18637
 
+
18638
 
+   For purposes of interpretation, the phrases in the "In-Reply-To:" and
18639
 
+   "References:" fields are ignored.
18640
 
+
18641
 
+   Semantically, none of the optional CFWS surrounding the local-part
18642
 
+   and the domain are part of the obs-id-left and obs-id-right
18643
 
+   respectively.
18644
 
+
18645
 
+4.5.5. Obsolete informational fields
18646
 
+
18647
 
+obs-subject     =       "Subject" *WSP ":" unstructured CRLF
18648
 
+
18649
 
+obs-comments    =       "Comments" *WSP ":" unstructured CRLF
18650
 
+
18651
 
+obs-keywords    =       "Keywords" *WSP ":" obs-phrase-list CRLF
18652
 
+
18653
 
+4.5.6. Obsolete resent fields
18654
 
+
18655
 
+   The obsolete syntax adds a "Resent-Reply-To:" field, which consists
18656
 
+   of the field name, the optional comments and folding white space, the
18657
 
+   colon, and a comma separated list of addresses.
18658
 
+
18659
 
+obs-resent-from =       "Resent-From" *WSP ":" mailbox-list CRLF
18660
 
+
18661
 
+obs-resent-send =       "Resent-Sender" *WSP ":" mailbox CRLF
18662
 
+
18663
 
+
18664
 
+
18665
 
+
18666
 
+Resnick                     Standards Track                    [Page 35]
18667
 
+
18668
 
+RFC 2822                Internet Message Format               April 2001
18669
 
+
18670
 
+
18671
 
+obs-resent-date =       "Resent-Date" *WSP ":" date-time CRLF
18672
 
+
18673
 
+obs-resent-to   =       "Resent-To" *WSP ":" address-list CRLF
18674
 
+
18675
 
+obs-resent-cc   =       "Resent-Cc" *WSP ":" address-list CRLF
18676
 
+
18677
 
+obs-resent-bcc  =       "Resent-Bcc" *WSP ":"
18678
 
+                         (address-list / [CFWS]) CRLF
18679
 
+
18680
 
+obs-resent-mid  =       "Resent-Message-ID" *WSP ":" msg-id CRLF
18681
 
+
18682
 
+obs-resent-rply =       "Resent-Reply-To" *WSP ":" address-list CRLF
18683
 
+
18684
 
+   As with other resent fields, the "Resent-Reply-To:" field is to be
18685
 
+   treated as trace information only.
18686
 
+
18687
 
+4.5.7. Obsolete trace fields
18688
 
+
18689
 
+   The obs-return and obs-received are again given here as template
18690
 
+   definitions, just as return and received are in section 3.  Their
18691
 
+   full syntax is given in [RFC2821].
18692
 
+
18693
 
+obs-return      =       "Return-Path" *WSP ":" path CRLF
18694
 
+
18695
 
+obs-received    =       "Received" *WSP ":" name-val-list CRLF
18696
 
+
18697
 
+obs-path        =       obs-angle-addr
18698
 
+
18699
 
+4.5.8. Obsolete optional fields
18700
 
+
18701
 
+obs-optional    =       field-name *WSP ":" unstructured CRLF
18702
 
+
18703
 
+5. Security Considerations
18704
 
+
18705
 
+   Care needs to be taken when displaying messages on a terminal or
18706
 
+   terminal emulator.  Powerful terminals may act on escape sequences
18707
 
+   and other combinations of ASCII control characters with a variety of
18708
 
+   consequences.  They can remap the keyboard or permit other
18709
 
+   modifications to the terminal which could lead to denial of service
18710
 
+   or even damaged data.  They can trigger (sometimes programmable)
18711
 
+   answerback messages which can allow a message to cause commands to be
18712
 
+   issued on the recipient's behalf.  They can also effect the operation
18713
 
+   of terminal attached devices such as printers.  Message viewers may
18714
 
+   wish to strip potentially dangerous terminal escape sequences from
18715
 
+   the message prior to display.  However, other escape sequences appear
18716
 
+   in messages for useful purposes (cf. [RFC2045, RFC2046, RFC2047,
18717
 
+   RFC2048, RFC2049, ISO2022]) and therefore should not be stripped
18718
 
+   indiscriminately.
18719
 
+
18720
 
+
18721
 
+
18722
 
+Resnick                     Standards Track                    [Page 36]
18723
 
+
18724
 
+RFC 2822                Internet Message Format               April 2001
18725
 
+
18726
 
+
18727
 
+   Transmission of non-text objects in messages raises additional
18728
 
+   security issues.  These issues are discussed in [RFC2045, RFC2046,
18729
 
+   RFC2047, RFC2048, RFC2049].
18730
 
+
18731
 
+   Many implementations use the "Bcc:" (blind carbon copy) field
18732
 
+   described in section 3.6.3 to facilitate sending messages to
18733
 
+   recipients without revealing the addresses of one or more of the
18734
 
+   addressees to the other recipients.  Mishandling this use of "Bcc:"
18735
 
+   has implications for confidential information that might be revealed,
18736
 
+   which could eventually lead to security problems through knowledge of
18737
 
+   even the existence of a particular mail address.  For example, if
18738
 
+   using the first method described in section 3.6.3, where the "Bcc:"
18739
 
+   line is removed from the message, blind recipients have no explicit
18740
 
+   indication that they have been sent a blind copy, except insofar as
18741
 
+   their address does not appear in the message header.  Because of
18742
 
+   this, one of the blind addressees could potentially send a reply to
18743
 
+   all of the shown recipients and accidentally reveal that the message
18744
 
+   went to the blind recipient.  When the second method from section
18745
 
+   3.6.3 is used, the blind recipient's address appears in the "Bcc:"
18746
 
+   field of a separate copy of the message. If the "Bcc:" field sent
18747
 
+   contains all of the blind addressees, all of the "Bcc:" recipients
18748
 
+   will be seen by each "Bcc:" recipient.  Even if a separate message is
18749
 
+   sent to each "Bcc:" recipient with only the individual's address,
18750
 
+   implementations still need to be careful to process replies to the
18751
 
+   message as per section 3.6.3 so as not to accidentally reveal the
18752
 
+   blind recipient to other recipients.
18753
 
+
18754
 
+6. Bibliography
18755
 
+
18756
 
+   [ASCII]    American National Standards Institute (ANSI), Coded
18757
 
+              Character Set - 7-Bit American National Standard Code for
18758
 
+              Information Interchange, ANSI X3.4, 1986.
18759
 
+
18760
 
+   [ISO2022] International Organization for Standardization (ISO),
18761
 
+              Information processing - ISO 7-bit and 8-bit coded
18762
 
+              character sets - Code extension techniques, Third edition
18763
 
+              - 1986-05-01, ISO 2022, 1986.
18764
 
+
18765
 
+   [RFC822]   Crocker, D., "Standard for the Format of ARPA Internet
18766
 
+              Text Messages", RFC 822, August 1982.
18767
 
+
18768
 
+   [RFC2045]  Freed, N. and  N. Borenstein, "Multipurpose Internet Mail
18769
 
+              Extensions (MIME) Part One: Format of Internet Message
18770
 
+              Bodies", RFC 2045, November 1996.
18771
 
+
18772
 
+   [RFC2046]  Freed, N. and N. Borenstein, "Multipurpose Internet Mail
18773
 
+              Extensions (MIME) Part Two: Media Types", RFC 2046,
18774
 
+              November 1996.
18775
 
+
18776
 
+
18777
 
+
18778
 
+Resnick                     Standards Track                    [Page 37]
18779
 
+
18780
 
+RFC 2822                Internet Message Format               April 2001
18781
 
+
18782
 
+
18783
 
+   [RFC2047]  Moore, K., "Multipurpose Internet Mail Extensions (MIME)
18784
 
+              Part Three: Message Header Extensions for Non-ASCII Text",
18785
 
+              RFC 2047, November 1996.
18786
 
+
18787
 
+   [RFC2048]  Freed, N., Klensin, J. and J. Postel, "Multipurpose
18788
 
+              Internet Mail Extensions (MIME) Part Four: Format of
18789
 
+              Internet Message Bodies", RFC 2048, November 1996.
18790
 
+
18791
 
+   [RFC2049]  Freed, N. and N. Borenstein, "Multipurpose Internet Mail
18792
 
+              Extensions (MIME) Part Five: Conformance Criteria and
18793
 
+              Examples", RFC 2049, November 1996.
18794
 
+
18795
 
+   [RFC2119]  Bradner, S., "Key words for use in RFCs to Indicate
18796
 
+              Requirement Levels", BCP 14, RFC 2119, March 1997.
18797
 
+
18798
 
+   [RFC2234]  Crocker, D., Editor, and P. Overell, "Augmented BNF for
18799
 
+              Syntax Specifications: ABNF", RFC 2234, November 1997.
18800
 
+
18801
 
+   [RFC2821]  Klensin, J., Editor, "Simple Mail Transfer Protocol", RFC
18802
 
+              2821, March 2001.
18803
 
+
18804
 
+   [STD3]     Braden, R., "Host Requirements", STD 3, RFC 1122 and RFC
18805
 
+              1123, October 1989.
18806
 
+
18807
 
+   [STD12]    Mills, D., "Network Time Protocol", STD 12, RFC 1119,
18808
 
+              September 1989.
18809
 
+
18810
 
+   [STD13]    Mockapetris, P., "Domain Name System", STD 13, RFC 1034
18811
 
+              and RFC 1035,  November 1987.
18812
 
+
18813
 
+   [STD14]    Partridge, C., "Mail Routing and the Domain System", STD
18814
 
+              14, RFC 974, January 1986.
18815
 
+
18816
 
+7. Editor's Address
18817
 
+
18818
 
+   Peter W. Resnick
18819
 
+   QUALCOMM Incorporated
18820
 
+   5775 Morehouse Drive
18821
 
+   San Diego, CA 92121-1714
18822
 
+   USA
18823
 
+
18824
 
+   Phone: +1 858 651 4478
18825
 
+   Fax:   +1 858 651 1102
18826
 
+   EMail: presnick@qualcomm.com
18827
 
+
18828
 
+
18829
 
+
18830
 
+
18831
 
+
18832
 
+
18833
 
+
18834
 
+Resnick                     Standards Track                    [Page 38]
18835
 
+
18836
 
+RFC 2822                Internet Message Format               April 2001
18837
 
+
18838
 
+
18839
 
+8. Acknowledgements
18840
 
+
18841
 
+   Many people contributed to this document.  They included folks who
18842
 
+   participated in the Detailed Revision and Update of Messaging
18843
 
+   Standards (DRUMS) Working Group of the Internet Engineering Task
18844
 
+   Force (IETF), the chair of DRUMS, the Area Directors of the IETF, and
18845
 
+   people who simply sent their comments in via e-mail.  The editor is
18846
 
+   deeply indebted to them all and thanks them sincerely.  The below
18847
 
+   list includes everyone who sent e-mail concerning this document.
18848
 
+   Hopefully, everyone who contributed is named here:
18849
 
+
18850
 
+   Matti Aarnio              Barry Finkel           Larry Masinter
18851
 
+   Tanaka Akira              Erik Forsberg          Denis McKeon
18852
 
+   Russ Allbery              Chuck Foster           William P McQuillan
18853
 
+   Eric Allman               Paul Fox               Alexey Melnikov
18854
 
+   Harald Tveit Alvestrand   Klaus M. Frank         Perry E. Metzger
18855
 
+   Ran Atkinson              Ned Freed              Steven Miller
18856
 
+   Jos Backus                Jochen Friedrich       Keith Moore
18857
 
+   Bruce Balden              Randall C. Gellens     John Gardiner Myers
18858
 
+   Dave Barr                 Sukvinder Singh Gill   Chris Newman
18859
 
+   Alan Barrett              Tim Goodwin            John W. Noerenberg
18860
 
+   John Beck                 Philip Guenther        Eric Norman
18861
 
+   J. Robert von Behren      Tony Hansen            Mike O'Dell
18862
 
+   Jos den Bekker            John Hawkinson         Larry Osterman
18863
 
+   D. J. Bernstein           Philip Hazel           Paul Overell
18864
 
+   James Berriman            Kai Henningsen         Jacob Palme
18865
 
+   Norbert Bollow            Robert Herriot         Michael A. Patton
18866
 
+   Raj Bose                  Paul Hethmon           Uzi Paz
18867
 
+   Antony Bowesman           Jim Hill               Michael A. Quinlan
18868
 
+   Scott Bradner             Paul E. Hoffman        Eric S. Raymond
18869
 
+   Randy Bush                Steve Hole             Sam Roberts
18870
 
+   Tom Byrer                 Kari Hurtta            Hugh Sasse
18871
 
+   Bruce Campbell            Marco S. Hyman         Bart Schaefer
18872
 
+   Larry Campbell            Ofer Inbar             Tom Scola
18873
 
+   W. J. Carpenter           Olle Jarnefors         Wolfgang Segmuller
18874
 
+   Michael Chapman           Kevin Johnson          Nick Shelness
18875
 
+   Richard Clayton           Sudish Joseph          John Stanley
18876
 
+   Maurizio Codogno          Maynard Kang           Einar Stefferud
18877
 
+   Jim Conklin               Prabhat Keni           Jeff Stephenson
18878
 
+   R. Kelley Cook            John C. Klensin        Bernard Stern
18879
 
+   Steve Coya                Graham Klyne           Peter Sylvester
18880
 
+   Mark Crispin              Brad Knowles           Mark Symons
18881
 
+   Dave Crocker              Shuhei Kobayashi       Eric Thomas
18882
 
+   Matt Curtin               Peter Koch             Lee Thompson
18883
 
+   Michael D'Errico          Dan Kohn               Karel De Vriendt
18884
 
+   Cyrus Daboo               Christian Kuhtz        Matthew Wall
18885
 
+   Jutta Degener             Anand Kumria           Rolf Weber
18886
 
+   Mark Delany               Steen Larsen           Brent B. Welch
18887
 
+
18888
 
+
18889
 
+
18890
 
+Resnick                     Standards Track                    [Page 39]
18891
 
+
18892
 
+RFC 2822                Internet Message Format               April 2001
18893
 
+
18894
 
+
18895
 
+   Steve Dorner              Eliot Lear             Dan Wing
18896
 
+   Harold A. Driscoll        Barry Leiba            Jack De Winter
18897
 
+   Michael Elkins            Jay Levitt             Gregory J. Woodhouse
18898
 
+   Robert Elz                Lars-Johan Liman       Greg A. Woods
18899
 
+   Johnny Eriksson           Charles Lindsey        Kazu Yamamoto
18900
 
+   Erik E. Fair              Pete Loshin            Alain Zahm
18901
 
+   Roger Fajman              Simon Lyall            Jamie Zawinski
18902
 
+   Patrik Faltstrom          Bill Manning           Timothy S. Zurcher
18903
 
+   Claus Andre Farber        John Martin
18904
 
+
18905
 
+
18906
 
+
18907
 
+
18908
 
+
18909
 
+
18910
 
+
18911
 
+
18912
 
+
18913
 
+
18914
 
+
18915
 
+
18916
 
+
18917
 
+
18918
 
+
18919
 
+
18920
 
+
18921
 
+
18922
 
+
18923
 
+
18924
 
+
18925
 
+
18926
 
+
18927
 
+
18928
 
+
18929
 
+
18930
 
+
18931
 
+
18932
 
+
18933
 
+
18934
 
+
18935
 
+
18936
 
+
18937
 
+
18938
 
+
18939
 
+
18940
 
+
18941
 
+
18942
 
+
18943
 
+
18944
 
+
18945
 
+
18946
 
+Resnick                     Standards Track                    [Page 40]
18947
 
+
18948
 
+RFC 2822                Internet Message Format               April 2001
18949
 
+
18950
 
+
18951
 
+Appendix A. Example messages
18952
 
+
18953
 
+   This section presents a selection of messages.  These are intended to
18954
 
+   assist in the implementation of this standard, but should not be
18955
 
+   taken as normative; that is to say, although the examples in this
18956
 
+   section were carefully reviewed, if there happens to be a conflict
18957
 
+   between these examples and the syntax described in sections 3 and 4
18958
 
+   of this document, the syntax in those sections is to be taken as
18959
 
+   correct.
18960
 
+
18961
 
+   Messages are delimited in this section between lines of "----".  The
18962
 
+   "----" lines are not part of the message itself.
18963
 
+
18964
 
+A.1. Addressing examples
18965
 
+
18966
 
+   The following are examples of messages that might be sent between two
18967
 
+   individuals.
18968
 
+
18969
 
+A.1.1. A message from one person to another with simple addressing
18970
 
+
18971
 
+   This could be called a canonical message.  It has a single author,
18972
 
+   John Doe, a single recipient, Mary Smith, a subject, the date, a
18973
 
+   message identifier, and a textual message in the body.
18974
 
+
18975
 
+----
18976
 
+From: John Doe <jdoe@machine.example>
18977
 
+To: Mary Smith <mary@example.net>
18978
 
+Subject: Saying Hello
18979
 
+Date: Fri, 21 Nov 1997 09:55:06 -0600
18980
 
+Message-ID: <1234@local.machine.example>
18981
 
+
18982
 
+This is a message just to say hello.
18983
 
+So, "Hello".
18984
 
+----
18985
 
+
18986
 
+
18987
 
+
18988
 
+
18989
 
+
18990
 
+
18991
 
+
18992
 
+
18993
 
+
18994
 
+
18995
 
+
18996
 
+
18997
 
+
18998
 
+
18999
 
+
19000
 
+
19001
 
+
19002
 
+Resnick                     Standards Track                    [Page 41]
19003
 
+
19004
 
+RFC 2822                Internet Message Format               April 2001
19005
 
+
19006
 
+
19007
 
+   If John's secretary Michael actually sent the message, though John
19008
 
+   was the author and replies to this message should go back to him, the
19009
 
+   sender field would be used:
19010
 
+
19011
 
+----
19012
 
+From: John Doe <jdoe@machine.example>
19013
 
+Sender: Michael Jones <mjones@machine.example>
19014
 
+To: Mary Smith <mary@example.net>
19015
 
+Subject: Saying Hello
19016
 
+Date: Fri, 21 Nov 1997 09:55:06 -0600
19017
 
+Message-ID: <1234@local.machine.example>
19018
 
+
19019
 
+This is a message just to say hello.
19020
 
+So, "Hello".
19021
 
+----
19022
 
+
19023
 
+A.1.2. Different types of mailboxes
19024
 
+
19025
 
+   This message includes multiple addresses in the destination fields
19026
 
+   and also uses several different forms of addresses.
19027
 
+
19028
 
+----
19029
 
+From: "Joe Q. Public" <john.q.public@example.com>
19030
 
+To: Mary Smith <mary@x.test>, jdoe@example.org, Who? <one@y.test>
19031
 
+Cc: <boss@nil.test>, "Giant; \"Big\" Box" <sysservices@example.net>
19032
 
+Date: Tue, 1 Jul 2003 10:52:37 +0200
19033
 
+Message-ID: <5678.21-Nov-1997@example.com>
19034
 
+
19035
 
+Hi everyone.
19036
 
+----
19037
 
+
19038
 
+   Note that the display names for Joe Q. Public and Giant; "Big" Box
19039
 
+   needed to be enclosed in double-quotes because the former contains
19040
 
+   the period and the latter contains both semicolon and double-quote
19041
 
+   characters (the double-quote characters appearing as quoted-pair
19042
 
+   construct).  Conversely, the display name for Who? could appear
19043
 
+   without them because the question mark is legal in an atom.  Notice
19044
 
+   also that jdoe@example.org and boss@nil.test have no display names
19045
 
+   associated with them at all, and jdoe@example.org uses the simpler
19046
 
+   address form without the angle brackets.
19047
 
+
19048
 
+
19049
 
+
19050
 
+
19051
 
+
19052
 
+
19053
 
+
19054
 
+
19055
 
+
19056
 
+
19057
 
+
19058
 
+Resnick                     Standards Track                    [Page 42]
19059
 
+
19060
 
+RFC 2822                Internet Message Format               April 2001
19061
 
+
19062
 
+
19063
 
+A.1.3. Group addresses
19064
 
+
19065
 
+----
19066
 
+From: Pete <pete@silly.example>
19067
 
+To: A Group:Chris Jones <c@a.test>,joe@where.test,John <jdoe@one.test>;
19068
 
+Cc: Undisclosed recipients:;
19069
 
+Date: Thu, 13 Feb 1969 23:32:54 -0330
19070
 
+Message-ID: <testabcd.1234@silly.example>
19071
 
+
19072
 
+Testing.
19073
 
+----
19074
 
+
19075
 
+   In this message, the "To:" field has a single group recipient named A
19076
 
+   Group which contains 3 addresses, and a "Cc:" field with an empty
19077
 
+   group recipient named Undisclosed recipients.
19078
 
+
19079
 
+A.2. Reply messages
19080
 
+
19081
 
+   The following is a series of three messages that make up a
19082
 
+   conversation thread between John and Mary.  John firsts sends a
19083
 
+   message to Mary, Mary then replies to John's message, and then John
19084
 
+   replies to Mary's reply message.
19085
 
+
19086
 
+   Note especially the "Message-ID:", "References:", and "In-Reply-To:"
19087
 
+   fields in each message.
19088
 
+
19089
 
+----
19090
 
+From: John Doe <jdoe@machine.example>
19091
 
+To: Mary Smith <mary@example.net>
19092
 
+Subject: Saying Hello
19093
 
+Date: Fri, 21 Nov 1997 09:55:06 -0600
19094
 
+Message-ID: <1234@local.machine.example>
19095
 
+
19096
 
+This is a message just to say hello.
19097
 
+So, "Hello".
19098
 
+----
19099
 
+
19100
 
+
19101
 
+
19102
 
+
19103
 
+
19104
 
+
19105
 
+
19106
 
+
19107
 
+
19108
 
+
19109
 
+
19110
 
+
19111
 
+
19112
 
+
19113
 
+
19114
 
+Resnick                     Standards Track                    [Page 43]
19115
 
+
19116
 
+RFC 2822                Internet Message Format               April 2001
19117
 
+
19118
 
+
19119
 
+   When sending replies, the Subject field is often retained, though
19120
 
+   prepended with "Re: " as described in section 3.6.5.
19121
 
+
19122
 
+----
19123
 
+From: Mary Smith <mary@example.net>
19124
 
+To: John Doe <jdoe@machine.example>
19125
 
+Reply-To: "Mary Smith: Personal Account" <smith@home.example>
19126
 
+Subject: Re: Saying Hello
19127
 
+Date: Fri, 21 Nov 1997 10:01:10 -0600
19128
 
+Message-ID: <3456@example.net>
19129
 
+In-Reply-To: <1234@local.machine.example>
19130
 
+References: <1234@local.machine.example>
19131
 
+
19132
 
+This is a reply to your hello.
19133
 
+----
19134
 
+
19135
 
+   Note the "Reply-To:" field in the above message.  When John replies
19136
 
+   to Mary's message above, the reply should go to the address in the
19137
 
+   "Reply-To:" field instead of the address in the "From:" field.
19138
 
+
19139
 
+----
19140
 
+To: "Mary Smith: Personal Account" <smith@home.example>
19141
 
+From: John Doe <jdoe@machine.example>
19142
 
+Subject: Re: Saying Hello
19143
 
+Date: Fri, 21 Nov 1997 11:00:00 -0600
19144
 
+Message-ID: <abcd.1234@local.machine.tld>
19145
 
+In-Reply-To: <3456@example.net>
19146
 
+References: <1234@local.machine.example> <3456@example.net>
19147
 
+
19148
 
+This is a reply to your reply.
19149
 
+----
19150
 
+
19151
 
+A.3. Resent messages
19152
 
+
19153
 
+   Start with the message that has been used as an example several
19154
 
+   times:
19155
 
+
19156
 
+----
19157
 
+From: John Doe <jdoe@machine.example>
19158
 
+To: Mary Smith <mary@example.net>
19159
 
+Subject: Saying Hello
19160
 
+Date: Fri, 21 Nov 1997 09:55:06 -0600
19161
 
+Message-ID: <1234@local.machine.example>
19162
 
+
19163
 
+This is a message just to say hello.
19164
 
+So, "Hello".
19165
 
+----
19166
 
+
19167
 
+
19168
 
+
19169
 
+
19170
 
+Resnick                     Standards Track                    [Page 44]
19171
 
+
19172
 
+RFC 2822                Internet Message Format               April 2001
19173
 
+
19174
 
+
19175
 
+   Say that Mary, upon receiving this message, wishes to send a copy of
19176
 
+   the message to Jane such that (a) the message would appear to have
19177
 
+   come straight from John; (b) if Jane replies to the message, the
19178
 
+   reply should go back to John; and (c) all of the original
19179
 
+   information, like the date the message was originally sent to Mary,
19180
 
+   the message identifier, and the original addressee, is preserved.  In
19181
 
+   this case, resent fields are prepended to the message:
19182
 
+
19183
 
+----
19184
 
+Resent-From: Mary Smith <mary@example.net>
19185
 
+Resent-To: Jane Brown <j-brown@other.example>
19186
 
+Resent-Date: Mon, 24 Nov 1997 14:22:01 -0800
19187
 
+Resent-Message-ID: <78910@example.net>
19188
 
+From: John Doe <jdoe@machine.example>
19189
 
+To: Mary Smith <mary@example.net>
19190
 
+Subject: Saying Hello
19191
 
+Date: Fri, 21 Nov 1997 09:55:06 -0600
19192
 
+Message-ID: <1234@local.machine.example>
19193
 
+
19194
 
+This is a message just to say hello.
19195
 
+So, "Hello".
19196
 
+----
19197
 
+
19198
 
+   If Jane, in turn, wished to resend this message to another person,
19199
 
+   she would prepend her own set of resent header fields to the above
19200
 
+   and send that.
19201
 
+
19202
 
+
19203
 
+
19204
 
+
19205
 
+
19206
 
+
19207
 
+
19208
 
+
19209
 
+
19210
 
+
19211
 
+
19212
 
+
19213
 
+
19214
 
+
19215
 
+
19216
 
+
19217
 
+
19218
 
+
19219
 
+
19220
 
+
19221
 
+
19222
 
+
19223
 
+
19224
 
+
19225
 
+
19226
 
+Resnick                     Standards Track                    [Page 45]
19227
 
+
19228
 
+RFC 2822                Internet Message Format               April 2001
19229
 
+
19230
 
+
19231
 
+A.4. Messages with trace fields
19232
 
+
19233
 
+   As messages are sent through the transport system as described in
19234
 
+   [RFC2821], trace fields are prepended to the message.  The following
19235
 
+   is an example of what those trace fields might look like.  Note that
19236
 
+   there is some folding white space in the first one since these lines
19237
 
+   can be long.
19238
 
+
19239
 
+----
19240
 
+Received: from x.y.test
19241
 
+   by example.net
19242
 
+   via TCP
19243
 
+   with ESMTP
19244
 
+   id ABC12345
19245
 
+   for <mary@example.net>;  21 Nov 1997 10:05:43 -0600
19246
 
+Received: from machine.example by x.y.test; 21 Nov 1997 10:01:22 -0600
19247
 
+From: John Doe <jdoe@machine.example>
19248
 
+To: Mary Smith <mary@example.net>
19249
 
+Subject: Saying Hello
19250
 
+Date: Fri, 21 Nov 1997 09:55:06 -0600
19251
 
+Message-ID: <1234@local.machine.example>
19252
 
+
19253
 
+This is a message just to say hello.
19254
 
+So, "Hello".
19255
 
+----
19256
 
+
19257
 
+
19258
 
+
19259
 
+
19260
 
+
19261
 
+
19262
 
+
19263
 
+
19264
 
+
19265
 
+
19266
 
+
19267
 
+
19268
 
+
19269
 
+
19270
 
+
19271
 
+
19272
 
+
19273
 
+
19274
 
+
19275
 
+
19276
 
+
19277
 
+
19278
 
+
19279
 
+
19280
 
+
19281
 
+
19282
 
+Resnick                     Standards Track                    [Page 46]
19283
 
+
19284
 
+RFC 2822                Internet Message Format               April 2001
19285
 
+
19286
 
+
19287
 
+A.5. White space, comments, and other oddities
19288
 
+
19289
 
+   White space, including folding white space, and comments can be
19290
 
+   inserted between many of the tokens of fields.  Taking the example
19291
 
+   from A.1.3, white space and comments can be inserted into all of the
19292
 
+   fields.
19293
 
+
19294
 
+----
19295
 
+From: Pete(A wonderful \) chap) <pete(his account)@silly.test(his host)>
19296
 
+To:A Group(Some people)
19297
 
+     :Chris Jones <c@(Chris's host.)public.example>,
19298
 
+         joe@example.org,
19299
 
+  John <jdoe@one.test> (my dear friend); (the end of the group)
19300
 
+Cc:(Empty list)(start)Undisclosed recipients  :(nobody(that I know))  ;
19301
 
+Date: Thu,
19302
 
+      13
19303
 
+        Feb
19304
 
+          1969
19305
 
+      23:32
19306
 
+               -0330 (Newfoundland Time)
19307
 
+Message-ID:              <testabcd.1234@silly.test>
19308
 
+
19309
 
+Testing.
19310
 
+----
19311
 
+
19312
 
+   The above example is aesthetically displeasing, but perfectly legal.
19313
 
+   Note particularly (1) the comments in the "From:" field (including
19314
 
+   one that has a ")" character appearing as part of a quoted-pair); (2)
19315
 
+   the white space absent after the ":" in the "To:" field as well as
19316
 
+   the comment and folding white space after the group name, the special
19317
 
+   character (".") in the comment in Chris Jones's address, and the
19318
 
+   folding white space before and after "joe@example.org,"; (3) the
19319
 
+   multiple and nested comments in the "Cc:" field as well as the
19320
 
+   comment immediately following the ":" after "Cc"; (4) the folding
19321
 
+   white space (but no comments except at the end) and the missing
19322
 
+   seconds in the time of the date field; and (5) the white space before
19323
 
+   (but not within) the identifier in the "Message-ID:" field.
19324
 
+
19325
 
+A.6. Obsoleted forms
19326
 
+
19327
 
+   The following are examples of obsolete (that is, the "MUST NOT
19328
 
+   generate") syntactic elements described in section 4 of this
19329
 
+   document.
19330
 
+
19331
 
+
19332
 
+
19333
 
+
19334
 
+
19335
 
+
19336
 
+
19337
 
+
19338
 
+Resnick                     Standards Track                    [Page 47]
19339
 
+
19340
 
+RFC 2822                Internet Message Format               April 2001
19341
 
+
19342
 
+
19343
 
+A.6.1. Obsolete addressing
19344
 
+
19345
 
+   Note in the below example the lack of quotes around Joe Q. Public,
19346
 
+   the route that appears in the address for Mary Smith, the two commas
19347
 
+   that appear in the "To:" field, and the spaces that appear around the
19348
 
+   "." in the jdoe address.
19349
 
+
19350
 
+----
19351
 
+From: Joe Q. Public <john.q.public@example.com>
19352
 
+To: Mary Smith <@machine.tld:mary@example.net>, , jdoe@test   . example
19353
 
+Date: Tue, 1 Jul 2003 10:52:37 +0200
19354
 
+Message-ID: <5678.21-Nov-1997@example.com>
19355
 
+
19356
 
+Hi everyone.
19357
 
+----
19358
 
+
19359
 
+A.6.2. Obsolete dates
19360
 
+
19361
 
+   The following message uses an obsolete date format, including a non-
19362
 
+   numeric time zone and a two digit year.  Note that although the
19363
 
+   day-of-week is missing, that is not specific to the obsolete syntax;
19364
 
+   it is optional in the current syntax as well.
19365
 
+
19366
 
+----
19367
 
+From: John Doe <jdoe@machine.example>
19368
 
+To: Mary Smith <mary@example.net>
19369
 
+Subject: Saying Hello
19370
 
+Date: 21 Nov 97 09:55:06 GMT
19371
 
+Message-ID: <1234@local.machine.example>
19372
 
+
19373
 
+This is a message just to say hello.
19374
 
+So, "Hello".
19375
 
+----
19376
 
+
19377
 
+A.6.3. Obsolete white space and comments
19378
 
+
19379
 
+   White space and comments can appear between many more elements than
19380
 
+   in the current syntax.  Also, folding lines that are made up entirely
19381
 
+   of white space are legal.
19382
 
+
19383
 
+
19384
 
+
19385
 
+
19386
 
+
19387
 
+
19388
 
+
19389
 
+
19390
 
+
19391
 
+
19392
 
+
19393
 
+
19394
 
+Resnick                     Standards Track                    [Page 48]
19395
 
+
19396
 
+RFC 2822                Internet Message Format               April 2001
19397
 
+
19398
 
+
19399
 
+----
19400
 
+From  : John Doe <jdoe@machine(comment).  example>
19401
 
+To    : Mary Smith
19402
 
+__
19403
 
+          <mary@example.net>
19404
 
+Subject     : Saying Hello
19405
 
+Date  : Fri, 21 Nov 1997 09(comment):   55  :  06 -0600
19406
 
+Message-ID  : <1234   @   local(blah)  .machine .example>
19407
 
+
19408
 
+This is a message just to say hello.
19409
 
+So, "Hello".
19410
 
+----
19411
 
+
19412
 
+   Note especially the second line of the "To:" field.  It starts with
19413
 
+   two space characters.  (Note that "__" represent blank spaces.)
19414
 
+   Therefore, it is considered part of the folding as described in
19415
 
+   section 4.2.  Also, the comments and white space throughout
19416
 
+   addresses, dates, and message identifiers are all part of the
19417
 
+   obsolete syntax.
19418
 
+
19419
 
+Appendix B. Differences from earlier standards
19420
 
+
19421
 
+   This appendix contains a list of changes that have been made in the
19422
 
+   Internet Message Format from earlier standards, specifically [RFC822]
19423
 
+   and [STD3].  Items marked with an asterisk (*) below are items which
19424
 
+   appear in section 4 of this document and therefore can no longer be
19425
 
+   generated.
19426
 
+
19427
 
+   1. Period allowed in obsolete form of phrase.
19428
 
+   2. ABNF moved out of document to [RFC2234].
19429
 
+   3. Four or more digits allowed for year.
19430
 
+   4. Header field ordering (and lack thereof) made explicit.
19431
 
+   5. Encrypted header field removed.
19432
 
+   6. Received syntax loosened to allow any token/value pair.
19433
 
+   7. Specifically allow and give meaning to "-0000" time zone.
19434
 
+   8. Folding white space is not allowed between every token.
19435
 
+   9. Requirement for destinations removed.
19436
 
+   10. Forwarding and resending redefined.
19437
 
+   11. Extension header fields no longer specifically called out.
19438
 
+   12. ASCII 0 (null) removed.*
19439
 
+   13. Folding continuation lines cannot contain only white space.*
19440
 
+   14. Free insertion of comments not allowed in date.*
19441
 
+   15. Non-numeric time zones not allowed.*
19442
 
+   16. Two digit years not allowed.*
19443
 
+   17. Three digit years interpreted, but not allowed for generation.
19444
 
+   18. Routes in addresses not allowed.*
19445
 
+   19. CFWS within local-parts and domains not allowed.*
19446
 
+   20. Empty members of address lists not allowed.*
19447
 
+
19448
 
+
19449
 
+
19450
 
+Resnick                     Standards Track                    [Page 49]
19451
 
+
19452
 
+RFC 2822                Internet Message Format               April 2001
19453
 
+
19454
 
+
19455
 
+   21. Folding white space between field name and colon not allowed.*
19456
 
+   22. Comments between field name and colon not allowed.
19457
 
+   23. Tightened syntax of in-reply-to and references.*
19458
 
+   24. CFWS within msg-id not allowed.*
19459
 
+   25. Tightened semantics of resent fields as informational only.
19460
 
+   26. Resent-Reply-To not allowed.*
19461
 
+   27. No multiple occurrences of fields (except resent and received).*
19462
 
+   28. Free CR and LF not allowed.*
19463
 
+   29. Routes in return path not allowed.*
19464
 
+   30. Line length limits specified.
19465
 
+   31. Bcc more clearly specified.
19466
 
+
19467
 
+Appendix C. Notices
19468
 
+
19469
 
+   Intellectual Property
19470
 
+
19471
 
+   The IETF takes no position regarding the validity or scope of any
19472
 
+   intellectual property or other rights that might be claimed to
19473
 
+   pertain to the implementation or use of the technology described in
19474
 
+   this document or the extent to which any license under such rights
19475
 
+   might or might not be available; neither does it represent that it
19476
 
+   has made any effort to identify any such rights.  Information on the
19477
 
+   IETF's procedures with respect to rights in standards-track and
19478
 
+   standards-related documentation can be found in BCP-11.  Copies of
19479
 
+   claims of rights made available for publication and any assurances of
19480
 
+   licenses to be made available, or the result of an attempt made to
19481
 
+   obtain a general license or permission for the use of such
19482
 
+   proprietary rights by implementors or users of this specification can
19483
 
+   be obtained from the IETF Secretariat.
19484
 
+
19485
 
+
19486
 
+
19487
 
+
19488
 
+
19489
 
+
19490
 
+
19491
 
+
19492
 
+
19493
 
+
19494
 
+
19495
 
+
19496
 
+
19497
 
+
19498
 
+
19499
 
+
19500
 
+
19501
 
+
19502
 
+
19503
 
+
19504
 
+
19505
 
+
19506
 
+Resnick                     Standards Track                    [Page 50]
19507
 
+
19508
 
+RFC 2822                Internet Message Format               April 2001
19509
 
+
19510
 
+
19511
 
+Full Copyright Statement
19512
 
+
19513
 
+   Copyright (C) The Internet Society (2001).  All Rights Reserved.
19514
 
+
19515
 
+   This document and translations of it may be copied and furnished to
19516
 
+   others, and derivative works that comment on or otherwise explain it
19517
 
+   or assist in its implementation may be prepared, copied, published
19518
 
+   and distributed, in whole or in part, without restriction of any
19519
 
+   kind, provided that the above copyright notice and this paragraph are
19520
 
+   included on all such copies and derivative works.  However, this
19521
 
+   document itself may not be modified in any way, such as by removing
19522
 
+   the copyright notice or references to the Internet Society or other
19523
 
+   Internet organizations, except as needed for the purpose of
19524
 
+   developing Internet standards in which case the procedures for
19525
 
+   copyrights defined in the Internet Standards process must be
19526
 
+   followed, or as required to translate it into languages other than
19527
 
+   English.
19528
 
+
19529
 
+   The limited permissions granted above are perpetual and will not be
19530
 
+   revoked by the Internet Society or its successors or assigns.
19531
 
+
19532
 
+   This document and the information contained herein is provided on an
19533
 
+   "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
19534
 
+   TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
19535
 
+   BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
19536
 
+   HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
19537
 
+   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
19538
 
+
19539
 
+Acknowledgement
19540
 
+
19541
 
+   Funding for the RFC Editor function is currently provided by the
19542
 
+   Internet Society.
19543
 
+
19544
 
+
19545
 
+
19546
 
+
19547
 
+
19548
 
+
19549
 
+
19550
 
+
19551
 
+
19552
 
+
19553
 
+
19554
 
+
19555
 
+
19556
 
+
19557
 
+
19558
 
+
19559
 
+
19560
 
+
19561
 
+
19562
 
+Resnick                     Standards Track                    [Page 51]
19563
 
+
19564
 
diff -urN dovecot-1.2.4/dovecot-libsieve/doc/rfc/imap4flags.rfc5232.txt dovecot-1.2.4.debian/dovecot-libsieve/doc/rfc/imap4flags.rfc5232.txt
19565
 
--- dovecot-1.2.4/dovecot-libsieve/doc/rfc/imap4flags.rfc5232.txt       1970-01-01 01:00:00.000000000 +0100
19566
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/doc/rfc/imap4flags.rfc5232.txt        2008-08-04 10:39:20.000000000 +0200
19567
 
@@ -0,0 +1,675 @@
19568
 
+
19569
 
+
19570
 
+
19571
 
+
19572
 
+
19573
 
+
19574
 
+Network Working Group                                       A.  Melnikov
19575
 
+Request for Comments: 5232                                 Isode Limited
19576
 
+Category: Standards Track                                   January 2008
19577
 
+
19578
 
+
19579
 
+              Sieve Email Filtering: Imap4flags Extension
19580
 
+
19581
 
+Status of This Memo
19582
 
+
19583
 
+   This document specifies an Internet standards track protocol for the
19584
 
+   Internet community, and requests discussion and suggestions for
19585
 
+   improvements.  Please refer to the current edition of the "Internet
19586
 
+   Official Protocol Standards" (STD 1) for the standardization state
19587
 
+   and status of this protocol.  Distribution of this memo is unlimited.
19588
 
+
19589
 
+Abstract
19590
 
+
19591
 
+   Recent discussions have shown that it is desirable to set different
19592
 
+   IMAP (RFC 3501) flags on message delivery.  This can be done, for
19593
 
+   example, by a Sieve interpreter that works as a part of a Mail
19594
 
+   Delivery Agent.
19595
 
+
19596
 
+   This document describes an extension to the Sieve mail filtering
19597
 
+   language for setting IMAP flags.  The extension allows setting of
19598
 
+   both IMAP system flags and IMAP keywords.
19599
 
+
19600
 
+Table of Contents
19601
 
+
19602
 
+   1. Introduction ....................................................2
19603
 
+      1.1. Conventions Used ...........................................2
19604
 
+   2. General Requirements for Flag Handling ..........................3
19605
 
+   3. Actions .........................................................3
19606
 
+      3.1. Action setflag .............................................4
19607
 
+      3.2. Action addflag .............................................4
19608
 
+      3.3. Action removeflag ..........................................5
19609
 
+   4. Test hasflag ....................................................6
19610
 
+   5. Tagged Argument :flags ..........................................7
19611
 
+   6. Interaction with Other Sieve Actions ............................8
19612
 
+   7. Security Considerations .........................................8
19613
 
+   8. IANA Considerations .............................................8
19614
 
+   9. Extended Example ................................................8
19615
 
+   10. Acknowledgments ...............................................10
19616
 
+   11. Normative References ..........................................10
19617
 
+
19618
 
+
19619
 
+
19620
 
+
19621
 
+
19622
 
+
19623
 
+
19624
 
+
19625
 
+Melnikov                    Standards Track                     [Page 1]
19626
 
+
19627
 
+RFC 5232              Sieve: Imap4flags Extension           January 2008
19628
 
+
19629
 
+
19630
 
+1.  Introduction
19631
 
+
19632
 
+   This is an extension to the Sieve language defined by [SIEVE] for
19633
 
+   setting [IMAP] flags.  It adds a new tagged argument to "keep" and
19634
 
+   "fileinto" that describes the list of flags that have to be set when
19635
 
+   the message is delivered to the specified mailbox.  It also adds
19636
 
+   several actions to help manipulate list of flags and a test to check
19637
 
+   whether a flag belongs to a list.
19638
 
+
19639
 
+   From the user's perspective, this extension provides several
19640
 
+   capabilities.  First, it allows manipulation of sets of IMAP flags.
19641
 
+   Second, it gives the ability to associate a set of IMAP flags with a
19642
 
+   message that is delivered to a mailstore using the keep/fileinto
19643
 
+   actions.  Third, it maintains an internal variable.  The internal
19644
 
+   variable contains the default flags that will be associated with a
19645
 
+   message that is delivered using the keep, implicit keep, or fileinto
19646
 
+   actions, when the :flags tagged argument is not specified.  When the
19647
 
+   Sieve [VARIABLES] extension is also supported by the Sieve engine, it
19648
 
+   enables support for multiple variables containing sets of IMAP flags.
19649
 
+
19650
 
+   The capability string associated with the extension defined in this
19651
 
+   document is "imap4flags".  All conformant implementations MUST
19652
 
+   implement all Sieve actions (setflag, addflag, removeflag), the
19653
 
+   "hasflag" test, and the ":flags" tagged argument described in this
19654
 
+   document.
19655
 
+
19656
 
+   The "imap4flags" extension can be used with or without the
19657
 
+   "variables" extension [VARIABLES].  When the "variables" extension is
19658
 
+   enabled in a script using <require "variables">, the script can use
19659
 
+   explicit variable names in setflag/addflag/removeflag actions and the
19660
 
+   hasflag test.  See also Section 3 for more details.  When the
19661
 
+   "variables" extension is not enabled, the explicit variable name
19662
 
+   parameter to setflag/addflag/removeflag/hasflag MUST NOT be used and
19663
 
+   MUST cause an error according to [SIEVE].
19664
 
+
19665
 
+1.1.  Conventions Used
19666
 
+
19667
 
+   Conventions for notations are as in [SIEVE], Section 1.1, including
19668
 
+   use of "Usage:" label for the definition of action and tagged
19669
 
+   arguments syntax.
19670
 
+
19671
 
+   The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
19672
 
+   "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
19673
 
+   document are to be interpreted as described in RFC 2119.
19674
 
+
19675
 
+
19676
 
+
19677
 
+
19678
 
+
19679
 
+
19680
 
+
19681
 
+Melnikov                    Standards Track                     [Page 2]
19682
 
+
19683
 
+RFC 5232              Sieve: Imap4flags Extension           January 2008
19684
 
+
19685
 
+
19686
 
+2.  General Requirements for Flag Handling
19687
 
+
19688
 
+   The following notes apply to processing of addflag/removeflag/setflag
19689
 
+   actions, the "hasflag" test and the ":flags" tagged argument.
19690
 
+
19691
 
+   A Sieve interpreter MUST ignore empty strings (i.e., "") in a list-
19692
 
+   of-flags parameter.
19693
 
+
19694
 
+   A string containing a space-separated list of flag names is
19695
 
+   equivalent to a string list consisting of the flags.  This
19696
 
+   requirement is to simplify amalgamation of multiple flag lists.
19697
 
+
19698
 
+   The Sieve interpreter SHOULD check the list of flags for validity as
19699
 
+   described by [IMAP] ABNF.  In particular, according to [IMAP], non-
19700
 
+   ASCII characters are not allowed in flag names.  However, spaces MUST
19701
 
+   always be allowed as delimiters in strings representing a list of
19702
 
+   flags.  In such strings, multiple spaces between flag names MUST be
19703
 
+   treated as a single space character, and leading and trailing spaces
19704
 
+   MUST be ignored.
19705
 
+
19706
 
+   If a flag validity check fails, the flag MUST be ignored.
19707
 
+
19708
 
+   Note that it is not possible to use this extension to set or clear
19709
 
+   the \Recent flag or any other special system flag that is not
19710
 
+   settable in [IMAP].  Any such flags MUST be ignored if included in a
19711
 
+   flag list.
19712
 
+
19713
 
+3.  Actions
19714
 
+
19715
 
+   All actions described in this specification (setflag, addflag,
19716
 
+   removeflag) operate on string variables that contain a set of [IMAP]
19717
 
+   flags.  On variable substitution, a set of flags is represented as a
19718
 
+   string containing a space-separated list of flag names.
19719
 
+
19720
 
+   Any setflag/addflag/removeflag action MAY alter the flag list in any
19721
 
+   way that leaves its semantics as a set of case-insensitive words
19722
 
+   unaltered.  For example, it may reorder the flags, alter the case of
19723
 
+   the letters in them, or add or remove duplicates or extraneous
19724
 
+   spaces.  Scripts MUST NOT make assumptions about the ordering of
19725
 
+   flags in lists or the preservation of their case.
19726
 
+
19727
 
+   Note that the parameter specifying a variable name to
19728
 
+   setflag/addflag/removeflag actions and the hasflag test is optional.
19729
 
+   If the parameter is not specified, the actions operate on the
19730
 
+   internal variable, which has the empty value when the script starts
19731
 
+   execution.  If the SIEVE interpreter doesn't support the "variables"
19732
 
+   extension [VARIABLES], the presence of the variable name parameter
19733
 
+   will cause a runtime error [SIEVE].
19734
 
+
19735
 
+
19736
 
+
19737
 
+Melnikov                    Standards Track                     [Page 3]
19738
 
+
19739
 
+RFC 5232              Sieve: Imap4flags Extension           January 2008
19740
 
+
19741
 
+
19742
 
+   The "addflag" action adds flags to an existing set.  The "removeflag"
19743
 
+   action removes flags from an existing set.  The "setflag" action
19744
 
+   replaces an existing set of flags with a new set.  The "set" action
19745
 
+   defined in [VARIABLES] can be used to replace an existing set of
19746
 
+   flags with a new set as well.  However, it should be noted that the
19747
 
+   "set" action can't perform any flag reordering, duplicate
19748
 
+   elimination, etc.
19749
 
+
19750
 
+   The :flags tagged argument to "keep" and "fileinto" actions is used
19751
 
+   to associate a set of flags with the current message.  If the :flags
19752
 
+   tagged argument is not specified with those two actions, the current
19753
 
+   value of the internal variable is used instead.  The value of the
19754
 
+   internal variable also applies to the implicit keep.
19755
 
+
19756
 
+   Note that when keep/fileinto is used multiple times in a script and
19757
 
+   duplicate message elimination is performed (as described in Section
19758
 
+   2.10.3 of [SIEVE]), the last flag list value MUST win.
19759
 
+
19760
 
+3.1.  Action setflag
19761
 
+
19762
 
+   Usage:   setflag [<variablename: string>]
19763
 
+            <list-of-flags: string-list>
19764
 
+
19765
 
+   Setflag is used for setting [IMAP] system flags or keywords.
19766
 
+   Setflag replaces any previously set flags.
19767
 
+
19768
 
+
19769
 
+   Example:  if size :over 500K {
19770
 
+                 setflag "\\Deleted";
19771
 
+             }
19772
 
+
19773
 
+   A more substantial example is the following:
19774
 
+
19775
 
+   Example:
19776
 
+        if header :contains "from" "boss@frobnitzm.example.edu" {
19777
 
+            setflag "flagvar" "\\Flagged";
19778
 
+            fileinto :flags "${flagvar}" "INBOX.From Boss";
19779
 
+        }
19780
 
+
19781
 
+3.2.  Action addflag
19782
 
+
19783
 
+   Usage:   addflag [<variablename: string>]
19784
 
+            <list-of-flags: string-list>
19785
 
+
19786
 
+   Addflag is used to add flags to a list of [IMAP] flags.  It doesn't
19787
 
+   replace any previously set flags.  This means that multiple
19788
 
+   occurrences of addflag are treated additively.
19789
 
+
19790
 
+
19791
 
+
19792
 
+
19793
 
+Melnikov                    Standards Track                     [Page 4]
19794
 
+
19795
 
+RFC 5232              Sieve: Imap4flags Extension           January 2008
19796
 
+
19797
 
+
19798
 
+   The following examples demonstrate requirements described in Section
19799
 
+   2.1.  The following two actions
19800
 
+
19801
 
+      addflag "flagvar" "\\Deleted";
19802
 
+      addflag "flagvar" "\\Answered";
19803
 
+
19804
 
+   produce the same result as the single action
19805
 
+
19806
 
+      addflag "flagvar" ["\\Deleted", "\\Answered"];
19807
 
+
19808
 
+   or
19809
 
+
19810
 
+      addflag "flagvar" "\\Deleted \\Answered";
19811
 
+
19812
 
+   or
19813
 
+
19814
 
+      addflag "flagvar" "\\Answered \\Deleted";
19815
 
+
19816
 
+3.3.  Action removeflag
19817
 
+
19818
 
+   Usage:   removeflag [<variablename: string>]
19819
 
+            <list-of-flags: string-list>
19820
 
+
19821
 
+   Removeflag is used to remove flags from a list of [IMAP] flags.
19822
 
+   Removeflag clears flags previously set by "set"/"addflag".  Calling
19823
 
+   removeflag with a flag that wasn't set before is not an error and is
19824
 
+   ignored.  Note that if an implementation doesn't perform automatic
19825
 
+   duplicate elimination, it MUST remove all occurrences of the flags
19826
 
+   specified in the second parameter to removeflag.  Empty strings in
19827
 
+   the list-of-flags MUST be ignored.  Also note that flag names are
19828
 
+   case-insensitive, as described in [IMAP].  Multiple removeflag
19829
 
+   actions are treated additively.
19830
 
+
19831
 
+      Example:
19832
 
+        if header :contains "Disposition-Notification-To"
19833
 
+           "mel@example.com" {
19834
 
+            addflag "flagvar" "$MDNRequired";
19835
 
+        }
19836
 
+        if header :contains "from" "imap@cac.washington.example.edu" {
19837
 
+            removeflag "flagvar" "$MDNRequired";
19838
 
+            fileinto :flags "${flagvar}" "INBOX.imap-list";
19839
 
+        }
19840
 
+
19841
 
+
19842
 
+
19843
 
+
19844
 
+
19845
 
+
19846
 
+
19847
 
+
19848
 
+
19849
 
+Melnikov                    Standards Track                     [Page 5]
19850
 
+
19851
 
+RFC 5232              Sieve: Imap4flags Extension           January 2008
19852
 
+
19853
 
+
19854
 
+4.  Test hasflag
19855
 
+
19856
 
+   Usage: hasflag [MATCH-TYPE] [COMPARATOR]
19857
 
+          [<variable-list: string-list>]
19858
 
+          <list-of-flags: string-list>
19859
 
+
19860
 
+   The hasflag test evaluates to true if any of the variables matches
19861
 
+   any flag name.  The type of match defaults to ":is".  If the list of
19862
 
+   variables is omitted, value of the internal variable is used instead.
19863
 
+
19864
 
+   The default comparator is "i;ascii-casemap", which is the same case-
19865
 
+   insensitive comparison as defined for IMAP flags by [IMAP].
19866
 
+
19867
 
+   The "relational" extension [RELATIONAL] adds a match type called
19868
 
+   ":count".  The :count of a variable returns the number of distinct
19869
 
+   flags in it.  The count of a list of variables is the sum of the
19870
 
+   counts of the member variables.
19871
 
+
19872
 
+   Example:
19873
 
+     If the internal variable has the value "A B", the following test
19874
 
+
19875
 
+      hasflag :is "b A"
19876
 
+
19877
 
+     evaluates to true.  The above test can also be written as
19878
 
+
19879
 
+      hasflag ["b","A"]
19880
 
+
19881
 
+   Example:
19882
 
+     If the variable "MyVar" has value "NonJunk Junk gnus-forward
19883
 
+     $Forwarded NotJunk JunkRecorded $Junk $NotJunk", the following
19884
 
+     tests evaluate to true:
19885
 
+
19886
 
+      hasflag :contains "MyVar" "Junk"
19887
 
+      hasflag :contains "MyVar" "forward"
19888
 
+      hasflag :contains "MyVar" ["label", "forward"]
19889
 
+      hasflag :contains "MyVar" ["junk", "forward"]
19890
 
+
19891
 
+     Note that the last of these tests can be rewritten
19892
 
+     as
19893
 
+
19894
 
+      hasflag :contains "MyVar" "junk forward"
19895
 
+
19896
 
+     or
19897
 
+
19898
 
+      hasflag :contains "MyVar" "forward junk"
19899
 
+
19900
 
+     However, the last two forms are not recommended.
19901
 
+
19902
 
+
19903
 
+
19904
 
+
19905
 
+Melnikov                    Standards Track                     [Page 6]
19906
 
+
19907
 
+RFC 5232              Sieve: Imap4flags Extension           January 2008
19908
 
+
19909
 
+
19910
 
+     And the following tests will evaluate to false:
19911
 
+
19912
 
+      hasflag :contains "MyVar" "label"
19913
 
+
19914
 
+      hasflag :contains "MyVar" ["label1", "label2"]
19915
 
+
19916
 
+   Example:
19917
 
+     If the variable "MyFlags" has the value "A B", the following test
19918
 
+
19919
 
+       hasflag :count "ge" :comparator "i;ascii-numeric"
19920
 
+               "MyFlags" "2"
19921
 
+
19922
 
+     evaluates to true, as the variable contains 2 distinct flags.
19923
 
+
19924
 
+5.  Tagged Argument :flags
19925
 
+
19926
 
+   This specification adds a new optional tagged argument ":flags" that
19927
 
+   alters the behavior of actions "keep" and "fileinto".
19928
 
+
19929
 
+   The :flags tagged argument specifies that the flags provided in the
19930
 
+   subsequent argument should be set when fileinto/keep delivers the
19931
 
+   message to the target mailbox/user's main mailbox.  If the :flags
19932
 
+   tagged argument is not specified, "keep" or "fileinto" will use the
19933
 
+   current value of the internal variable when delivering the message to
19934
 
+   the target mailbox.
19935
 
+
19936
 
+   Usage:   ":flags" <list-of-flags: string-list>
19937
 
+
19938
 
+   The copy of the message filed into the mailbox will have only flags
19939
 
+   listed after the :flags tagged argument.
19940
 
+
19941
 
+   The Sieve interpreter MUST ignore all flags that it can't store
19942
 
+   permanently.  This means that the interpreter MUST NOT treat failure
19943
 
+   to store any flag as a runtime failure to execute the Sieve script.
19944
 
+   For example, if the mailbox "INBOX.From Boss" can't store any flags,
19945
 
+   then
19946
 
+
19947
 
+     fileinto :flags "\\Deleted" "INBOX.From Boss";
19948
 
+
19949
 
+   and
19950
 
+
19951
 
+     fileinto "INBOX.From Boss";
19952
 
+
19953
 
+   are equivalent.
19954
 
+
19955
 
+   This document doesn't dictate how the Sieve interpreter will set the
19956
 
+   [IMAP] flags.  In particular, the Sieve interpreter may work as an
19957
 
+   IMAP client or may have direct access to the mailstore.
19958
 
+
19959
 
+
19960
 
+
19961
 
+Melnikov                    Standards Track                     [Page 7]
19962
 
+
19963
 
+RFC 5232              Sieve: Imap4flags Extension           January 2008
19964
 
+
19965
 
+
19966
 
+6.  Interaction with Other Sieve Actions
19967
 
+
19968
 
+   This extension works only on the message that is currently being
19969
 
+   processed by Sieve; it doesn't affect another message generated as a
19970
 
+   side effect of any action or any other message already in the
19971
 
+   mailstore.
19972
 
+
19973
 
+   The extension described in this document doesn't change the implicit
19974
 
+   keep (see Section 2.10.2 of [SIEVE]).
19975
 
+
19976
 
+7.  Security Considerations
19977
 
+
19978
 
+   Security considerations are discussed in [IMAP], [SIEVE], and
19979
 
+   [VARIABLES].
19980
 
+
19981
 
+   This extension intentionally doesn't allow setting [IMAP] flags on an
19982
 
+   arbitrary message in the [IMAP] message store.
19983
 
+
19984
 
+   It is believed that this extension doesn't introduce any additional
19985
 
+   security concerns.
19986
 
+
19987
 
+8.  IANA Considerations
19988
 
+
19989
 
+   The following template specifies the IANA registration of the
19990
 
+   variables Sieve extension specified in this document:
19991
 
+
19992
 
+   To: iana@iana.org
19993
 
+   Subject: Registration of new Sieve extension
19994
 
+
19995
 
+   Capability name: imap4flags
19996
 
+   Description:     Adds actions and tests for manipulating IMAP flags
19997
 
+   RFC number:      RFC 5232
19998
 
+   Contact address: The Sieve discussion list <ietf-mta-filters@imc.org>
19999
 
+
20000
 
+   This information has been added to the list of Sieve extensions given
20001
 
+   on http://www.iana.org/assignments/sieve-extensions.
20002
 
+
20003
 
+9.  Extended Example
20004
 
+
20005
 
+   #
20006
 
+   # Example Sieve Filter
20007
 
+   # Declare any optional features or extension used by the script
20008
 
+   #
20009
 
+   require ["fileinto", "imap4flags", "variables"];
20010
 
+
20011
 
+   #
20012
 
+   # Move large messages to a special mailbox
20013
 
+   #
20014
 
+
20015
 
+
20016
 
+
20017
 
+Melnikov                    Standards Track                     [Page 8]
20018
 
+
20019
 
+RFC 5232              Sieve: Imap4flags Extension           January 2008
20020
 
+
20021
 
+
20022
 
+   if size :over 1M
20023
 
+           {
20024
 
+           addflag "MyFlags" "Big";
20025
 
+           if header :is "From" "boss@company.example.com"
20026
 
+                      {
20027
 
+   # The message will be marked as "\Flagged Big" when filed into
20028
 
+   # mailbox "Big messages"
20029
 
+                      addflag "MyFlags" "\\Flagged";
20030
 
+                      }
20031
 
+           fileinto :flags "${MyFlags}" "Big messages";
20032
 
+           }
20033
 
+
20034
 
+   if header :is "From" "grandma@example.net"
20035
 
+           {
20036
 
+           addflag "MyFlags" ["\\Answered", "$MDNSent"];
20037
 
+   # If the message is bigger than 1Mb it will be marked as
20038
 
+   # "Big \Answered $MDNSent" when filed into mailbox "grandma".
20039
 
+   # If the message is shorter than 1Mb it will be marked as
20040
 
+   # "\Answered $MDNSent"
20041
 
+           fileinto :flags "${MyFlags}" "GrandMa";
20042
 
+           }
20043
 
+
20044
 
+   #
20045
 
+   # Handle messages from known mailing lists
20046
 
+   # Move messages from IETF filter discussion list to filter folder
20047
 
+   #
20048
 
+   if header :is "Sender" "owner-ietf-mta-filters@example.org"
20049
 
+           {
20050
 
+           set "MyFlags" "\\Flagged $Work";
20051
 
+   # Message will have both "\Flagged" and $Work flags
20052
 
+           keep :flags "${MyFlags}";
20053
 
+           }
20054
 
+
20055
 
+   #
20056
 
+   # Keep all messages to or from people in my company
20057
 
+   #
20058
 
+   elsif anyof address :domain :is ["From", "To"] "company.example.com"
20059
 
+           {
20060
 
+           keep :flags "${MyFlags}"; # keep in "Inbox" folder
20061
 
+           }
20062
 
+
20063
 
+   # Try to catch unsolicited email.  If a message is not to me,
20064
 
+   # or it contains a subject known to be spam, file it away.
20065
 
+   #
20066
 
+   elsif anyof (not address :all :contains
20067
 
+                  ["To", "Cc"] "me@company.example.com",
20068
 
+                header :matches "subject"
20069
 
+                  ["*make*money*fast*", "*university*dipl*mas*"])
20070
 
+
20071
 
+
20072
 
+
20073
 
+Melnikov                    Standards Track                     [Page 9]
20074
 
+
20075
 
+RFC 5232              Sieve: Imap4flags Extension           January 2008
20076
 
+
20077
 
+
20078
 
+           {
20079
 
+           remove "MyFlags" "\\Flagged";
20080
 
+           fileinto :flags "${MyFlags}" "spam";
20081
 
+           }
20082
 
+   else
20083
 
+           {
20084
 
+           # Move all other external mail to "personal"
20085
 
+           # folder.
20086
 
+           fileinto :flags "${MyFlags}" "personal";
20087
 
+           }
20088
 
+
20089
 
+10.  Acknowledgments
20090
 
+
20091
 
+   This document has been revised in part based on comments and
20092
 
+   discussions that took place on and off the Sieve mailing list.
20093
 
+
20094
 
+   The help of those who took the time to review the document and make
20095
 
+   suggestions is appreciated, especially that of Tim Showalter, Barry
20096
 
+   Leiba, Randall Gellens, Ken Murchison, Cyrus Daboo, Matthew Elvey,
20097
 
+   Jutta Degener, Ned Freed, Marc Mutz, Nigel Swinson, Kjetil Torgrim
20098
 
+   Homme, Mark E.  Mallett, Dave Cridland, Arnt Gulbrandsen, Philip
20099
 
+   Guenther, Rob Austein, Sam Hartman, Eric Gray, and Cullen Jennings.
20100
 
+
20101
 
+   Special thanks to Tony Hansen and David Lamb for helping me better
20102
 
+   explain the concept.
20103
 
+
20104
 
+11.  Normative References
20105
 
+
20106
 
+   [SIEVE]      Guenther, P., Ed., and T. Showalter, Ed., "Sieve: An
20107
 
+                Email Filtering Language", RFC 5228, January 2008.
20108
 
+
20109
 
+   [IMAP]       Crispin, M., "INTERNET MESSAGE ACCESS PROTOCOL - VERSION
20110
 
+                4rev1", RFC 3501, March 2003.
20111
 
+
20112
 
+   [VARIABLES]  Homme, K., "Sieve Email Filtering: Variables Extension",
20113
 
+                RFC 5229, January 2008.
20114
 
+
20115
 
+   [RELATIONAL] Segmuller, W. and B. Leiba "Sieve Email Filtering:
20116
 
+                Relational Extension", RFC 5231, January 2008.
20117
 
+
20118
 
+
20119
 
+
20120
 
+
20121
 
+
20122
 
+
20123
 
+
20124
 
+
20125
 
+
20126
 
+
20127
 
+
20128
 
+
20129
 
+Melnikov                    Standards Track                    [Page 10]
20130
 
+
20131
 
+RFC 5232              Sieve: Imap4flags Extension           January 2008
20132
 
+
20133
 
+
20134
 
+Author's Address
20135
 
+
20136
 
+   Alexey Melnikov
20137
 
+   Isode Limited
20138
 
+
20139
 
+   5 Castle Business Village
20140
 
+   Hampton, Middlesex
20141
 
+   United Kingdom, TW12 2BX
20142
 
+
20143
 
+   EMail: alexey.melnikov@isode.com
20144
 
+
20145
 
+
20146
 
+
20147
 
+
20148
 
+
20149
 
+
20150
 
+
20151
 
+
20152
 
+
20153
 
+
20154
 
+
20155
 
+
20156
 
+
20157
 
+
20158
 
+
20159
 
+
20160
 
+
20161
 
+
20162
 
+
20163
 
+
20164
 
+
20165
 
+
20166
 
+
20167
 
+
20168
 
+
20169
 
+
20170
 
+
20171
 
+
20172
 
+
20173
 
+
20174
 
+
20175
 
+
20176
 
+
20177
 
+
20178
 
+
20179
 
+
20180
 
+
20181
 
+
20182
 
+
20183
 
+
20184
 
+
20185
 
+Melnikov                    Standards Track                    [Page 11]
20186
 
+
20187
 
+RFC 5232              Sieve: Imap4flags Extension           January 2008
20188
 
+
20189
 
+
20190
 
+Full Copyright Statement
20191
 
+
20192
 
+   Copyright (C) The IETF Trust (2008).
20193
 
+
20194
 
+   This document is subject to the rights, licenses and restrictions
20195
 
+   contained in BCP 78, and except as set forth therein, the authors
20196
 
+   retain all their rights.
20197
 
+
20198
 
+   This document and the information contained herein are provided on an
20199
 
+   "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS
20200
 
+   OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY, THE IETF TRUST AND
20201
 
+   THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS
20202
 
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF
20203
 
+   THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
20204
 
+   WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
20205
 
+
20206
 
+Intellectual Property
20207
 
+
20208
 
+   The IETF takes no position regarding the validity or scope of any
20209
 
+   Intellectual Property Rights or other rights that might be claimed to
20210
 
+   pertain to the implementation or use of the technology described in
20211
 
+   this document or the extent to which any license under such rights
20212
 
+   might or might not be available; nor does it represent that it has
20213
 
+   made any independent effort to identify any such rights.  Information
20214
 
+   on the procedures with respect to rights in RFC documents can be
20215
 
+   found in BCP 78 and BCP 79.
20216
 
+
20217
 
+   Copies of IPR disclosures made to the IETF Secretariat and any
20218
 
+   assurances of licenses to be made available, or the result of an
20219
 
+   attempt made to obtain a general license or permission for the use of
20220
 
+   such proprietary rights by implementers or users of this
20221
 
+   specification can be obtained from the IETF on-line IPR repository at
20222
 
+   http://www.ietf.org/ipr.
20223
 
+
20224
 
+   The IETF invites any interested party to bring to its attention any
20225
 
+   copyrights, patents or patent applications, or other proprietary
20226
 
+   rights that may cover technology that may be required to implement
20227
 
+   this standard.  Please address the information to the IETF at
20228
 
+   ietf-ipr@ietf.org.
20229
 
+
20230
 
+
20231
 
+
20232
 
+
20233
 
+
20234
 
+
20235
 
+
20236
 
+
20237
 
+
20238
 
+
20239
 
+
20240
 
+
20241
 
+Melnikov                    Standards Track                    [Page 12]
20242
 
+
20243
 
diff -urN dovecot-1.2.4/dovecot-libsieve/doc/rfc/mailto.rfc2368.txt dovecot-1.2.4.debian/dovecot-libsieve/doc/rfc/mailto.rfc2368.txt
20244
 
--- dovecot-1.2.4/dovecot-libsieve/doc/rfc/mailto.rfc2368.txt   1970-01-01 01:00:00.000000000 +0100
20245
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/doc/rfc/mailto.rfc2368.txt    2008-11-21 22:05:14.000000000 +0100
20246
 
@@ -0,0 +1,563 @@
20247
 
+
20248
 
+
20249
 
+
20250
 
+
20251
 
+
20252
 
+
20253
 
+Network Working Group                                       P. Hoffman
20254
 
+Request for Comments: 2368                    Internet Mail Consortium
20255
 
+Updates: 1738, 1808                                        L. Masinter
20256
 
+Category: Standards Track                            Xerox Corporation
20257
 
+                                                           J. Zawinski
20258
 
+                                               Netscape Communications
20259
 
+                                                             July 1998
20260
 
+
20261
 
+
20262
 
+                         The mailto URL scheme
20263
 
+
20264
 
+Status of this Memo
20265
 
+
20266
 
+   This document specifies an Internet standards track protocol for the
20267
 
+   Internet community, and requests discussion and suggestions for
20268
 
+   improvements.  Please refer to the current edition of the "Internet
20269
 
+   Official Protocol Standards" (STD 1) for the standardization state
20270
 
+   and status of this protocol.  Distribution of this memo is unlimited.
20271
 
+
20272
 
+Copyright Notice
20273
 
+
20274
 
+   Copyright (C) The Internet Society (1998).  All Rights Reserved.
20275
 
+
20276
 
+Abstract
20277
 
+
20278
 
+   This document defines the format of Uniform Resource Locators (URL)
20279
 
+   for designating electronic mail addresses. It is one of a suite of
20280
 
+   documents which replace RFC 1738, 'Uniform Resource Locators', and
20281
 
+   RFC 1808, 'Relative Uniform Resource Locators'. The syntax of
20282
 
+   'mailto' URLs from RFC 1738 is extended to allow creation of more RFC
20283
 
+   822 messages by allowing the URL to express additional header and
20284
 
+   body fields.
20285
 
+
20286
 
+1. Introduction
20287
 
+
20288
 
+   The mailto URL scheme is used to designate the Internet mailing
20289
 
+   address of an individual or service. In its simplest form, a mailto
20290
 
+   URL contains an Internet mail address.
20291
 
+
20292
 
+   For greater functionality, because interaction with some resources
20293
 
+   may require message headers or message bodies to be specified as well
20294
 
+   as the mail address, the mailto URL scheme is extended to allow
20295
 
+   setting mail header fields and the message body.
20296
 
+
20297
 
+2. Syntax of a mailto URL
20298
 
+
20299
 
+   Following the syntax conventions of RFC 1738 [RFC1738], a "mailto"
20300
 
+   URL has the form:
20301
 
+
20302
 
+
20303
 
+
20304
 
+Hoffman, et. al.            Standards Track                     [Page 1]
20305
 
+
20306
 
+RFC 2368                 The mailto URL scheme                 July 1998
20307
 
+
20308
 
+
20309
 
+     mailtoURL  =  "mailto:" [ to ] [ headers ]
20310
 
+     to         =  #mailbox
20311
 
+     headers    =  "?" header *( "&" header )
20312
 
+     header     =  hname "=" hvalue
20313
 
+     hname      =  *urlc
20314
 
+     hvalue     =  *urlc
20315
 
+
20316
 
+   "#mailbox" is as specified in RFC 822 [RFC822]. This means that it
20317
 
+   consists of zero or more comma-separated mail addresses, possibly
20318
 
+   including "phrase" and "comment" components. Note that all URL
20319
 
+   reserved characters in "to" must be encoded: in particular,
20320
 
+   parentheses, commas, and the percent sign ("%"), which commonly occur
20321
 
+   in the "mailbox" syntax.
20322
 
+
20323
 
+   "hname" and "hvalue" are encodings of an RFC 822 header name and
20324
 
+   value, respectively. As with "to", all URL reserved characters must
20325
 
+   be encoded.
20326
 
+
20327
 
+   The special hname "body" indicates that the associated hvalue is the
20328
 
+   body of the message. The "body" hname should contain the content for
20329
 
+   the first text/plain body part of the message. The mailto URL is
20330
 
+   primarily intended for generation of short text messages that are
20331
 
+   actually the content of automatic processing (such as "subscribe"
20332
 
+   messages for mailing lists), not general MIME bodies.
20333
 
+
20334
 
+   Within mailto URLs, the characters "?", "=", "&" are reserved.
20335
 
+
20336
 
+   Because the "&" (ampersand) character is reserved in HTML, any mailto
20337
 
+   URL which contains an ampersand must be spelled differently in HTML
20338
 
+   than in other contexts.  A mailto URL which appears in an HTML
20339
 
+   document must use "&amp;" instead of "&".
20340
 
+
20341
 
+   Also note that it is legal to specify both "to" and an "hname" whose
20342
 
+   value is "to". That is,
20343
 
+
20344
 
+     mailto:addr1%2C%20addr2
20345
 
+
20346
 
+     is equivalent to
20347
 
+
20348
 
+     mailto:?to=addr1%2C%20addr2
20349
 
+
20350
 
+     is equivalent to
20351
 
+
20352
 
+     mailto:addr1?to=addr2
20353
 
+
20354
 
+   8-bit characters in mailto URLs are forbidden. MIME encoded words (as
20355
 
+   defined in [RFC2047]) are permitted in header values, but not for any
20356
 
+   part of a "body" hname.
20357
 
+
20358
 
+
20359
 
+
20360
 
+Hoffman, et. al.            Standards Track                     [Page 2]
20361
 
+
20362
 
+RFC 2368                 The mailto URL scheme                 July 1998
20363
 
+
20364
 
+
20365
 
+3. Semantics and operations
20366
 
+
20367
 
+   A mailto URL designates an "internet resource", which is the mailbox
20368
 
+   specified in the address. When additional headers are supplied, the
20369
 
+   resource designated is the same address, but with an additional
20370
 
+   profile for accessing the resource. While there are Internet
20371
 
+   resources that can only be accessed via electronic mail, the mailto
20372
 
+   URL is not intended as a way of retrieving such objects
20373
 
+   automatically.
20374
 
+
20375
 
+   In current practice, resolving URLs such as those in the "http"
20376
 
+   scheme causes an immediate interaction between client software and a
20377
 
+   host running an interactive server. The "mailto" URL has unusual
20378
 
+   semantics because resolving such a URL does not cause an immediate
20379
 
+   interaction. Instead, the client creates a message to the designated
20380
 
+   address with the various header fields set as default. The user can
20381
 
+   edit the message, send this message unedited, or choose not to send
20382
 
+   the message. The operation of how any URL scheme is resolved is not
20383
 
+   mandated by the URL specifications.
20384
 
+
20385
 
+4. Unsafe headers
20386
 
+
20387
 
+   The user agent interpreting a mailto URL SHOULD choose not to create
20388
 
+   a message if any of the headers are considered dangerous; it may also
20389
 
+   choose to create a message with only a subset of the headers given in
20390
 
+   the URL.  Only the Subject, Keywords, and Body headers are believed
20391
 
+   to be both safe and useful.
20392
 
+
20393
 
+   The creator of a mailto URL cannot expect the resolver of a URL to
20394
 
+   understand more than the "subject" and "body" headers. Clients that
20395
 
+   resolve mailto URLs into mail messages should be able to correctly
20396
 
+   create RFC 822-compliant mail messages using the "subject" and "body"
20397
 
+   headers.
20398
 
+
20399
 
+5. Encoding
20400
 
+
20401
 
+   RFC 1738 requires that many characters in URLs be encoded. This
20402
 
+   affects the mailto scheme for some common characters that might
20403
 
+   appear in addresses, headers or message contents. One such character
20404
 
+   is space (" ", ASCII hex 20). Note the examples above that use "%20"
20405
 
+   for space in the message body.  Also note that line breaks in the
20406
 
+   body of a message MUST be encoded with "%0D%0A".
20407
 
+
20408
 
+   People creating mailto URLs must be careful to encode any reserved
20409
 
+   characters that are used in the URLs so that properly-written URL
20410
 
+   interpreters can read them. Also, client software that reads URLs
20411
 
+   must be careful to decode strings before creating the mail message so
20412
 
+
20413
 
+
20414
 
+
20415
 
+
20416
 
+Hoffman, et. al.            Standards Track                     [Page 3]
20417
 
+
20418
 
+RFC 2368                 The mailto URL scheme                 July 1998
20419
 
+
20420
 
+
20421
 
+   that the mail messages appear in a form that the recipient will
20422
 
+   understand. These strings should be decoded before showing the user
20423
 
+   the message.
20424
 
+
20425
 
+   The mailto URL scheme is limited in that it does not provide for
20426
 
+   substitution of variables. Thus, a message body that must include a
20427
 
+   user's email address can not be encoded using the mailto URL. This
20428
 
+   limitation also prevents mailto URLs that are signed with public keys
20429
 
+   and other such variable information.
20430
 
+
20431
 
+6. Examples
20432
 
+
20433
 
+   URLs for an ordinary individual mailing address:
20434
 
+
20435
 
+     <mailto:chris@example.com>
20436
 
+
20437
 
+   A URL for a mail response system that requires the name of the file
20438
 
+   in the subject:
20439
 
+
20440
 
+     <mailto:infobot@example.com?subject=current-issue>
20441
 
+
20442
 
+   A mail response system that requires a "send" request in the body:
20443
 
+
20444
 
+     <mailto:infobot@example.com?body=send%20current-issue>
20445
 
+
20446
 
+   A similar URL could have two lines with different "send" requests (in
20447
 
+   this case, "send current-issue" and, on the next line, "send index".)
20448
 
+
20449
 
+     <mailto:infobot@example.com?body=send%20current-
20450
 
+     issue%0D%0Asend%20index>
20451
 
+
20452
 
+   An interesting use of your mailto URL is when browsing archives of
20453
 
+   messages. Each browsed message might contain a mailto URL like:
20454
 
+
20455
 
+     <mailto:foobar@example.com?In-Reply-
20456
 
+     To=%3c3469A91.D10AF4C@example.com>
20457
 
+
20458
 
+   A request to subscribe to a mailing list:
20459
 
+
20460
 
+     <mailto:majordomo@example.com?body=subscribe%20bamboo-l>
20461
 
+
20462
 
+   A URL for a single user which includes a CC of another user:
20463
 
+
20464
 
+     <mailto:joe@example.com?cc=bob@example.com&body=hello>
20465
 
+
20466
 
+   Another way of expressing the same thing:
20467
 
+
20468
 
+     <mailto:?to=joe@example.com&cc=bob@example.com&body=hello>
20469
 
+
20470
 
+
20471
 
+
20472
 
+Hoffman, et. al.            Standards Track                     [Page 4]
20473
 
+
20474
 
+RFC 2368                 The mailto URL scheme                 July 1998
20475
 
+
20476
 
+
20477
 
+   Note the use of the "&" reserved character, above. The following
20478
 
+   example, by using "?" twice, is incorrect:
20479
 
+
20480
 
+     <mailto:joe@example.com?cc=bob@example.com?body=hello>   ; WRONG!
20481
 
+
20482
 
+   According to RFC 822, the characters "?", "&", and even "%" may occur
20483
 
+   in addr-specs. The fact that they are reserved characters in this URL
20484
 
+   scheme is not a problem: those characters may appear in mailto URLs,
20485
 
+   they just may not appear in unencoded form. The standard URL encoding
20486
 
+   mechanisms ("%" followed by a two-digit hex number) must be used in
20487
 
+   certain cases.
20488
 
+
20489
 
+   To indicate the address "gorby%kremvax@example.com" one would do:
20490
 
+
20491
 
+     <mailto:gorby%25kremvax@example.com>
20492
 
+
20493
 
+   To indicate the address "unlikely?address@example.com", and include
20494
 
+   another header, one would do:
20495
 
+
20496
 
+     <mailto:unlikely%3Faddress@example.com?blat=foop>
20497
 
+
20498
 
+   As described above, the "&" (ampersand) character is reserved in HTML
20499
 
+   and must be replacded with "&amp;". Thus, a complex URL that has
20500
 
+   internal ampersands might look like:
20501
 
+
20502
 
+     Click
20503
 
+     <a href="mailto:?to=joe@xyz.com&amp;cc=bob@xyz.com&amp;body=hello">
20504
 
+     mailto:?to=joe@xyz.com&amp;cc=bob@xyz.com&amp;body=hello</a> to
20505
 
+     send a greeting message to <i>Joe and Bob</i>.
20506
 
+
20507
 
+7. Security Considerations
20508
 
+
20509
 
+   The mailto scheme can be used to send a message from one user to
20510
 
+   another, and thus can introduce many security concerns. Mail messages
20511
 
+   can be logged at the originating site, the recipient site, and
20512
 
+   intermediary sites along the delivery path. If the messages are not
20513
 
+   encoded, they can also be read at any of those sites.
20514
 
+
20515
 
+   A mailto URL gives a template for a message that can be sent by mail
20516
 
+   client software. The contents of that template may be opaque or
20517
 
+   difficult to read by the user at the time of specifying the URL.
20518
 
+   Thus, a mail client should never send a message based on a mailto URL
20519
 
+   without first showing the user the full message that will be sent
20520
 
+   (including all headers that were specified by the mailto URL), fully
20521
 
+   decoded, and asking the user for approval to send the message as
20522
 
+   electronic mail. The mail client should also make it clear that the
20523
 
+   user is about to send an electronic mail message, since the user may
20524
 
+   not be aware that this is the result of a mailto URL.
20525
 
+
20526
 
+
20527
 
+
20528
 
+Hoffman, et. al.            Standards Track                     [Page 5]
20529
 
+
20530
 
+RFC 2368                 The mailto URL scheme                 July 1998
20531
 
+
20532
 
+
20533
 
+   A mail client should never send anything without complete disclosure
20534
 
+   to the user of what is will be sent; it should disclose not only the
20535
 
+   message destination, but also any headers. Unrecognized headers, or
20536
 
+   headers with values inconsistent with those the mail client would
20537
 
+   normally send should be especially suspect. MIME headers (MIME-
20538
 
+   Version, Content-*) are most likely inappropriate, as are those
20539
 
+   relating to routing (From, Bcc, Apparently-To, etc.)
20540
 
+
20541
 
+   Note that some headers are inherently unsafe to include in a message
20542
 
+   generated from a URL. For example, headers such as "From:", "Bcc:",
20543
 
+   and so on, should never be interpreted from a URL. In general, the
20544
 
+   fewer headers interpreted from the URL, the less likely it is that a
20545
 
+   sending agent will create an unsafe message.
20546
 
+
20547
 
+   Examples of problems with sending unapproved mail include:
20548
 
+
20549
 
+     * mail that breaks laws upon delivery, such as making illegal
20550
 
+       threats;
20551
 
+
20552
 
+     * mail that identifies the sender as someone interested in breaking
20553
 
+       laws;
20554
 
+
20555
 
+     * mail that identifies the sender to an unwanted third party;
20556
 
+
20557
 
+     * mail that causes a financial charge to be incurred on the sender;
20558
 
+
20559
 
+     * mail that causes an action on the recipient machine that causes
20560
 
+       damage that might be attributed to the sender.
20561
 
+
20562
 
+   Programs that interpret mailto URLs should ensure that the SMTP
20563
 
+   "From" address is set and correct.
20564
 
+
20565
 
+8. IANA Considerations
20566
 
+
20567
 
+   This document changes the definition of the mailto: URI scheme; any
20568
 
+   registry of URI schemes should refer to this document rather than its
20569
 
+   predecessor, RFC 1738.
20570
 
+
20571
 
+
20572
 
+
20573
 
+
20574
 
+
20575
 
+
20576
 
+
20577
 
+
20578
 
+
20579
 
+
20580
 
+
20581
 
+
20582
 
+
20583
 
+
20584
 
+Hoffman, et. al.            Standards Track                     [Page 6]
20585
 
+
20586
 
+RFC 2368                 The mailto URL scheme                 July 1998
20587
 
+
20588
 
+
20589
 
+9. References
20590
 
+
20591
 
+   [RFC822] Crocker, D., "Standard for the Format of ARPA Internet Text
20592
 
+            Messages", STD 11, RFC 822, August 1982.
20593
 
+
20594
 
+   [RFC1738] Berners-Lee, T., Masinter, L., and M. McCahill, Editors,
20595
 
+             "Uniform Resource Locators (URL)", RFC 1738, December 1994.
20596
 
+
20597
 
+   [RFC1808] Fielding, R., "Relative Uniform Resource Locators", RFC
20598
 
+             1808, June 1995.
20599
 
+
20600
 
+   [RFC2047] Moore, K., "MIME Part Three: Message Header Extensions for
20601
 
+             Non-ASCII Text", RFC 2047, November 1996.
20602
 
+
20603
 
+
20604
 
+
20605
 
+
20606
 
+
20607
 
+
20608
 
+
20609
 
+
20610
 
+
20611
 
+
20612
 
+
20613
 
+
20614
 
+
20615
 
+
20616
 
+
20617
 
+
20618
 
+
20619
 
+
20620
 
+
20621
 
+
20622
 
+
20623
 
+
20624
 
+
20625
 
+
20626
 
+
20627
 
+
20628
 
+
20629
 
+
20630
 
+
20631
 
+
20632
 
+
20633
 
+
20634
 
+
20635
 
+
20636
 
+
20637
 
+
20638
 
+
20639
 
+
20640
 
+Hoffman, et. al.            Standards Track                     [Page 7]
20641
 
+
20642
 
+RFC 2368                 The mailto URL scheme                 July 1998
20643
 
+
20644
 
+
20645
 
+A. Change from RFC 1738
20646
 
+
20647
 
+   RFC 1738 defined only a simple 'mailto' with no headers, just an
20648
 
+   addr-spec (not a full mailbox.)  However, required usage and
20649
 
+   implementation has led to the development of an extended syntax that
20650
 
+   included more header fields.
20651
 
+
20652
 
+B. Acknowledgments
20653
 
+
20654
 
+   This document was derived from RFC 1738 and RFC 1808 [RFC1808]; the
20655
 
+   acknowledgments from those specifications still applies.
20656
 
+
20657
 
+   The following people contributed to this memo or had and discussed
20658
 
+   similar ideas for mailto.
20659
 
+
20660
 
+   Harald Alvestrand
20661
 
+   Bryan Costales
20662
 
+   Steve Dorner
20663
 
+   Al Gilman
20664
 
+   Mark Joseph
20665
 
+   Laurence Lundblade
20666
 
+   Keith Moore
20667
 
+   Jacob Palme
20668
 
+   Michael Patton
20669
 
+
20670
 
+
20671
 
+
20672
 
+
20673
 
+
20674
 
+
20675
 
+
20676
 
+
20677
 
+
20678
 
+
20679
 
+
20680
 
+
20681
 
+
20682
 
+
20683
 
+
20684
 
+
20685
 
+
20686
 
+
20687
 
+
20688
 
+
20689
 
+
20690
 
+
20691
 
+
20692
 
+
20693
 
+
20694
 
+
20695
 
+
20696
 
+Hoffman, et. al.            Standards Track                     [Page 8]
20697
 
+
20698
 
+RFC 2368                 The mailto URL scheme                 July 1998
20699
 
+
20700
 
+
20701
 
+C. Author Contact Information
20702
 
+
20703
 
+   Paul E. Hoffman
20704
 
+   Internet Mail Consortium
20705
 
+   127 Segre Place
20706
 
+   Santa Cruz, CA  95060 USA
20707
 
+
20708
 
+   EMail: phoffman@imc.org
20709
 
+
20710
 
+
20711
 
+   Larry Masinter
20712
 
+   Xerox Corporation
20713
 
+   3333 Coyote Hill Road
20714
 
+   Palo Alto, CA 94304 USA
20715
 
+
20716
 
+   EMail: masinter@parc.xerox.com
20717
 
+
20718
 
+
20719
 
+   Jamie Zawinski
20720
 
+   Netscape Communications Corp.
20721
 
+   501 East Middlefield Road
20722
 
+   Mountain View, CA 94043 USA
20723
 
+
20724
 
+   EMail: jwz@netscape.com
20725
 
+
20726
 
+
20727
 
+
20728
 
+
20729
 
+
20730
 
+
20731
 
+
20732
 
+
20733
 
+
20734
 
+
20735
 
+
20736
 
+
20737
 
+
20738
 
+
20739
 
+
20740
 
+
20741
 
+
20742
 
+
20743
 
+
20744
 
+
20745
 
+
20746
 
+
20747
 
+
20748
 
+
20749
 
+
20750
 
+
20751
 
+
20752
 
+Hoffman, et. al.            Standards Track                     [Page 9]
20753
 
+
20754
 
+RFC 2368                 The mailto URL scheme                 July 1998
20755
 
+
20756
 
+
20757
 
+D.  Full Copyright Statement
20758
 
+
20759
 
+   Copyright (C) The Internet Society (1998).  All Rights Reserved.
20760
 
+
20761
 
+   This document and translations of it may be copied and furnished to
20762
 
+   others, and derivative works that comment on or otherwise explain it
20763
 
+   or assist in its implementation may be prepared, copied, published
20764
 
+   and distributed, in whole or in part, without restriction of any
20765
 
+   kind, provided that the above copyright notice and this paragraph are
20766
 
+   included on all such copies and derivative works.  However, this
20767
 
+   document itself may not be modified in any way, such as by removing
20768
 
+   the copyright notice or references to the Internet Society or other
20769
 
+   Internet organizations, except as needed for the purpose of
20770
 
+   developing Internet standards in which case the procedures for
20771
 
+   copyrights defined in the Internet Standards process must be
20772
 
+   followed, or as required to translate it into languages other than
20773
 
+   English.
20774
 
+
20775
 
+   The limited permissions granted above are perpetual and will not be
20776
 
+   revoked by the Internet Society or its successors or assigns.
20777
 
+
20778
 
+   This document and the information contained herein is provided on an
20779
 
+   "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
20780
 
+   TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
20781
 
+   BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
20782
 
+   HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
20783
 
+   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
20784
 
+
20785
 
+
20786
 
+
20787
 
+
20788
 
+
20789
 
+
20790
 
+
20791
 
+
20792
 
+
20793
 
+
20794
 
+
20795
 
+
20796
 
+
20797
 
+
20798
 
+
20799
 
+
20800
 
+
20801
 
+
20802
 
+
20803
 
+
20804
 
+
20805
 
+
20806
 
+
20807
 
+
20808
 
+Hoffman, et. al.            Standards Track                    [Page 10]
20809
 
+
20810
 
diff -urN dovecot-1.2.4/dovecot-libsieve/doc/rfc/notify-mailto.rfc5436.txt dovecot-1.2.4.debian/dovecot-libsieve/doc/rfc/notify-mailto.rfc5436.txt
20811
 
--- dovecot-1.2.4/dovecot-libsieve/doc/rfc/notify-mailto.rfc5436.txt    1970-01-01 01:00:00.000000000 +0100
20812
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/doc/rfc/notify-mailto.rfc5436.txt     2009-02-02 10:17:30.000000000 +0100
20813
 
@@ -0,0 +1,675 @@
20814
 
+
20815
 
+
20816
 
+
20817
 
+
20818
 
+
20819
 
+
20820
 
+Network Working Group                                           B. Leiba
20821
 
+Request for Comments: 5436               IBM T.J. Watson Research Center
20822
 
+Updates: 3834                                                  M. Haardt
20823
 
+Category: Standards Track                                freenet.de GmbH
20824
 
+                                                            January 2009
20825
 
+
20826
 
+
20827
 
+                  Sieve Notification Mechanism: mailto
20828
 
+
20829
 
+Status of This Memo
20830
 
+
20831
 
+   This document specifies an Internet standards track protocol for the
20832
 
+   Internet community, and requests discussion and suggestions for
20833
 
+   improvements.  Please refer to the current edition of the "Internet
20834
 
+   Official Protocol Standards" (STD 1) for the standardization state
20835
 
+   and status of this protocol.  Distribution of this memo is unlimited.
20836
 
+
20837
 
+Copyright Notice
20838
 
+
20839
 
+   Copyright (c) 2009 IETF Trust and the persons identified as the
20840
 
+   document authors.  All rights reserved.
20841
 
+
20842
 
+   This document is subject to BCP 78 and the IETF Trust's Legal
20843
 
+   Provisions Relating to IETF Documents (http://trustee.ietf.org/
20844
 
+   license-info) in effect on the date of publication of this document.
20845
 
+   Please review these documents carefully, as they describe your rights
20846
 
+   and restrictions with respect to this document.
20847
 
+
20848
 
+Abstract
20849
 
+
20850
 
+   This document describes a profile of the Sieve extension for
20851
 
+   notifications, to allow notifications to be sent by electronic mail.
20852
 
+
20853
 
+
20854
 
+
20855
 
+
20856
 
+
20857
 
+
20858
 
+
20859
 
+
20860
 
+
20861
 
+
20862
 
+
20863
 
+
20864
 
+
20865
 
+
20866
 
+
20867
 
+
20868
 
+
20869
 
+
20870
 
+
20871
 
+Leiba & Haardt              Standards Track                     [Page 1]
20872
 
+
20873
 
+RFC 5436          Sieve Notification Mechanism: mailto      January 2009
20874
 
+
20875
 
+
20876
 
+Table of Contents
20877
 
+
20878
 
+   1. Introduction ....................................................3
20879
 
+      1.1. Overview ...................................................3
20880
 
+      1.2. Conventions Used in This Document ..........................3
20881
 
+   2. Definition ......................................................3
20882
 
+      2.1. Notify Parameter "method" ..................................3
20883
 
+      2.2. Test notify_method_capability ..............................3
20884
 
+      2.3. Notify Tag ":from" .........................................3
20885
 
+      2.4. Notify Tag ":importance" ...................................4
20886
 
+      2.5. Notify Tag ":options" ......................................4
20887
 
+      2.6. Notify Tag ":message" ......................................4
20888
 
+      2.7. Other Definitions ..........................................4
20889
 
+           2.7.1. The Auto-Submitted Header Field .....................6
20890
 
+   3. Examples ........................................................7
20891
 
+   4. Internationalization Considerations .............................8
20892
 
+   5. Security Considerations .........................................9
20893
 
+   6. IANA Considerations ............................................10
20894
 
+      6.1. Registration of Notification Mechanism ....................10
20895
 
+      6.2. New Registry for Auto-Submitted Header Field Keywords .....10
20896
 
+      6.3. Initial Registration of Auto-Submitted Header
20897
 
+           Field Keywords ............................................11
20898
 
+   7. References .....................................................11
20899
 
+      7.1. Normative References ......................................11
20900
 
+      7.2. Informative References ....................................12
20901
 
+
20902
 
+
20903
 
+
20904
 
+
20905
 
+
20906
 
+
20907
 
+
20908
 
+
20909
 
+
20910
 
+
20911
 
+
20912
 
+
20913
 
+
20914
 
+
20915
 
+
20916
 
+
20917
 
+
20918
 
+
20919
 
+
20920
 
+
20921
 
+
20922
 
+
20923
 
+
20924
 
+
20925
 
+
20926
 
+
20927
 
+Leiba & Haardt              Standards Track                     [Page 2]
20928
 
+
20929
 
+RFC 5436          Sieve Notification Mechanism: mailto      January 2009
20930
 
+
20931
 
+
20932
 
+1.  Introduction
20933
 
+
20934
 
+1.1.  Overview
20935
 
+
20936
 
+   The [Notify] extension to the [Sieve] mail filtering language is a
20937
 
+   framework for providing notifications by employing URIs to specify
20938
 
+   the notification mechanism.  This document defines how [mailto] URIs
20939
 
+   are used to generate notifications by email.
20940
 
+
20941
 
+1.2.  Conventions Used in This Document
20942
 
+
20943
 
+   Conventions for notations are as in Section 1.1 of [Sieve], including
20944
 
+   the use of [Kwds].
20945
 
+
20946
 
+   The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
20947
 
+   "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
20948
 
+   document are to be interpreted as described in [Kwds].
20949
 
+
20950
 
+2.  Definition
20951
 
+
20952
 
+   The mailto mechanism results in the sending of a new email message (a
20953
 
+   "notification message") to notify a recipient about a "triggering
20954
 
+   message".
20955
 
+
20956
 
+2.1.  Notify Parameter "method"
20957
 
+
20958
 
+   The mailto notification mechanism uses standard mailto URIs as
20959
 
+   specified in [mailto]. mailto URIs may contain header fields
20960
 
+   consisting of a header name and value.  These header fields are
20961
 
+   called "URI headers" to distinguish them from "message headers".
20962
 
+
20963
 
+2.2.  Test notify_method_capability
20964
 
+
20965
 
+   The notify_method_capability test for "online" may return "yes" or
20966
 
+   "no" only if the Sieve processor can determine with certainty whether
20967
 
+   or not the recipients of the notification message are online and
20968
 
+   logged in.  Otherwise, the test returns "maybe" for this notification
20969
 
+   method.
20970
 
+
20971
 
+2.3.  Notify Tag ":from"
20972
 
+
20973
 
+   The ":from" tag overrides the default sender of the notification
20974
 
+   message.  "Sender", here, refers to the value used in the [RFC5322]
20975
 
+   "From" header.  Implementations MAY also use this value in the
20976
 
+   [RFC5321] "MAIL FROM" command (the "envelope sender"), or they may
20977
 
+   prefer to establish a mailbox that receives bounces from notification
20978
 
+   messages.
20979
 
+
20980
 
+
20981
 
+
20982
 
+
20983
 
+Leiba & Haardt              Standards Track                     [Page 3]
20984
 
+
20985
 
+RFC 5436          Sieve Notification Mechanism: mailto      January 2009
20986
 
+
20987
 
+
20988
 
+2.4.  Notify Tag ":importance"
20989
 
+
20990
 
+   The ":importance" tag has no special meaning for this notification
20991
 
+   mechanism, and this specification puts no restriction on its use.
20992
 
+   Implementations MAY use the value of ":importance" to set a priority
20993
 
+   or importance indication on the notification message (perhaps a
20994
 
+   visual indication, or perhaps making use of one of the non-standard
20995
 
+   but commonly used message headers).
20996
 
+
20997
 
+2.5.  Notify Tag ":options"
20998
 
+
20999
 
+   This tag is not used by the mailto method.
21000
 
+
21001
 
+2.6.  Notify Tag ":message"
21002
 
+
21003
 
+   The value of this tag, if it is present, is used as the subject of
21004
 
+   the notification message, and overrides all other mechanisms for
21005
 
+   determining the subject (as described below).  Its value SHOULD NOT
21006
 
+   normally be truncated, though it may be sensible to truncate an
21007
 
+   excessively long value.
21008
 
+
21009
 
+2.7.  Other Definitions
21010
 
+
21011
 
+   Because the receipt of an email message is generating another email
21012
 
+   message, implementations MUST take steps to avoid mail loops.  The
21013
 
+   REQUIRED inclusion of an "Auto-Submitted:" field, as described in the
21014
 
+   message composition guidelines, will also help in loop detection and
21015
 
+   avoidance.
21016
 
+
21017
 
+   Implementations SHOULD NOT trigger notifications for messages
21018
 
+   containing "Auto-Submitted:" header fields with any value other than
21019
 
+   "No".
21020
 
+
21021
 
+   Implementations MUST allow messages with empty envelope senders to
21022
 
+   trigger notifications.
21023
 
+
21024
 
+   Because this notification method uses a store-and-forward system for
21025
 
+   delivery of the notification message, the Sieve processor should not
21026
 
+   have a need to retry notifications.  Therefore, implementations of
21027
 
+   this method SHOULD use normal mechanisms for submitting SMTP messages
21028
 
+   and for retrying the initial submission.  Once the notification
21029
 
+   message is submitted, implementations MUST NOT resubmit it, as this
21030
 
+   is likely to result in multiple notifications, and increases the
21031
 
+   danger of message loops.
21032
 
+
21033
 
+   Implementations SHOULD consider limiting notification messages.  In
21034
 
+   particular, they SHOULD NOT sent duplicate notifications to the same
21035
 
+   address from the same script invocation.  Batching of notifications
21036
 
+
21037
 
+
21038
 
+
21039
 
+Leiba & Haardt              Standards Track                     [Page 4]
21040
 
+
21041
 
+RFC 5436          Sieve Notification Mechanism: mailto      January 2009
21042
 
+
21043
 
+
21044
 
+   within a short time to the same address might also be useful.
21045
 
+   Different implementations, different administrative domains, and
21046
 
+   different users may have different needs; configuration options are a
21047
 
+   good idea here.
21048
 
+
21049
 
+   The overall notification message is composed using the following
21050
 
+   guidelines (see [RFC5322] for references to message header fields):
21051
 
+
21052
 
+   o  If the envelope sender of the triggering message is empty, the
21053
 
+      envelope sender of the notification message MUST be empty as well,
21054
 
+      to avoid message loops.  Otherwise, the envelope sender of the
21055
 
+      notification message SHOULD be set to the value of the ":from" tag
21056
 
+      to the notify action, if one is specified, has email address
21057
 
+      syntax, and is valid according to the implementation-specific
21058
 
+      security checks (see Section 3.3 of [Notify]).  If ":from" is not
21059
 
+      specified or is not valid, the envelope sender of the notification
21060
 
+      message SHOULD be set either to the envelope "to" field from the
21061
 
+      triggering message, as used by Sieve, or to an email address
21062
 
+      associated with the notification system, at the discretion of the
21063
 
+      implementation.  This MUST NOT be overridden by a "from" URI
21064
 
+      header, and any such URI header MUST be ignored.
21065
 
+
21066
 
+   o  The envelope recipient(s) of the notification message SHOULD be
21067
 
+      set to the address(es) specified in the URI (including any URI
21068
 
+      headers where the hname is "to" or "cc").
21069
 
+
21070
 
+   o  The header field "Auto-Submitted: auto-notified" MUST be included
21071
 
+      in the notification message (see Section 2.7.1).  This is to
21072
 
+      reduce the likelihood of message loops, by tagging this as an
21073
 
+      automatically generated message.  Among other results, it will
21074
 
+      inform other notification systems not to generate further
21075
 
+      notifications. mailto URI headers with hname "auto-submitted" are
21076
 
+      considered unsafe and MUST be ignored.
21077
 
+
21078
 
+   o  The "From:" header field of the notification message SHOULD be set
21079
 
+      to the value of the ":from" tag to the notify action, if one is
21080
 
+      specified, has email address syntax, and is valid according to the
21081
 
+      implementation-specific security checks (see Section 3.3 of
21082
 
+      [Notify]).  If ":from" is not specified or is not valid, the
21083
 
+      "From:" header field of the notification message SHOULD be set
21084
 
+      either to the envelope "to" field from the triggering message, as
21085
 
+      used by Sieve, or to an email address associated with the
21086
 
+      notification system, at the discretion of the implementation.
21087
 
+      This MUST NOT be overridden by a "from" URI header, and any such
21088
 
+      URI header MUST be ignored.
21089
 
+
21090
 
+
21091
 
+
21092
 
+
21093
 
+
21094
 
+
21095
 
+Leiba & Haardt              Standards Track                     [Page 5]
21096
 
+
21097
 
+RFC 5436          Sieve Notification Mechanism: mailto      January 2009
21098
 
+
21099
 
+
21100
 
+   o  The "To:" header field of the notification message SHOULD be set
21101
 
+      to the address(es) specified in the URI (including any URI headers
21102
 
+      where the hname is "to").
21103
 
+
21104
 
+   o  The "Subject:" field of the notification message SHOULD contain
21105
 
+      the value defined by the ":message" tag, as described in [Notify].
21106
 
+      If there is no ":message" tag and there is a "subject" header on
21107
 
+      the URI, then that value SHOULD be used.  If the "subject" header
21108
 
+      is also absent, the subject SHOULD be retained from the triggering
21109
 
+      message.  Note that Sieve [Variables] can be used to advantage
21110
 
+      here, as shown in the example in Section 3.
21111
 
+
21112
 
+   o  The "References:" field of the notification message MAY be set to
21113
 
+      refer to the triggering message, and MAY include references from
21114
 
+      the triggering message.
21115
 
+
21116
 
+   o  If the mailto URI contains a "body" header, the value of that
21117
 
+      header SHOULD be used as the body of the notification message.  If
21118
 
+      there is no "body" header, it is up to the implementation whether
21119
 
+      to leave the body empty or to use an excerpt of the original
21120
 
+      message.
21121
 
+
21122
 
+   o  The "Received:" fields from the triggering message MAY be retained
21123
 
+      in the notification message, as these could provide useful trace/
21124
 
+      history/diagnostic information.  The "Auto-Submitted" header field
21125
 
+      MUST be placed above these (see Section 2.7.1).  URI headers with
21126
 
+      hname "received" are considered unsafe, and MUST be ignored.
21127
 
+
21128
 
+   o  Other header fields of the notification message that are normally
21129
 
+      related to an individual new message (such as "Message-ID" and
21130
 
+      "Date") are generated for the notification message in the normal
21131
 
+      manner, and MUST NOT be copied from the triggering message.  Any
21132
 
+      URI headers with those names MUST be ignored.  Further, the "Date"
21133
 
+      header serves as the notification timestamp defined in [Notify].
21134
 
+
21135
 
+   o  All other header fields of the notification message either are as
21136
 
+      specified by URI headers, or have implementation-specific values;
21137
 
+      their values are not defined here.  It is suggested that the
21138
 
+      implementation capitalize the first letter of URI headers and add
21139
 
+      a space character after the colon between the mail header name and
21140
 
+      value when adding URI headers to the message, to be consistent
21141
 
+      with common practice in email headers.
21142
 
+
21143
 
+2.7.1.  The Auto-Submitted Header Field
21144
 
+
21145
 
+   The header field "Auto-Submitted: auto-notified" MUST be included in
21146
 
+   the notification message (see [RFC3834]).  The "Auto-Submitted"
21147
 
+   header field is considered a "trace field", similar to "Received"
21148
 
+
21149
 
+
21150
 
+
21151
 
+Leiba & Haardt              Standards Track                     [Page 6]
21152
 
+
21153
 
+RFC 5436          Sieve Notification Mechanism: mailto      January 2009
21154
 
+
21155
 
+
21156
 
+   header fields (see [RFC5321]).  If the implementation retains the
21157
 
+   "Received" fields from the triggering message (see above), the "Auto-
21158
 
+   Submitted" field MUST be placed above those "Received" fields,
21159
 
+   serving as a boundary between the ones from the triggering message
21160
 
+   and those that will be part of the notification message.
21161
 
+
21162
 
+   The header field "Auto-Submitted: auto-notified" MUST include one or
21163
 
+   both of the following parameters:
21164
 
+
21165
 
+   o  owner-email - specifies an email address, determined by the
21166
 
+      implementation, of the owner of the Sieve script that generated
21167
 
+      this notification.  If specified, it might be used to identify or
21168
 
+      contact the script's owner.  The parameter attribute is "owner-
21169
 
+      email", and the parameter value is a quoted string containing an
21170
 
+      email address, as defined by "addr-spec" in [RFC5322].  Example:
21171
 
+        Auto-Submitted: auto-notified; owner-email="me@example.com"
21172
 
+
21173
 
+   o  owner-token - specifies an opaque token, determined by the
21174
 
+      implementation, that the administrative domain of the owner of the
21175
 
+      Sieve script that generated this notification can use to identify
21176
 
+      the owner.  This might be used to allow identification of the
21177
 
+      owner while protecting the owner's privacy.  The parameter
21178
 
+      attribute is "owner-token", and the parameter value is as defined
21179
 
+      by "token" in [RFC3834].  Example:
21180
 
+        Auto-Submitted: auto-notified; owner-token=af3NN2pK5dDXI0W
21181
 
+
21182
 
+   See Section 5 for discussion of possible uses of these parameters.
21183
 
+
21184
 
+3.  Examples
21185
 
+
21186
 
+   Triggering message (received by recipient@example.org):
21187
 
+
21188
 
+      Return-Path: <knitting-bounces@example.com>
21189
 
+      Received: from mail.example.com by mail.example.org
21190
 
+        for <recipient@example.org>; Wed, 7 Dec 2005 05:08:02 -0500
21191
 
+      Received: from hobbies.example.com by mail.example.com
21192
 
+        for <knitting@example.com>; Wed, 7 Dec 2005 02:00:26 -0800
21193
 
+      Message-ID: <1234567.89ABCDEF@example.com>
21194
 
+      Date: Wed, 07 Dec 2005 10:59:19 +0100
21195
 
+      Precedence: list
21196
 
+      List-Id: Knitting Mailing List <knitting.example.com>
21197
 
+      Sender: knitting-bounces@example.com
21198
 
+      Errors-To: knitting-bounces@example.com
21199
 
+      From: "Jeff Smith" <jeff@hobbies.example.com>
21200
 
+      To: "Knitting Mailing List" <knitting@example.com>
21201
 
+      Subject: [Knitting] A new sweater
21202
 
+
21203
 
+      I just finished a great new sweater!
21204
 
+
21205
 
+
21206
 
+
21207
 
+Leiba & Haardt              Standards Track                     [Page 7]
21208
 
+
21209
 
+RFC 5436          Sieve Notification Mechanism: mailto      January 2009
21210
 
+
21211
 
+
21212
 
+   Sieve script (run on behalf of recipient@example.org):
21213
 
+
21214
 
+      require ["enotify", "variables"];
21215
 
+
21216
 
+      if header :contains "list-id" "knitting.example.com" {
21217
 
+        if header :matches "Subject" "[*] *" {
21218
 
+          notify :message "From ${1} list: ${2}"
21219
 
+              :importance "3"
21220
 
+              "mailto:0123456789@sms.example.net?to=backup@example.com";
21221
 
+        }
21222
 
+      }
21223
 
+
21224
 
+
21225
 
+   Notification message:
21226
 
+
21227
 
+      Auto-Submitted: auto-notified; owner-email="recipient@example.org"
21228
 
+      Received: from mail.example.com by mail.example.org
21229
 
+        for <recipient@example.org>; Wed, 7 Dec 2005 05:08:02 -0500
21230
 
+      Received: from hobbies.example.com by mail.example.com
21231
 
+        for <knitting@example.com>; Wed, 7 Dec 2005 02:00:26 -0800
21232
 
+      Date: Wed, 7 Dec 2005 05:08:55 -0500
21233
 
+      Message-ID: <A2299BB.FF7788@example.org>
21234
 
+      From: recipient@example.org
21235
 
+      To: 0123456789@sms.example.net, backup@example.com
21236
 
+      Subject: From Knitting list: A new sweater
21237
 
+
21238
 
+   Note that:
21239
 
+
21240
 
+   o  Fields such as "Message-ID:" and "Date:" were generated afresh for
21241
 
+      the notification message, and do not relate to the triggering
21242
 
+      message.
21243
 
+
21244
 
+   o  Additional "Received:" fields will be added to the notification
21245
 
+      message in transit; the ones shown were copied from the triggering
21246
 
+      message.  New ones will be added above the Auto-Submitted: header
21247
 
+      field.
21248
 
+
21249
 
+   o  If this message should appear at the mail.example.org server
21250
 
+      again, the server can use the presence of a "mail.example.org"
21251
 
+      received line to recognize that.  The Auto-Submitted header field
21252
 
+      is also present to tell the server to avoid sending another
21253
 
+      notification, and it includes an optional owner-email parameter
21254
 
+      for identification.
21255
 
+
21256
 
+4.  Internationalization Considerations
21257
 
+
21258
 
+   This specification introduces no specific internationalization issues
21259
 
+   that are not already addressed in [Sieve] and in [Notify].
21260
 
+
21261
 
+
21262
 
+
21263
 
+Leiba & Haardt              Standards Track                     [Page 8]
21264
 
+
21265
 
+RFC 5436          Sieve Notification Mechanism: mailto      January 2009
21266
 
+
21267
 
+
21268
 
+5.  Security Considerations
21269
 
+
21270
 
+   Sending a notification is comparable with forwarding mail to the
21271
 
+   notification recipient.  Care must be taken when forwarding mail
21272
 
+   automatically, to ensure that confidential information is not sent
21273
 
+   into an insecure environment.
21274
 
+
21275
 
+   The automated sending of email messages exposes the system to mail
21276
 
+   loops, which can cause operational problems.  Implementations of this
21277
 
+   specification MUST protect themselves against mail loops; see
21278
 
+   Section 2.7 for discussion of this and some suggestions.  Other
21279
 
+   possible mitigations for mail loops involve types of service
21280
 
+   limitations.  For example, the number of notifications generated for
21281
 
+   a single user might be limited to no more than, say, 30 in a
21282
 
+   60-minute period.  Of course, this technique presents its own
21283
 
+   problems, in that the actual rate-limit must be selected carefully,
21284
 
+   to allow most legitimate situations in the given environment.  Even
21285
 
+   with careful selection, it's inevitable that there will be false
21286
 
+   positives -- and false negatives.
21287
 
+
21288
 
+   Ultimately, human intervention may be necessary to re-enable
21289
 
+   notifications that have been disabled because a loop was detected, or
21290
 
+   to terminate a very slow loop that's under the automatic-detection
21291
 
+   radar.  Administrative mechanisms MUST be available to handle these
21292
 
+   sorts of situations.
21293
 
+
21294
 
+   Email addresses specified as recipients of notifications might not be
21295
 
+   owned by the entity that owns the Sieve script.  As a result, a
21296
 
+   notification recipient could wind up as the target of unwanted
21297
 
+   notifications, either through intent (using scripts to mount a mail-
21298
 
+   bomb attack) or by accident (an address was mistyped or has been
21299
 
+   reassigned).  The situation is arguably no worse than any other in
21300
 
+   which a recipient gets unwanted email, and some of the same
21301
 
+   mechanisms can be used in this case.  But those deploying this
21302
 
+   extension have to be aware of the potential extra problems here,
21303
 
+   where scripts might be created through means that do not adequately
21304
 
+   validate email addresses, and such scripts might then be forgotten
21305
 
+   and left to run indefinitely.
21306
 
+
21307
 
+   In particular, note that the Auto-Submitted header field is required
21308
 
+   to include a value that a recipient can use when contacting the
21309
 
+   source domain of the notification message (see Section 2.7.1).  That
21310
 
+   value will allow the domain to track down the script's owner and have
21311
 
+   the script corrected or disabled.  Domains that enable this extension
21312
 
+   MUST be prepared to respond to such complaints, in order to limit the
21313
 
+   damage caused by a faulty script.
21314
 
+
21315
 
+
21316
 
+
21317
 
+
21318
 
+
21319
 
+Leiba & Haardt              Standards Track                     [Page 9]
21320
 
+
21321
 
+RFC 5436          Sieve Notification Mechanism: mailto      January 2009
21322
 
+
21323
 
+
21324
 
+   Problems can also show up if notification messages are sent to a
21325
 
+   gateway into another service, such as SMS.  Information from the
21326
 
+   email message is often lost in the gateway translation; and in this
21327
 
+   case, critical information needed to avoid loops, to contact the
21328
 
+   script owner, and to resolve other problems might be lost.
21329
 
+   Developers of email gateways should consider these issues, and try to
21330
 
+   preserve as much information as possible, including what appears in
21331
 
+   email trace headers and the Auto-Submitted header field.
21332
 
+
21333
 
+   Additional security considerations are discussed in [Sieve] and in
21334
 
+   [Notify].
21335
 
+
21336
 
+6.  IANA Considerations
21337
 
+
21338
 
+6.1.  Registration of Notification Mechanism
21339
 
+
21340
 
+   The following template specifies the IANA registration of the Sieve
21341
 
+   notification mechanism specified in this document:
21342
 
+
21343
 
+   To: iana@iana.org
21344
 
+   Subject: Registration of new Sieve notification mechanism
21345
 
+   Mechanism name: mailto
21346
 
+   Mechanism URI: RFC2368
21347
 
+   Mechanism-specific options: none
21348
 
+   Permanent and readily available reference: RFC 5436
21349
 
+   Person and email address to contact for further information:
21350
 
+      Michael Haardt <michael.haardt@freenet.ag>
21351
 
+
21352
 
+   This information should be added to the list of Sieve notification
21353
 
+   mechanisms available from http://www.iana.org.
21354
 
+
21355
 
+6.2.  New Registry for Auto-Submitted Header Field Keywords
21356
 
+
21357
 
+   Because [RFC3834] does not define a registry for new keywords used in
21358
 
+   the Auto-Submitted header field, we define one here, which has been
21359
 
+   created and is available from http://www.iana.org.  Keywords are
21360
 
+   registered using the "Specification Required" policy [IANA].
21361
 
+
21362
 
+   This defines the template to be used to register new keywords.
21363
 
+   Initial entries to this registry follow in Section 6.3.
21364
 
+
21365
 
+   To: iana@iana.org
21366
 
+   Subject: Registration of new auto-submitted header field keyword
21367
 
+   Keyword value: [the text value of the field]
21368
 
+   Description: [a brief explanation of the purpose of this value]
21369
 
+   Parameters: [list any keyword-specific parameters, specify their
21370
 
+      meanings, specify whether they are required or optional; use
21371
 
+      "none" if there are none]
21372
 
+
21373
 
+
21374
 
+
21375
 
+Leiba & Haardt              Standards Track                    [Page 10]
21376
 
+
21377
 
+RFC 5436          Sieve Notification Mechanism: mailto      January 2009
21378
 
+
21379
 
+
21380
 
+   Permanent and readily available reference: [identifies
21381
 
+      the specification that defines the value being registered]
21382
 
+   Contact: [name and email address to contact for further information]
21383
 
+
21384
 
+6.3.  Initial Registration of Auto-Submitted Header Field Keywords
21385
 
+
21386
 
+   The following are the initial keywords that have been registered in
21387
 
+   the "Auto-Submitted Header Field Keywords" registry, available from
21388
 
+   http://www.iana.org.
21389
 
+
21390
 
+   Keyword value: no
21391
 
+   Description: Indicates that a message was NOT automatically
21392
 
+      generated, but was created by a human.  It is the equivalent to
21393
 
+      the absence of an Auto-Submitted header altogether.
21394
 
+   Parameters: none
21395
 
+   Permanent and readily available reference: RFC3834
21396
 
+   Contact: Keith Moore <moore@network-heretics.com>
21397
 
+
21398
 
+   Keyword value: auto-generated
21399
 
+   Description: Indicates that a message was generated by an automatic
21400
 
+      process, and is not a direct response to another message.
21401
 
+   Parameters: none
21402
 
+   Permanent and readily available reference: RFC3834
21403
 
+   Contact: Keith Moore <moore@network-heretics.com>
21404
 
+
21405
 
+   Keyword value: auto-replied
21406
 
+   Description: Indicates that a message was automatically generated as
21407
 
+      a direct response to another message.
21408
 
+   Parameters: none
21409
 
+   Permanent and readily available reference: RFC3834
21410
 
+   Contact: Keith Moore <moore@network-heretics.com>
21411
 
+
21412
 
+   Keyword value: auto-notified
21413
 
+   Description: Indicates that a message was generated by a Sieve
21414
 
+      notification system.
21415
 
+   Parameters: owner-email, owner-token.  At least one is required;
21416
 
+      both refer to the owner of the Sieve script that generated this
21417
 
+      message.  See the relevant RFC for details.
21418
 
+   Permanent and readily available reference: RFC 5436
21419
 
+   Contact: Michael Haardt <michael.haardt@freenet.ag>
21420
 
+
21421
 
+7.  References
21422
 
+
21423
 
+7.1.  Normative References
21424
 
+
21425
 
+   [IANA]       Narten, T. and H. Alvestrand, "Guidelines for Writing an
21426
 
+                IANA Considerations Section in RFCs", BCP 26, RFC 5226,
21427
 
+                May 2008.
21428
 
+
21429
 
+
21430
 
+
21431
 
+Leiba & Haardt              Standards Track                    [Page 11]
21432
 
+
21433
 
+RFC 5436          Sieve Notification Mechanism: mailto      January 2009
21434
 
+
21435
 
+
21436
 
+   [Kwds]       Bradner, S., "Key words for use in RFCs to Indicate
21437
 
+                Requirement Levels", BCP 14, RFC 2119, March 1997.
21438
 
+
21439
 
+   [Notify]     Melnikov, A., Ed., Leiba, B., Ed., Segmuller, W., and T.
21440
 
+                Martin, "Sieve Email Filtering: Extension for
21441
 
+                Notifications", RFC 5435, January 2009.
21442
 
+
21443
 
+   [RFC3834]    Moore, K., "Recommendations for Automatic Responses to
21444
 
+                Electronic Mail", RFC 3834, August 2004.
21445
 
+
21446
 
+   [RFC5322]    Resnick, P., Ed., "Internet Message Format", RFC 5322,
21447
 
+                October 2008.
21448
 
+
21449
 
+   [Sieve]      Guenther, P., Ed. and T. Showalter, Ed., "Sieve: An
21450
 
+                Email Filtering Language", RFC 5228, January 2008.
21451
 
+
21452
 
+   [mailto]     Hoffman, P., Masinter, L., and J. Zawinski, "The mailto
21453
 
+                URL scheme", RFC 2368, July 1998.
21454
 
+
21455
 
+7.2.  Informative References
21456
 
+
21457
 
+   [RFC5321]    Klensin, J., Ed., "Simple Mail Transfer Protocol",
21458
 
+                RFC 5321, October 2008.
21459
 
+
21460
 
+   [Variables]  Homme, K., "Sieve Extension: Variables", RFC 5229,
21461
 
+                January 2008.
21462
 
+
21463
 
+Authors' Addresses
21464
 
+
21465
 
+   Barry Leiba
21466
 
+   IBM T.J. Watson Research Center
21467
 
+   19 Skyline Drive
21468
 
+   Hawthorne, NY  10532
21469
 
+   US
21470
 
+
21471
 
+   Phone: +1 914 784 7941
21472
 
+   EMail: leiba@watson.ibm.com
21473
 
+
21474
 
+
21475
 
+   Michael Haardt
21476
 
+   freenet.de GmbH
21477
 
+   Willstaetter Str. 13
21478
 
+   Duesseldorf, NRW  40549
21479
 
+   Germany
21480
 
+
21481
 
+   Phone: +49 241 53087 520
21482
 
+   EMail: michael.haardt@freenet.ag
21483
 
+
21484
 
+
21485
 
+
21486
 
+
21487
 
+Leiba & Haardt              Standards Track                    [Page 12]
21488
 
+
21489
 
diff -urN dovecot-1.2.4/dovecot-libsieve/doc/rfc/notify.rfc5435.txt dovecot-1.2.4.debian/dovecot-libsieve/doc/rfc/notify.rfc5435.txt
21490
 
--- dovecot-1.2.4/dovecot-libsieve/doc/rfc/notify.rfc5435.txt   1970-01-01 01:00:00.000000000 +0100
21491
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/doc/rfc/notify.rfc5435.txt    2009-02-02 10:17:30.000000000 +0100
21492
 
@@ -0,0 +1,955 @@
21493
 
+
21494
 
+
21495
 
+
21496
 
+
21497
 
+
21498
 
+
21499
 
+Network Working Group                                   A. Melnikov, Ed.
21500
 
+Request for Comments: 5435                                 Isode Limited
21501
 
+Category: Standards Track                                  B. Leiba, Ed.
21502
 
+                                                            W. Segmuller
21503
 
+                                         IBM T.J. Watson Research Center
21504
 
+                                                               T. Martin
21505
 
+                                                       Endless Crossword
21506
 
+                                                            January 2009
21507
 
+
21508
 
+
21509
 
+           Sieve Email Filtering: Extension for Notifications
21510
 
+
21511
 
+Status of This Memo
21512
 
+
21513
 
+   This document specifies an Internet standards track protocol for the
21514
 
+   Internet community, and requests discussion and suggestions for
21515
 
+   improvements.  Please refer to the current edition of the "Internet
21516
 
+   Official Protocol Standards" (STD 1) for the standardization state
21517
 
+   and status of this protocol.  Distribution of this memo is unlimited.
21518
 
+
21519
 
+Copyright Notice
21520
 
+
21521
 
+   Copyright (c) 2009 IETF Trust and the persons identified as the
21522
 
+   document authors.  All rights reserved.
21523
 
+
21524
 
+   This document is subject to BCP 78 and the IETF Trust's Legal
21525
 
+   Provisions Relating to IETF Documents (http://trustee.ietf.org/
21526
 
+   license-info) in effect on the date of publication of this document.
21527
 
+   Please review these documents carefully, as they describe your rights
21528
 
+   and restrictions with respect to this document.
21529
 
+
21530
 
+Abstract
21531
 
+
21532
 
+   Users go to great lengths to be notified as quickly as possible that
21533
 
+   they have received new mail.  Most of these methods involve polling
21534
 
+   to check for new messages periodically.  A push method handled by the
21535
 
+   final delivery agent gives users quicker notifications and saves
21536
 
+   server resources.  This document does not specify the notification
21537
 
+   method, but it is expected that using existing instant messaging
21538
 
+   infrastructure such as Extensible Messaging and Presence Protocol
21539
 
+   (XMPP), or Global System for Mobile Communications (GSM) Short
21540
 
+   Message Service (SMS) messages will be popular.  This document
21541
 
+   describes an extension to the Sieve mail filtering language that
21542
 
+   allows users to give specific rules for how and when notifications
21543
 
+   should be sent.
21544
 
+
21545
 
+
21546
 
+
21547
 
+
21548
 
+
21549
 
+
21550
 
+Melnikov, et al.            Standards Track                     [Page 1]
21551
 
+
21552
 
+RFC 5435             Sieve Extension: Notifications         January 2009
21553
 
+
21554
 
+
21555
 
+Table of Contents
21556
 
+
21557
 
+   1. Introduction ....................................................3
21558
 
+      1.1. Conventions Used in This Document ..........................3
21559
 
+   2. Capability Identifier ...........................................3
21560
 
+   3. Notify Action ...................................................3
21561
 
+      3.1. Notify Action Syntax and Semantics .........................3
21562
 
+      3.2. Notify Parameter "method" ..................................3
21563
 
+      3.3. Notify Tag ":from" .........................................4
21564
 
+      3.4. Notify Tag ":importance" ...................................4
21565
 
+      3.5. Notify Tag ":options" ......................................5
21566
 
+      3.6. Notify Tag ":message" ......................................5
21567
 
+      3.7. Examples ...................................................6
21568
 
+      3.8. Requirements on Notification Methods Specifications ........7
21569
 
+   4. Test valid_notify_method ........................................8
21570
 
+   5. Test notify_method_capability ...................................9
21571
 
+   6. Modifier encodeurl to the 'set' Action .........................10
21572
 
+   7. Interactions with Other Sieve Actions ..........................11
21573
 
+   8. Security Considerations ........................................11
21574
 
+   9. IANA Considerations ............................................13
21575
 
+      9.1. Registration of Sieve Extension ...........................13
21576
 
+      9.2. New Registry for Sieve Notification Mechanisms ............14
21577
 
+      9.3. New Registry for Notification-Capability Parameters .......14
21578
 
+   10. Acknowledgements ..............................................15
21579
 
+   11. References ....................................................16
21580
 
+      11.1. Normative References .....................................16
21581
 
+      11.2. Informative References ...................................16
21582
 
+
21583
 
+
21584
 
+
21585
 
+
21586
 
+
21587
 
+
21588
 
+
21589
 
+
21590
 
+
21591
 
+
21592
 
+
21593
 
+
21594
 
+
21595
 
+
21596
 
+
21597
 
+
21598
 
+
21599
 
+
21600
 
+
21601
 
+
21602
 
+
21603
 
+
21604
 
+
21605
 
+
21606
 
+Melnikov, et al.            Standards Track                     [Page 2]
21607
 
+
21608
 
+RFC 5435             Sieve Extension: Notifications         January 2009
21609
 
+
21610
 
+
21611
 
+1.  Introduction
21612
 
+
21613
 
+   This is an extension to the Sieve language defined by [Sieve] for
21614
 
+   providing instant notifications.  It defines the new action "notify".
21615
 
+
21616
 
+   This document does not specify the notification methods.  Examples of
21617
 
+   possible notification methods are email and XMPP.  To allow for the
21618
 
+   portability of scripts that use notifications, implementation of the
21619
 
+   [MailTo] method is mandatory.  Other available methods shall depend
21620
 
+   upon the implementation and configuration of the system.
21621
 
+
21622
 
+1.1.  Conventions Used in This Document
21623
 
+
21624
 
+   Conventions for notations are as in [Sieve], Section 1.1, including
21625
 
+   the use of [ABNF].
21626
 
+
21627
 
+   The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
21628
 
+   "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
21629
 
+   document are to be interpreted as described in [Kwds].
21630
 
+
21631
 
+2.  Capability Identifier
21632
 
+
21633
 
+   The capability string associated with the extension defined in this
21634
 
+   document is "enotify".
21635
 
+
21636
 
+3.  Notify Action
21637
 
+
21638
 
+3.1.  Notify Action Syntax and Semantics
21639
 
+
21640
 
+   Usage:  notify [":from" string]
21641
 
+           [":importance" <"1" / "2" / "3">]
21642
 
+           [":options" string-list]
21643
 
+           [":message" string]
21644
 
+           <method: string>
21645
 
+
21646
 
+   The "notify" action specifies that a notification should be sent to a
21647
 
+   user.  The format of the notification is implementation-defined and
21648
 
+   is also affected by the notification method used (see Section 3.2).
21649
 
+   However, all content specified in the ":message" parameter SHOULD be
21650
 
+   included.
21651
 
+
21652
 
+3.2.  Notify Parameter "method"
21653
 
+
21654
 
+   The "method" positional parameter identifies the notification method
21655
 
+   that will be used; it is a URI [URI].  For example, the notification
21656
 
+   method can be a tel URI [TEL-URI] with a phone number to send SMS
21657
 
+   messages to, or an XMPP [XMPP] URI containing an XMPP identifier
21658
 
+   [XMPP-URI].
21659
 
+
21660
 
+
21661
 
+
21662
 
+Melnikov, et al.            Standards Track                     [Page 3]
21663
 
+
21664
 
+RFC 5435             Sieve Extension: Notifications         January 2009
21665
 
+
21666
 
+
21667
 
+   The supported URI values will be site-specific, but support for the
21668
 
+   [MailTo] method is REQUIRED in order to ensure interoperability.  If
21669
 
+   a URI schema is specified that the implementation does not support,
21670
 
+   the notification MUST cause an error condition at run time.  Sieve
21671
 
+   scripts can check the supported methods using the valid_notify_method
21672
 
+   test to be sure that they only use supported ones, to avoid such
21673
 
+   error conditions.
21674
 
+
21675
 
+   If the "method" parameter contains a supported URI schema, then the
21676
 
+   URI MUST be checked for syntactic validity.  Invalid URI syntax or an
21677
 
+   unsupported URI extension MUST cause an error.  An implementation MAY
21678
 
+   enforce other semantic restrictions on URIs -- for example, to
21679
 
+   restrict phone numbers in a tel: URI to a particular geographical
21680
 
+   region -- and will treat violations of such semantic restrictions as
21681
 
+   errors.
21682
 
+
21683
 
+3.3.  Notify Tag ":from"
21684
 
+
21685
 
+   A ":from" tag may be used to specify an author of the notification.
21686
 
+   The syntax of this parameter's value is method-specific.
21687
 
+   Implementations SHOULD check the syntax according to the notification
21688
 
+   method specification and generate an error when a syntactically
21689
 
+   invalid ":from" tag is specified.
21690
 
+
21691
 
+   In order to minimize/prevent forgery of the author value,
21692
 
+   implementations SHOULD impose restrictions on what values can be
21693
 
+   specified in a ":from" tag.  For example, an implementation may
21694
 
+   restrict this value to be a member of a list of known author
21695
 
+   addresses or to belong to a particular domain.  It is suggested that
21696
 
+   values that don't satisfy such restrictions simply be ignored rather
21697
 
+   than causing the "notify" action to fail.
21698
 
+
21699
 
+3.4.  Notify Tag ":importance"
21700
 
+
21701
 
+   The ":importance" tag specifies the importance of quick delivery of
21702
 
+   the notification, as perceived by the Sieve script owner.  The
21703
 
+   ":importance" tag is followed by a numeric value represented as a
21704
 
+   string: "1" (high importance), "2" (normal importance), and "3" (low
21705
 
+   importance).  If no importance is given, the default value "2" SHOULD
21706
 
+   be assumed.  A notification method MAY treat the importance value as
21707
 
+   a transport indicator.  For example, it might deliver notifications
21708
 
+   of high importance quicker than notifications of normal or low
21709
 
+   importance.  Some notification methods allow users to specify their
21710
 
+   state of activity (for example, "busy" or "away from keyboard").  If
21711
 
+   the notification method provides this information, it SHOULD be used
21712
 
+   to selectively send notifications.  If, for example, the user marks
21713
 
+
21714
 
+
21715
 
+
21716
 
+
21717
 
+
21718
 
+Melnikov, et al.            Standards Track                     [Page 4]
21719
 
+
21720
 
+RFC 5435             Sieve Extension: Notifications         January 2009
21721
 
+
21722
 
+
21723
 
+   herself as "busy", a notification method can require that a
21724
 
+   notification with importance of "3" is not to be sent; however, the
21725
 
+   user might be notified of a notification with higher importance.
21726
 
+
21727
 
+   If the notification method allows users to filter messages based upon
21728
 
+   certain parameters in the message, users SHOULD be able to filter
21729
 
+   based upon importance.  If the notification method does not support
21730
 
+   importance, then this parameter MUST be ignored.  An implementation
21731
 
+   MAY include the importance value in the default message, Section 3.6,
21732
 
+   if one is not provided.
21733
 
+
21734
 
+3.5.  Notify Tag ":options"
21735
 
+
21736
 
+   The ":options" tag is used to send additional parameters to the
21737
 
+   notification method.  Interpretation of the parameters is method-
21738
 
+   specific.  This document doesn't specify any such additional
21739
 
+   parameter.
21740
 
+
21741
 
+   Each string in the options string list has the following syntax:
21742
 
+   "<optionname>=<value>"
21743
 
+   where optionname has the following ABNF [ABNF]:
21744
 
+
21745
 
+
21746
 
+      l-d = ALPHA / DIGIT
21747
 
+      l-d-p = l-d / "." / "-" / "_"
21748
 
+      optionname = l-d *l-d-p
21749
 
+      value = *(%x01-09 / %x0B-0C / %x0E-FF)
21750
 
+
21751
 
+3.6.  Notify Tag ":message"
21752
 
+
21753
 
+   The ":message" tag specifies the message data to be included in the
21754
 
+   notification.  The entirety of the string SHOULD be sent, but
21755
 
+   implementations MAY shorten the message for technical or aesthetic
21756
 
+   reasons.  If the ":message" parameter is absent, a default
21757
 
+   implementation-specific message is used.  Unless otherwise specified
21758
 
+   by a particular notification mechanism, an implementation default
21759
 
+   containing at least the value of the "From" header field and the
21760
 
+   value of the "Subject" header field is RECOMMENDED.
21761
 
+
21762
 
+   In order to construct more complex messages, the notify extension can
21763
 
+   be used together with the Sieve variables extension [Variables], as
21764
 
+   shown in the examples below.
21765
 
+
21766
 
+
21767
 
+
21768
 
+
21769
 
+
21770
 
+
21771
 
+
21772
 
+
21773
 
+
21774
 
+Melnikov, et al.            Standards Track                     [Page 5]
21775
 
+
21776
 
+RFC 5435             Sieve Extension: Notifications         January 2009
21777
 
+
21778
 
+
21779
 
+3.7.  Examples
21780
 
+
21781
 
+   Example 1:
21782
 
+       require ["enotify", "fileinto", "variables"];
21783
 
+
21784
 
+       if header :contains "from" "boss@example.org" {
21785
 
+           notify :importance "1"
21786
 
+               :message "This is probably very important"
21787
 
+                           "mailto:alm@example.com";
21788
 
+           # Don't send any further notifications
21789
 
+           stop;
21790
 
+       }
21791
 
+
21792
 
+       if header :contains "to" "sievemailinglist@example.org" {
21793
 
+           # :matches is used to get the value of the Subject header
21794
 
+           if header :matches "Subject" "*" {
21795
 
+               set "subject" "${1}";
21796
 
+           }
21797
 
+
21798
 
+           # :matches is used to get the value of the From header
21799
 
+           if header :matches "From" "*" {
21800
 
+               set "from" "${1}";
21801
 
+           }
21802
 
+
21803
 
+           notify :importance "3"
21804
 
+               :message "[SIEVE] ${from}: ${subject}"
21805
 
+               "mailto:alm@example.com";
21806
 
+           fileinto "INBOX.sieve";
21807
 
+       }
21808
 
+
21809
 
+   Example 2:
21810
 
+       require ["enotify", "fileinto", "variables", "envelope"];
21811
 
+
21812
 
+       if header :matches "from" "*@*.example.org" {
21813
 
+           # :matches is used to get the MAIL FROM address
21814
 
+           if envelope :all :matches "from" "*" {
21815
 
+               set "env_from" " [really: ${1}]";
21816
 
+           }
21817
 
+
21818
 
+           # :matches is used to get the value of the Subject header
21819
 
+           if header :matches "Subject" "*" {
21820
 
+               set "subject" "${1}";
21821
 
+           }
21822
 
+
21823
 
+           # :matches is used to get the address from the From header
21824
 
+           if address :matches :all "from" "*" {
21825
 
+               set "from_addr" "${1}";
21826
 
+           }
21827
 
+
21828
 
+
21829
 
+
21830
 
+Melnikov, et al.            Standards Track                     [Page 6]
21831
 
+
21832
 
+RFC 5435             Sieve Extension: Notifications         January 2009
21833
 
+
21834
 
+
21835
 
+           notify :message "${from_addr}${env_from}: ${subject}"
21836
 
+                           "mailto:alm@example.com";
21837
 
+       }
21838
 
+
21839
 
+ Example 3:
21840
 
+     require ["enotify", "variables"];
21841
 
+
21842
 
+     set "notif_method"
21843
 
+     "xmpp:tim@example.com?message;subject=SIEVE;body=You%20got%20mail";
21844
 
+
21845
 
+     if header :contains "subject" "Your dog" {
21846
 
+         set "notif_method" "tel:+14085551212";
21847
 
+     }
21848
 
+
21849
 
+     if header :contains "to" "sievemailinglist@example.org" {
21850
 
+         set "notif_method" "";
21851
 
+     }
21852
 
+
21853
 
+     if not string :is "${notif_method}" "" {
21854
 
+         notify "${notif_method}";
21855
 
+     }
21856
 
+
21857
 
+     if header :contains "from" "boss@example.org" {
21858
 
+         # :matches is used to get the value of the Subject header
21859
 
+         if header :matches "Subject" "*" {
21860
 
+             set "subject" "${1}";
21861
 
+         }
21862
 
+
21863
 
+         # don't need high importance notification for
21864
 
+         # a 'for your information'
21865
 
+         if not header :contains "subject" "FYI:" {
21866
 
+             notify :importance "1" :message "BOSS: ${subject}"
21867
 
+                                "tel:+14085551212";
21868
 
+         }
21869
 
+     }
21870
 
+
21871
 
+3.8.  Requirements on Notification Methods Specifications
21872
 
+
21873
 
+   This section describes requirements for documents that define
21874
 
+   specific Sieve notification methods.
21875
 
+
21876
 
+   Notification mechanisms MUST NOT add new Sieve tags to the "notify"
21877
 
+   action.
21878
 
+
21879
 
+   A notification method MAY allow modification of the final
21880
 
+   notification text -- for example, truncating it if it exceeds a
21881
 
+   length limit or modifying characters that can not be represented in
21882
 
+   the target character set.  Characters in the notification text that
21883
 
+
21884
 
+
21885
 
+
21886
 
+Melnikov, et al.            Standards Track                     [Page 7]
21887
 
+
21888
 
+RFC 5435             Sieve Extension: Notifications         January 2009
21889
 
+
21890
 
+
21891
 
+   can't be represented by the notification method SHOULD be replaced
21892
 
+   with a symbol indicating an unknown character.  Allowed modifications
21893
 
+   MUST be documented in the document describing the notification
21894
 
+   method.
21895
 
+
21896
 
+   A notification method MAY ignore parameters specified in the "notify"
21897
 
+   action.
21898
 
+
21899
 
+   A notification method MAY recommend the default message value to be
21900
 
+   used if the ":message" argument is not specified.
21901
 
+
21902
 
+   Notifications SHOULD include timestamps, if the notification method
21903
 
+   allows for their transmission outside of the textual message.
21904
 
+   Implementation methods that can only transmit timestamps in the
21905
 
+   textual message MAY include them in the textual message.
21906
 
+
21907
 
+   A notification MUST include means to identify/track its origin in
21908
 
+   order to allow a recipient to stop notifications or find out how to
21909
 
+   contact the sender.  This requirement is to help with tracking a
21910
 
+   misconfigured or abusive origin of notifications.
21911
 
+
21912
 
+   Methods SHOULD NOT include any other extraneous information not
21913
 
+   specified in parameters to the "notify" action.
21914
 
+
21915
 
+   Methods MUST specify which URI parameters (if any) must be ignored,
21916
 
+   which ones must be used in the resulting notification, and which ones
21917
 
+   must cause an error.
21918
 
+
21919
 
+   Methods MUST specify what values are returned by the
21920
 
+   notify_method_capability test, Section 5, in particular for the
21921
 
+   "online" notification-capability.
21922
 
+
21923
 
+   If there are errors sending the notification, the Sieve interpreter
21924
 
+   SHOULD ignore the notification and not retry indefinitely.  The Sieve
21925
 
+   interpreter MAY throttle notifications; if it does, a request to send
21926
 
+   a notification MAY be silently ignored.  Documents describing
21927
 
+   notification methods SHOULD describe how retries, throttling,
21928
 
+   duplicate suppression (if any), etc. are to be handled by
21929
 
+   implementations.
21930
 
+
21931
 
+4.  Test valid_notify_method
21932
 
+
21933
 
+   Usage:  valid_notify_method <notification-uris: string-list>
21934
 
+
21935
 
+   The valid_notify_method test is true if the notification methods
21936
 
+   listed in the notification-uris argument are supported and they are
21937
 
+   valid both syntactically (including URI parameters) and semantically
21938
 
+
21939
 
+
21940
 
+
21941
 
+
21942
 
+Melnikov, et al.            Standards Track                     [Page 8]
21943
 
+
21944
 
+RFC 5435             Sieve Extension: Notifications         January 2009
21945
 
+
21946
 
+
21947
 
+   (including implementation-specific semantic restrictions).  This test
21948
 
+   MUST perform exactly the same validation as would be performed on the
21949
 
+   "method" parameter to the "notify" action.
21950
 
+
21951
 
+   The test is true only if ALL of the listed notification methods are
21952
 
+   supported and valid.
21953
 
+
21954
 
+   Example 4 (partial):
21955
 
+             if not valid_notify_method ["mailto:",
21956
 
+                     "http://gw.example.net/notify?test"] {
21957
 
+                 stop;
21958
 
+             }
21959
 
+
21960
 
+5.  Test notify_method_capability
21961
 
+
21962
 
+   Usage:  notify_method_capability [COMPARATOR] [MATCH-TYPE]
21963
 
+           <notification-uri: string>
21964
 
+           <notification-capability: string>
21965
 
+           <key-list: string-list>
21966
 
+
21967
 
+   The notify_method_capability test retrieves the notification
21968
 
+   capability specified by the notification-capability string that is
21969
 
+   specific to the notification-uri and matches it to the values
21970
 
+   specified in the key-list.  The test succeeds if a match occurs.  The
21971
 
+   type of match defaults to ":is", and the default comparator is
21972
 
+   "i;ascii-casemap".
21973
 
+
21974
 
+   The notification-capability parameter is case insensitive.
21975
 
+
21976
 
+   The notify_method_capability test MUST fail unconditionally if the
21977
 
+   specified notification-uri is syntactically invalid (as determined by
21978
 
+   the valid_notify_method test, Section 4) or specifies an unsupported
21979
 
+   notification method.  However this MUST NOT cause an error.
21980
 
+
21981
 
+   The notify_method_capability test MUST fail unconditionally if the
21982
 
+   specified notification-capability item is not known to the Sieve
21983
 
+   interpreter.  A script MUST NOT fail with an error if the item does
21984
 
+   not exist.  This allows scripts to be written that handle nonexistent
21985
 
+   items gracefully.
21986
 
+
21987
 
+   This document defines a single notification-capability value
21988
 
+   "online", which is described below.  Additional notification-
21989
 
+   capability values may be defined by using the procedure defined in
21990
 
+   Section 9.3.
21991
 
+
21992
 
+   The "relational" extension [Relational] adds a match type called
21993
 
+   ":count".  The count of an notify_method_capability test is 0, if the
21994
 
+   returned information is the empty string, or 1.
21995
 
+
21996
 
+
21997
 
+
21998
 
+Melnikov, et al.            Standards Track                     [Page 9]
21999
 
+
22000
 
+RFC 5435             Sieve Extension: Notifications         January 2009
22001
 
+
22002
 
+
22003
 
+   For the "online" notification-capability, the
22004
 
+   notify_method_capability test can match one of the following key-list
22005
 
+   values:
22006
 
+
22007
 
+   o  "yes" - the entity identified by the notification-uri can receive
22008
 
+      a notify notification immediately.  Note that even after this
22009
 
+      value is returned, there is no guarantee that the entity would
22010
 
+      actually be able to receive any notification immediately or even
22011
 
+      receive it at all.  Transport errors, recipient policy, etc. can
22012
 
+      prevent that.
22013
 
+
22014
 
+   o  "no" - the entity identified by the notification-uri is not
22015
 
+      currently available to receive an immediate notification.
22016
 
+
22017
 
+   o  "maybe" - the Sieve interpreter can't determine if the entity
22018
 
+      identified by the notification-uri is online or not.
22019
 
+
22020
 
+   Example 5:
22021
 
+             require ["enotify"];
22022
 
+
22023
 
+             if notify_method_capability
22024
 
+                    "xmpp:tim@example.com?message;subject=SIEVE"
22025
 
+                    "Online"
22026
 
+                    "yes" {
22027
 
+                 notify :importance "1" :message "You got mail"
22028
 
+                      "xmpp:tim@example.com?message;subject=SIEVE";
22029
 
+             } else {
22030
 
+                 notify :message "You got mail" "tel:+14085551212";
22031
 
+             }
22032
 
+
22033
 
+6.  Modifier encodeurl to the 'set' Action
22034
 
+
22035
 
+   Usage:  ":encodeurl"
22036
 
+
22037
 
+   When the Sieve script specifies both "variables" [Variables] and
22038
 
+   "enotify" capabilities in the "require", a new "set" action modifier
22039
 
+   (see [Variables]) ":encodeurl" becomes available to Sieve scripts.
22040
 
+   This modifier performs percent-encoding of any octet in the string
22041
 
+   that doesn't belong to the "unreserved" set (see [URI]).  The
22042
 
+   percent-encoding procedure is described in [URI].
22043
 
+
22044
 
+   The ":encodeurl" modifier has precedence 15.
22045
 
+
22046
 
+
22047
 
+
22048
 
+
22049
 
+
22050
 
+
22051
 
+
22052
 
+
22053
 
+
22054
 
+Melnikov, et al.            Standards Track                    [Page 10]
22055
 
+
22056
 
+RFC 5435             Sieve Extension: Notifications         January 2009
22057
 
+
22058
 
+
22059
 
+   Example 6:
22060
 
+       require ["enotify", "variables"];
22061
 
+
22062
 
+       set :encodeurl "body_param" "Safe body&evil=evilbody";
22063
 
+
22064
 
+       notify "mailto:tim@example.com?body=${body_param}";
22065
 
+
22066
 
+7.  Interactions with Other Sieve Actions
22067
 
+
22068
 
+   The "notify" action is compatible with all other actions, and does
22069
 
+   not affect the operation of other actions.  In particular, the
22070
 
+   "notify" action MUST NOT cancel the implicit keep.
22071
 
+
22072
 
+   Multiple executed "notify" actions are allowed.  Specific
22073
 
+   notification methods MAY allow multiple notifications from the same
22074
 
+   script to be collapsed into one.
22075
 
+
22076
 
+8.  Security Considerations
22077
 
+
22078
 
+   Security considerations are discussed in [Sieve].  Additionally,
22079
 
+   implementations must be careful to follow the security considerations
22080
 
+   of the specific notification methods.
22081
 
+
22082
 
+   The "notify" action is potentially very dangerous.  The path the
22083
 
+   notification takes through the network may not be secure.  An error
22084
 
+   in the options string may cause the message to be transmitted to
22085
 
+   someone it was not intended for, or may expose information to
22086
 
+   eavesdroppers.
22087
 
+
22088
 
+   Just because a notification is received doesn't mean that it was sent
22089
 
+   by the Sieve implementation.  It might be possible to forge
22090
 
+   notifications or modify parts of valid notifications with some
22091
 
+   notification methods.
22092
 
+
22093
 
+   Forgery of the ":importance" value (for example, by unauthorized
22094
 
+   script modification) can potentially result in slowdown in
22095
 
+   notification delivery.
22096
 
+
22097
 
+   Note that some components of notifications should not be trusted.
22098
 
+   For example, the timestamp field can be easily forged or modified
22099
 
+   when some notification transports are used.  Even if the timestamp is
22100
 
+   believed to be correct by the sender and is not modified in transit,
22101
 
+   it might be misleading on the receiving system due to clock
22102
 
+   differences.
22103
 
+
22104
 
+
22105
 
+
22106
 
+
22107
 
+
22108
 
+
22109
 
+
22110
 
+Melnikov, et al.            Standards Track                    [Page 11]
22111
 
+
22112
 
+RFC 5435             Sieve Extension: Notifications         January 2009
22113
 
+
22114
 
+
22115
 
+   An organization may have a policy about the forwarding of classified
22116
 
+   information to unclassified networks.  Unless the policy is also
22117
 
+   enforced in the module responsible for the generating (or sending) of
22118
 
+   notifications, users can use the extension defined in this document
22119
 
+   to extract classified information and bypass the policy.
22120
 
+
22121
 
+   Notifications can result in loops and bounces.  Also, allowing a
22122
 
+   single script to notify multiple destinations can be used as a means
22123
 
+   of amplifying the number of messages in an attack.  Moreover, if loop
22124
 
+   detection is not properly implemented, it may be possible to set up
22125
 
+   exponentially growing notification loops.  Accordingly, Sieve
22126
 
+   notification methods:
22127
 
+
22128
 
+   1.  MUST provide mechanisms for avoiding notification loops.
22129
 
+
22130
 
+   2.  MUST provide the means for administrators to limit the ability of
22131
 
+       users to abuse notify.  In particular, it MUST be possible to
22132
 
+       limit the number of "notify" actions a script can perform.
22133
 
+       Additionally, if no use cases exist for using "notify" with
22134
 
+       multiple destinations, this limit SHOULD be set to 1.  Additional
22135
 
+       limits, such as the ability to restrict "notify" to local users,
22136
 
+       MAY also be implemented.
22137
 
+
22138
 
+   3.  MUST provide facilities to log the use of "notify" in order to
22139
 
+       facilitate tracking down abuse.
22140
 
+
22141
 
+   4.  MAY use script analysis to determine whether or not a given
22142
 
+       script can be executed safely.  While the Sieve language is
22143
 
+       sufficiently complex so that full analysis of all possible
22144
 
+       scripts is computationally infeasible, the majority of real-world
22145
 
+       scripts are amenable to analysis.  For example, an implementation
22146
 
+       might allow scripts that it has determined to be safe to run
22147
 
+       unhindered, block scripts that are potentially problematic, and
22148
 
+       subject unclassifiable scripts to additional auditing and
22149
 
+       logging.
22150
 
+
22151
 
+   Allowing "notify" action at all may not be appropriate in situations
22152
 
+   where Sieve scripts are associated with email accounts that are
22153
 
+   freely-available and/or not trackable to a human who can be held
22154
 
+   accountable for creating message bombs or other abuse.
22155
 
+
22156
 
+   Implementations that construct URIs internally from various notify
22157
 
+   parameters MUST make sure that all components of such URIs are
22158
 
+   properly percent-encoded (see [URI]).  In particular, this applies to
22159
 
+   values of the ":from" and ":message" tagged arguments and may apply
22160
 
+   to the ":options" values.
22161
 
+
22162
 
+
22163
 
+
22164
 
+
22165
 
+
22166
 
+Melnikov, et al.            Standards Track                    [Page 12]
22167
 
+
22168
 
+RFC 5435             Sieve Extension: Notifications         January 2009
22169
 
+
22170
 
+
22171
 
+   Header/envelope tests [Sieve], together with Sieve variables, can be
22172
 
+   used to extract the list of users to receive notifications from the
22173
 
+   incoming email message or its envelope.  This is potentially quite
22174
 
+   dangerous, as this can be used for denial-of-service attacks on
22175
 
+   recipients controlled by the message sender.  For this reason,
22176
 
+   implementations SHOULD NOT allow the use of variables containing
22177
 
+   values extracted from the email message in the "method" parameter to
22178
 
+   the "notify" action.  Note that violation of this SHOULD NOT may
22179
 
+   result in the creation of an open relay, i.e., any sender would be
22180
 
+   able to create specially crafted email messages that would result in
22181
 
+   notifications delivered to recipients under the control of the
22182
 
+   sender.  In the worst case, this might result in financial loss by
22183
 
+   the user controlling the Sieve script and/or by recipients of
22184
 
+   notifications (e.g., if a notification is an SMS message).
22185
 
+
22186
 
+   Note that the last SHOULD NOT is not a generic prohibition of use of
22187
 
+   variables in the "notify" action, as controlling the target of a
22188
 
+   notification by extracting it from user-owned data stores (such as
22189
 
+   user's Lightweight Directory Access Protocol (LDAP) entry) is
22190
 
+   considered to be useful.
22191
 
+
22192
 
+   It is imperative that whatever implementations use to store the user-
22193
 
+   defined filtering scripts protect them from unauthorized
22194
 
+   modification, to preserve the integrity of the mail system.  An
22195
 
+   attacker who can modify a script can cause mail to be discarded,
22196
 
+   rejected, or forwarded to an unauthorized recipient.  In addition,
22197
 
+   it's possible that Sieve scripts might expose private information,
22198
 
+   such as mailbox names or email addresses of favored (or disfavored)
22199
 
+   correspondents.  Because of that, scripts SHOULD also be protected
22200
 
+   from unauthorized retrieval.
22201
 
+
22202
 
+9.  IANA Considerations
22203
 
+
22204
 
+9.1.  Registration of Sieve Extension
22205
 
+
22206
 
+   To:  iana@iana.org
22207
 
+   Subject:  Registration of new Sieve extension
22208
 
+   Capability name:  enotify
22209
 
+   Description:  adds the "notify" action for notifying user about the
22210
 
+      received message.  It also provides two new tests:
22211
 
+         valid_notify_method checks notification URIs for validity;
22212
 
+         notify_method_capability can check recipients capabilities.
22213
 
+   RFC number:  this RFC
22214
 
+   Contact address:  The Sieve discussion list
22215
 
+      <ietf-mta-filters@imc.org>
22216
 
+
22217
 
+   This information has been added to the list of Sieve extensions
22218
 
+   available from http://www.iana.org/.
22219
 
+
22220
 
+
22221
 
+
22222
 
+Melnikov, et al.            Standards Track                    [Page 13]
22223
 
+
22224
 
+RFC 5435             Sieve Extension: Notifications         January 2009
22225
 
+
22226
 
+
22227
 
+9.2.  New Registry for Sieve Notification Mechanisms
22228
 
+
22229
 
+   IANA has created a new registry for Sieve notification mechanisms.
22230
 
+   This registry contains both vendor-controlled notification mechanism
22231
 
+   names (beginning with "vnd.") and IETF-controlled notification
22232
 
+   mechanism names.  Vendor-controlled notification mechanism names have
22233
 
+   the format as defined in the following paragraph and may be
22234
 
+   registered on a "First Come First Served" basis [IANA-GUIDELINES], by
22235
 
+   applying to IANA with the form specified later in this section.
22236
 
+   Registration of notification mechanisms that do not begin with "vnd."
22237
 
+   are registered using a "Specification Required" policy
22238
 
+   [IANA-GUIDELINES].
22239
 
+
22240
 
+   Vendor-controlled notification mechanism names MUST have the form
22241
 
+   "vnd.<vendor-name>.<mechanism-name>", where <vendor-name> is as
22242
 
+   specified in the Application Configuration Access Protocol (ACAP)
22243
 
+   Vendor Subtree registry [ACAP].
22244
 
+
22245
 
+   This defines the template for a new registry for Sieve notification
22246
 
+   mechanisms, which has been created and is available from
22247
 
+   http://www.iana.org/.  There are no initial entries for this
22248
 
+   registry.
22249
 
+
22250
 
+   To:  iana@iana.org
22251
 
+   Subject:  Registration of new Sieve notification mechanism
22252
 
+   Mechanism name:  [the name of the mechanism]
22253
 
+   Mechanism URI:  [the RFC number of the document that defines the URI
22254
 
+      used by this mechanism.  Different mechanisms MUST use different
22255
 
+      URI schema.]
22256
 
+   Mechanism-specific options:  [the names of any Sieve notify options
22257
 
+      (as used in the ":options" parameter) that are specific to this
22258
 
+      mechanism, or "none"]
22259
 
+   Permanent and readily available reference:  [the RFC number or an URL
22260
 
+      of the document that defines this notification mechanism]
22261
 
+   Person and email address to contact for further information:  [the
22262
 
+      name and email address of the technical contact for information
22263
 
+      about this mechanism]
22264
 
+
22265
 
+9.3.  New Registry for Notification-Capability Parameters
22266
 
+
22267
 
+   IANA has created a new registry for the notification-capability
22268
 
+   parameters of the notify_method_capability test.  This registry
22269
 
+   contains both vendor-controlled notification-capability values
22270
 
+   (beginning with "vnd.") and IETF-controlled notification-capability
22271
 
+   values.  Vendor-controlled notification-capability values have the
22272
 
+   format as defined in the following paragraph and may be registered on
22273
 
+   a "First Come First Served" basis [IANA-GUIDELINES], by applying to
22274
 
+   IANA with the form specified later in this section.  Registration of
22275
 
+
22276
 
+
22277
 
+
22278
 
+Melnikov, et al.            Standards Track                    [Page 14]
22279
 
+
22280
 
+RFC 5435             Sieve Extension: Notifications         January 2009
22281
 
+
22282
 
+
22283
 
+   notification-capability values that do not begin with "vnd." are
22284
 
+   registered using the "Specification Required" policy
22285
 
+   [IANA-GUIDELINES].
22286
 
+
22287
 
+   Vendor-controlled notification-capability values MUST have the form
22288
 
+   "vnd.<vendor-name>.<capability-name>", where <vendor-name> is as
22289
 
+   specified in the ACAP Vendor Subtree registry [ACAP].
22290
 
+
22291
 
+   The following template must be used for registering notification-
22292
 
+   capability parameters:
22293
 
+
22294
 
+   To:  iana@iana.org
22295
 
+   Subject:  Registration of a new notification-capability parameter
22296
 
+   Capability name:  [the name of the notification-capability]
22297
 
+   Description:  [an explanation of the purpose of the notification-
22298
 
+      capability]
22299
 
+   Syntax:  [formal definition of allowed values and their syntax]
22300
 
+   Permanent and readily available reference(s):  [the RFC number(s) or
22301
 
+      an URL of the document that defines this notification mechanism]
22302
 
+   Contact information:  [the name and email address of the technical
22303
 
+      contact for information about this mechanism]
22304
 
+
22305
 
+   Below is the registration form for the "online" notification-
22306
 
+   capability:
22307
 
+
22308
 
+   To:  iana@iana.org
22309
 
+   Subject:  Registration of a new notification-capability parameter
22310
 
+   Capability name:  online
22311
 
+   Description:  Returns whether the entity identified by the
22312
 
+      notification-uri parameter to the notify_method_capability test
22313
 
+      can receive a notify notification immediately.
22314
 
+   Syntax:  Can contain one of three values: "yes", "no", and, "maybe".
22315
 
+      Values MUST be in lowercase.
22316
 
+   Permanent and readily available reference(s):  This RFC
22317
 
+   Contact information:  The Sieve discussion list
22318
 
+      <ietf-mta-filters@imc.org>
22319
 
+
22320
 
+10.  Acknowledgements
22321
 
+
22322
 
+   Thanks to Larry Greenfield, Sarah Robeson, Tim Showalter, Cyrus
22323
 
+   Daboo, Nigel Swinson, Kjetil Torgrim Homme, Michael Haardt, Mark E.
22324
 
+   Mallett, Ned Freed, Lisa Dusseault, Dilyan Palauzov, Arnt
22325
 
+   Gulbrandsen, Peter Saint-Andre, Sean Turner, Cullen Jennings, and
22326
 
+   Pasi Eronen for help with this document.
22327
 
+
22328
 
+
22329
 
+
22330
 
+
22331
 
+
22332
 
+
22333
 
+
22334
 
+Melnikov, et al.            Standards Track                    [Page 15]
22335
 
+
22336
 
+RFC 5435             Sieve Extension: Notifications         January 2009
22337
 
+
22338
 
+
22339
 
+11.  References
22340
 
+
22341
 
+11.1.  Normative References
22342
 
+
22343
 
+   [ABNF]             Crocker, D., Ed. and P. Overell, "Augmented BNF
22344
 
+                      for Syntax Specifications: ABNF", STD 68,
22345
 
+                      RFC 5234, January 2008.
22346
 
+
22347
 
+   [Kwds]             Bradner, S., "Key words for use in RFCs to
22348
 
+                      Indicate Requirement Levels", BCP 14, RFC 2119,
22349
 
+                      March 1997.
22350
 
+
22351
 
+   [MailTo]           Leiba, B. and M. Haardt, "Sieve Notification
22352
 
+                      Mechanism: mailto", RFC 5436, January 2009.
22353
 
+
22354
 
+   [Relational]       Segmuller, W. and B. Leiba, "Sieve Extension:
22355
 
+                      Relational Tests", RFC 5231, January 2008.
22356
 
+
22357
 
+   [Sieve]            Guenther, P., Ed. and T. Showalter, Ed., "Sieve:
22358
 
+                      An Email Filtering Language", RFC 5228,
22359
 
+                      January 2008.
22360
 
+
22361
 
+   [URI]              Berners-Lee, T., Fielding, R., and L. Masinter,
22362
 
+                      "Uniform Resource Identifier (URI): Generic
22363
 
+                      Syntax", STD 66, RFC 3986, January 2005.
22364
 
+
22365
 
+   [Variables]        Homme, K., "Sieve Extension: Variables", RFC 5229,
22366
 
+                      January 2008.
22367
 
+
22368
 
+11.2.  Informative References
22369
 
+
22370
 
+   [ACAP]             Newman, C. and J. Myers, "ACAP -- Application
22371
 
+                      Configuration Access Protocol", RFC 2244,
22372
 
+                      November 1997.
22373
 
+
22374
 
+   [IANA-GUIDELINES]  Narten, T. and H. Alvestrand, "Guidelines for
22375
 
+                      Writing an IANA Considerations Section in RFCs",
22376
 
+                      BCP 26, RFC 5226, May 2008.
22377
 
+
22378
 
+   [TEL-URI]          Schulzrinne, H., "The tel URI for Telephone
22379
 
+                      Numbers", RFC 3966, December 2004.
22380
 
+
22381
 
+   [XMPP]             Saint-Andre, Ed., P., "Extensible Messaging and
22382
 
+                      Presence Protocol (XMPP): Core", RFC 3920,
22383
 
+                      October 2004.
22384
 
+
22385
 
+
22386
 
+
22387
 
+
22388
 
+
22389
 
+
22390
 
+Melnikov, et al.            Standards Track                    [Page 16]
22391
 
+
22392
 
+RFC 5435             Sieve Extension: Notifications         January 2009
22393
 
+
22394
 
+
22395
 
+   [XMPP-URI]         Saint-Andre, P., "Internationalized Resource
22396
 
+                      Identifiers (IRIs) and Uniform Resource
22397
 
+                      Identifiers (URIs) for the Extensible Messaging
22398
 
+                      and Presence Protocol (XMPP)", RFC 5122,
22399
 
+                      February 2008.
22400
 
+
22401
 
+Authors' Addresses
22402
 
+
22403
 
+   Alexey Melnikov (editor)
22404
 
+   Isode Limited
22405
 
+   5 Castle Business Village
22406
 
+   36 Station Road
22407
 
+   Hampton, Middlesex  TW12 2BX
22408
 
+   UK
22409
 
+
22410
 
+   EMail: Alexey.Melnikov@isode.com
22411
 
+
22412
 
+
22413
 
+   Barry Leiba (editor)
22414
 
+   IBM T.J. Watson Research Center
22415
 
+   19 Skyline Drive
22416
 
+   Hawthorne, NY  10532
22417
 
+   US
22418
 
+
22419
 
+   Phone: +1 914 784 7941
22420
 
+   EMail: leiba@watson.ibm.com
22421
 
+
22422
 
+
22423
 
+   Wolfgang Segmuller
22424
 
+   IBM T.J. Watson Research Center
22425
 
+   19 Skyline Drive
22426
 
+   Hawthorne, NY  10532
22427
 
+   US
22428
 
+
22429
 
+   Phone: +1 914 784 7408
22430
 
+   EMail: werewolf@us.ibm.com
22431
 
+
22432
 
+
22433
 
+   Tim Martin
22434
 
+   Endless Crossword
22435
 
+   672 Haight st.
22436
 
+   San Francisco, CA  94117
22437
 
+   US
22438
 
+
22439
 
+   Phone: +1 510 260-4175
22440
 
+   EMail: timmartin@alumni.cmu.edu
22441
 
+
22442
 
+
22443
 
+
22444
 
+
22445
 
+
22446
 
+Melnikov, et al.            Standards Track                    [Page 17]
22447
 
+
22448
 
diff -urN dovecot-1.2.4/dovecot-libsieve/doc/rfc/reject-ereject.rfc5429.txt dovecot-1.2.4.debian/dovecot-libsieve/doc/rfc/reject-ereject.rfc5429.txt
22449
 
--- dovecot-1.2.4/dovecot-libsieve/doc/rfc/reject-ereject.rfc5429.txt   1970-01-01 01:00:00.000000000 +0100
22450
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/doc/rfc/reject-ereject.rfc5429.txt    2009-07-20 23:30:49.000000000 +0200
22451
 
@@ -0,0 +1,787 @@
22452
 
+
22453
 
+
22454
 
+
22455
 
+
22456
 
+
22457
 
+
22458
 
+Network Working Group                                      A. Stone, Ed.
22459
 
+Request for Comments: 5429                                   Serendipity
22460
 
+Obsoletes: 3028                                               March 2009
22461
 
+Updates: 5228
22462
 
+Category: Standards Track
22463
 
+
22464
 
+
22465
 
+      Sieve Email Filtering: Reject and Extended Reject Extensions
22466
 
+
22467
 
+Status of This Memo
22468
 
+
22469
 
+   This document specifies an Internet standards track protocol for the
22470
 
+   Internet community, and requests discussion and suggestions for
22471
 
+   improvements.  Please refer to the current edition of the "Internet
22472
 
+   Official Protocol Standards" (STD 1) for the standardization state
22473
 
+   and status of this protocol.  Distribution of this memo is unlimited.
22474
 
+
22475
 
+Copyright Notice
22476
 
+
22477
 
+   Copyright (c) 2009 IETF Trust and the persons identified as the
22478
 
+   document authors.  All rights reserved.
22479
 
+
22480
 
+   This document is subject to BCP 78 and the IETF Trust's Legal
22481
 
+   Provisions Relating to IETF Documents in effect on the date of
22482
 
+   publication of this document (http://trustee.ietf.org/license-info).
22483
 
+   Please review these documents carefully, as they describe your rights
22484
 
+   and restrictions with respect to this document.
22485
 
+
22486
 
+   This document may contain material from IETF Documents or IETF
22487
 
+   Contributions published or made publicly available before November
22488
 
+   10, 2008.  The person(s) controlling the copyright in some of this
22489
 
+   material may not have granted the IETF Trust the right to allow
22490
 
+   modifications of such material outside the IETF Standards Process.
22491
 
+   Without obtaining an adequate license from the person(s) controlling
22492
 
+   the copyright in such materials, this document may not be modified
22493
 
+   outside the IETF Standards Process, and derivative works of it may
22494
 
+   not be created outside the IETF Standards Process, except to format
22495
 
+   it for publication as an RFC or to translate it into languages other
22496
 
+   than English.
22497
 
+
22498
 
+Abstract
22499
 
+
22500
 
+   This memo updates the definition of the Sieve mail filtering language
22501
 
+   "reject" extension, originally defined in RFC 3028.
22502
 
+
22503
 
+   A "Joe-job" is a spam run forged to appear as though it came from an
22504
 
+   innocent party, who is then generally flooded by automated bounces,
22505
 
+   Message Disposition Notifications (MDNs), and personal messages with
22506
 
+
22507
 
+
22508
 
+
22509
 
+Stone                       Standards Track                     [Page 1]
22510
 
+
22511
 
+RFC 5429                Sieve Extension: Reject               March 2009
22512
 
+
22513
 
+
22514
 
+   complaints.  The original Sieve "reject" action defined in RFC 3028
22515
 
+   required use of MDNs for rejecting messages, thus contributing to the
22516
 
+   flood of Joe-job spam to victims of Joe-jobs.
22517
 
+
22518
 
+   This memo updates the definition of the "reject" action to allow
22519
 
+   messages to be refused during the SMTP transaction, and defines the
22520
 
+   "ereject" action to require messages to be refused during the SMTP
22521
 
+   transaction, if possible.
22522
 
+
22523
 
+   The "ereject" action is intended to replace the "reject" action
22524
 
+   wherever possible.  The "ereject" action is similar to "reject", but
22525
 
+   will always favor protocol-level message rejection.
22526
 
+
22527
 
+Table of Contents
22528
 
+
22529
 
+   1.  Introduction . . . . . . . . . . . . . . . . . . . . . . . . .  3
22530
 
+     1.1.  Conventions Used in This Document  . . . . . . . . . . . .  3
22531
 
+   2.  Sieve "reject" and "ereject" Extensions  . . . . . . . . . . .  4
22532
 
+     2.1.  Action ereject . . . . . . . . . . . . . . . . . . . . . .  4
22533
 
+       2.1.1.  Rejecting a Message at the SMTP/LMTP Protocol Level  .  5
22534
 
+       2.1.2.  Rejecting a Message by Sending a DSN . . . . . . . . .  5
22535
 
+     2.2.  Action reject  . . . . . . . . . . . . . . . . . . . . . .  6
22536
 
+       2.2.1.  Rejecting a Message by Sending an MDN  . . . . . . . .  7
22537
 
+     2.3.  Silent Upgrade from "reject" to "ereject"  . . . . . . . .  8
22538
 
+     2.4.  Compatibility with Other Actions . . . . . . . . . . . . .  9
22539
 
+     2.5.  Details of Protocol-Level Refusal  . . . . . . . . . . . .  9
22540
 
+   3.  Changes from RFC 3028  . . . . . . . . . . . . . . . . . . . . 11
22541
 
+   4.  Security Considerations  . . . . . . . . . . . . . . . . . . . 11
22542
 
+   5.  IANA Considerations  . . . . . . . . . . . . . . . . . . . . . 11
22543
 
+     5.1.  "reject" Extension Registration  . . . . . . . . . . . . . 11
22544
 
+     5.2.  "ereject" Extension Registration . . . . . . . . . . . . . 12
22545
 
+   6.  References . . . . . . . . . . . . . . . . . . . . . . . . . . 12
22546
 
+     6.1.  Normative References . . . . . . . . . . . . . . . . . . . 12
22547
 
+     6.2.  Informative References . . . . . . . . . . . . . . . . . . 13
22548
 
+   Appendix A.  Acknowledgements  . . . . . . . . . . . . . . . . . . 14
22549
 
+   Appendix B.  Contributors  . . . . . . . . . . . . . . . . . . . . 14
22550
 
+
22551
 
+
22552
 
+
22553
 
+
22554
 
+
22555
 
+
22556
 
+
22557
 
+
22558
 
+
22559
 
+
22560
 
+
22561
 
+
22562
 
+
22563
 
+
22564
 
+
22565
 
+Stone                       Standards Track                     [Page 2]
22566
 
+
22567
 
+RFC 5429                Sieve Extension: Reject               March 2009
22568
 
+
22569
 
+
22570
 
+1.  Introduction
22571
 
+
22572
 
+   The Sieve mail filtering language, as originally defined in RFC 3028
22573
 
+   [RFC3028], specified that the "reject" action shall discard a message
22574
 
+   and send a Message Disposition Notification [MDN] to the envelope
22575
 
+   sender along with an explanatory message.  The Sieve mail filtering
22576
 
+   language, as updated in RFC 5228 [SIEVE], does not define any
22577
 
+   "reject" action, hence that is the purpose of this document.
22578
 
+
22579
 
+   This document updates the definition of the "reject" action to permit
22580
 
+   refusal of the message during the SMTP transaction, if possible, and
22581
 
+   defines a new "ereject" action to require refusal of the message
22582
 
+   during the SMTP transaction, if possible.
22583
 
+
22584
 
+   An important goal of this document is to reduce the risk of Sieve
22585
 
+   scripts being used to perpetrate "Joe-job" spam runs, where the MDN
22586
 
+   is sent notifying the sender of a message of its non-delivery is in
22587
 
+   fact sent to an innocent third-party.  The original Sieve "reject"
22588
 
+   action defined in RFC 3028 required use of MDNs for rejecting
22589
 
+   messages, thus contributing to the flood of Joe-job spam to victims
22590
 
+   of Joe-jobs.  By rejecting the message at the protocol level, it is
22591
 
+   less likely that an MDN will be needed, and thus less likely that an
22592
 
+   MDN will be misdirected at an innocent third-party.
22593
 
+
22594
 
+   Implementations are further encouraged to use spam-detection systems
22595
 
+   to determine the level of risk associated with sending an MDN, and
22596
 
+   this document allows implementations to silently drop the MDN if the
22597
 
+   rejected message is deemed likely to be spam.
22598
 
+
22599
 
+   This document also describes how to use "reject"/"ereject" at varying
22600
 
+   points in the email stack: Mail Transfer Agent (MTA), Mail Delivery
22601
 
+   Agent (MDA), and Mail User Agent (MUA).  See [EMAIL-ARCH] for a
22602
 
+   comprehensive discussion of these environments.
22603
 
+
22604
 
+   In general, an MDN is generated by an MUA, and can be used to
22605
 
+   indicate the status of a message with respect to its recipient, while
22606
 
+   a Delivery Status Notification (DSN) [DSN] is generated by an MTA,
22607
 
+   and can be used to indicate whether or not a message was received and
22608
 
+   delivered by the mail system.
22609
 
+
22610
 
+   Further discussion highlighting the risks of generating MDNs and the
22611
 
+   benefits of protocol-level refusal can be found in [Joe-DoS].
22612
 
+
22613
 
+1.1.  Conventions Used in This Document
22614
 
+
22615
 
+   The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
22616
 
+   "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
22617
 
+   document are to be interpreted as described in [KEYWORDS].
22618
 
+
22619
 
+
22620
 
+
22621
 
+Stone                       Standards Track                     [Page 3]
22622
 
+
22623
 
+RFC 5429                Sieve Extension: Reject               March 2009
22624
 
+
22625
 
+
22626
 
+   Conventions for notations are as in Section 1.1 of RFC 5228 [SIEVE].
22627
 
+
22628
 
+   This document does not attempt to define spam or how it should be
22629
 
+   identified, nor does it attempt to define an email virus or how it
22630
 
+   should be detected.  Implementors are advised to follow best
22631
 
+   practices and keep abreast of current research in these fields.
22632
 
+
22633
 
+2.  Sieve "reject" and "ereject" Extensions
22634
 
+
22635
 
+2.1.  Action ereject
22636
 
+
22637
 
+   Usage: ereject <reason: string>
22638
 
+
22639
 
+   Sieve implementations that implement the "ereject" action must use
22640
 
+   the "ereject" capability string.
22641
 
+
22642
 
+   The "ereject" action cancels the implicit keep and refuses delivery
22643
 
+   of a message.  The "reason" string is a UTF-8 [UTF-8] string
22644
 
+   specifying the reason for refusal.  How a message is refused depends
22645
 
+   on the capabilities of the mail component (MDA or MTA) executing the
22646
 
+   Sieve script.  The Sieve interpreter MUST carry out one of the
22647
 
+   following actions (listed in order from most to least preferred),
22648
 
+   MUST carry out the most preferable action possible, and MUST fall
22649
 
+   back to lesser actions if a preferred action fails.
22650
 
+
22651
 
+   1.  Refuse message delivery by sending a 5XX response code over SMTP
22652
 
+       [SMTP] or Local Mail Transfer Protocol (LMTP) [LMTP].  See
22653
 
+       Section 2.1.1 for more details.
22654
 
+
22655
 
+   2.  Send a non-delivery report to the envelope sender ([REPORT]
22656
 
+       [DSN]), unless the envelope sender address is determined to be a
22657
 
+       forged or otherwise invalid address.
22658
 
+
22659
 
+   Note that the determination of whether or not an envelope sender is a
22660
 
+   forgery may be performed by site-specific and implementation-specific
22661
 
+   heuristic techniques, such as "return-path verification", details of
22662
 
+   which are outside the scope of this document.  Implementations SHOULD
22663
 
+   log instances when a non-delivery report is not sent and the reason
22664
 
+   for not sending the report (e.g., content was spam, return-path
22665
 
+   invalid, etc.).
22666
 
+
22667
 
+   The "ereject" action MUST NOT be available in environments that do
22668
 
+   not support protocol-level rejection, e.g., an MUA, and MUST be
22669
 
+   available in all other environments that support the "reject" action.
22670
 
+
22671
 
+
22672
 
+
22673
 
+
22674
 
+
22675
 
+
22676
 
+
22677
 
+Stone                       Standards Track                     [Page 4]
22678
 
+
22679
 
+RFC 5429                Sieve Extension: Reject               March 2009
22680
 
+
22681
 
+
22682
 
+       Example:
22683
 
+               require ["ereject"];
22684
 
+
22685
 
+               if address "from" "someone@example.com" {
22686
 
+                   ereject "I no longer accept mail from this address";
22687
 
+               }
22688
 
+
22689
 
+2.1.1.  Rejecting a Message at the SMTP/LMTP Protocol Level
22690
 
+
22691
 
+   Sieve implementations that are able to reject messages at the SMTP/
22692
 
+   LMTP level MUST do so and SHOULD use the 550 response code.  Note
22693
 
+   that if a message is arriving over SMTP and has multiple recipients,
22694
 
+   some of whom have accepted the message, Section 2.1.2 defines how to
22695
 
+   reject such a message.
22696
 
+
22697
 
+   The risk that these actions will generate blowback spam are minimized
22698
 
+   but cannot be eliminated completely even in the case of "ereject", so
22699
 
+   caution is advised when using these actions to deal with messages
22700
 
+   determined to be spam.
22701
 
+
22702
 
+   Note that SMTP [SMTP] does not allow non-US-ACSII characters in the
22703
 
+   SMTP response text.  If non-US-ACSII characters appear in the
22704
 
+   "reason" string, they can be sent at the protocol level if and only
22705
 
+   if the client and the server use an SMTP extension that allows for
22706
 
+   transmission of non-US-ACSII reply text.  (One example of such an
22707
 
+   SMTP extension is described in [UTF8-RESP].)  In the absence of such
22708
 
+   an SMTP extension, the Sieve engine MUST replace any "reason" string
22709
 
+   being sent at the protocol level and containing non-US-ACSII
22710
 
+   characters with an implementation-defined US-ACSII-only string.
22711
 
+
22712
 
+   Users who don't like this behavior should consider using the "reject"
22713
 
+   action described in Section 2.2, if available.
22714
 
+
22715
 
+   See Section 2.5 for the detailed instructions about performing
22716
 
+   protocol-level rejection.
22717
 
+
22718
 
+2.1.2.  Rejecting a Message by Sending a DSN
22719
 
+
22720
 
+   An implementation may receive a message via SMTP that has more than
22721
 
+   one RCPT TO that has been accepted by the server, and at least one
22722
 
+   but not all of them are refusing delivery (whether the refusal is
22723
 
+   caused by a Sieve "ereject" action or for some other reason).  In
22724
 
+   this case, the server MUST accept the message and generate DSNs for
22725
 
+   all recipients that are refusing it.  Note that this exception does
22726
 
+   not apply to LMTP, as LMTP is able to reject messages on a per-
22727
 
+   recipient basis.  (However, the LMTP client may then have no choice
22728
 
+   but to generate a DSN to report the error, which may result in
22729
 
+   blowback spam.)
22730
 
+
22731
 
+
22732
 
+
22733
 
+Stone                       Standards Track                     [Page 5]
22734
 
+
22735
 
+RFC 5429                Sieve Extension: Reject               March 2009
22736
 
+
22737
 
+
22738
 
+   Note that according to [DSN], Delivery Status Notifications MUST NOT
22739
 
+   be generated if the MAIL FROM (or Return-Path) is empty.
22740
 
+
22741
 
+   The DSN message MUST follow the requirements of [DSN] and [REPORT].
22742
 
+   The action-value field defined in [DSN], Section 2.3.3, MUST contain
22743
 
+   the value "failed".  The human-readable portion of the non-delivery
22744
 
+   report MUST contain the "reason" string from the "ereject" action and
22745
 
+   SHOULD contain additional text alerting the apparent original sender
22746
 
+   that the message was refused by an email filter.  This part of the
22747
 
+   report might appear as follows:
22748
 
+
22749
 
+   ------------------------------------------------------------
22750
 
+   Your message was refused by the recipient's mail filtering program.
22751
 
+   The reason given is as follows:
22752
 
+
22753
 
+   I am not taking mail from you, and I don't want your birdseed,
22754
 
+   either!
22755
 
+   ------------------------------------------------------------
22756
 
+
22757
 
+2.2.  Action reject
22758
 
+
22759
 
+   This section updates the definition of the "reject" action in Section
22760
 
+   4.1 of RFC 3028 [RFC3028] and is an optional extension to [SIEVE].
22761
 
+
22762
 
+          Usage:   reject <reason: string>
22763
 
+
22764
 
+   Sieve implementations that implement the "reject" action must use the
22765
 
+   "reject" capability string.
22766
 
+
22767
 
+   The "reject" action cancels the implicit keep and refuses delivery of
22768
 
+   a message.  The "reason" string is a UTF-8 [UTF-8] string specifying
22769
 
+   the reason for refusal.  Unlike the "ereject" action described above,
22770
 
+   this action would always favor preserving the exact text of the
22771
 
+   refusal reason.  Typically, the "reject" action refuses delivery of a
22772
 
+   message by sending back an MDN to the sender (see Section 2.2.1).
22773
 
+   However, implementations MAY refuse delivery over SMTP/LMTP protocol
22774
 
+   (as detailed in Section 2.5), if and only if all of the following
22775
 
+   conditions are true:
22776
 
+
22777
 
+   1.  The "reason" string consists of only US-ASCII characters
22778
 
+         or
22779
 
+       The "reason" string contains non-US-ASCII and both the client and
22780
 
+       server support and negotiate use of an SMTP/LMTP extension for
22781
 
+       sending UTF-8 responses.
22782
 
+
22783
 
+
22784
 
+
22785
 
+
22786
 
+
22787
 
+
22788
 
+
22789
 
+Stone                       Standards Track                     [Page 6]
22790
 
+
22791
 
+RFC 5429                Sieve Extension: Reject               March 2009
22792
 
+
22793
 
+
22794
 
+   2.  LMTP protocol is used
22795
 
+         or
22796
 
+       SMTP protocol is used and the message has a single recipient
22797
 
+         or
22798
 
+       SMTP protocol is used, the message has multiple recipients, and
22799
 
+       all of them refused message delivery (whether or not Sieve is
22800
 
+       being used).
22801
 
+
22802
 
+
22803
 
+      Example:
22804
 
+              require ["reject"];
22805
 
+
22806
 
+              if size :over 100K {
22807
 
+                  reject text:
22808
 
+      Your message is too big.  If you want to send me a big attachment,
22809
 
+      put it on a public web site and send me a URL.
22810
 
+      .
22811
 
+                  ;
22812
 
+              }
22813
 
+
22814
 
+   (Pretend that the "reason" string above contains some non-US-ACSII
22815
 
+   text.)
22816
 
+
22817
 
+   Implementations may use techniques as described in Section 2.1 to
22818
 
+   determine if a non-delivery report should not be sent to a forged
22819
 
+   sender.  Implementations SHOULD log instances when a non-delivery
22820
 
+   report is not sent and the reason for not sending the report.
22821
 
+
22822
 
+2.2.1.  Rejecting a Message by Sending an MDN
22823
 
+
22824
 
+   The "reject" action resends the received message to the envelope
22825
 
+   sender specified by the MAIL FROM (or Return-Path) address, wrapping
22826
 
+   it in a "reject" form, explaining that it was rejected by the
22827
 
+   recipient.
22828
 
+
22829
 
+   Note that according to [MDN], Message Disposition Notifications MUST
22830
 
+   NOT be generated if the MAIL FROM (or Return-Path) is empty.
22831
 
+
22832
 
+   A reject message MUST take the form of a failure MDN as specified by
22833
 
+   [MDN].  The human-readable portion of the message, the first
22834
 
+   component of the MDN, contains the human-readable message describing
22835
 
+   the error, and it SHOULD contain additional text alerting the
22836
 
+   apparent original sender that mail was refused by an email filter.
22837
 
+
22838
 
+   The MDN disposition-field as defined in the MDN specification MUST be
22839
 
+   "deleted" and MUST have the "MDN-sent-automatically" and "automatic-
22840
 
+   action" modes set (see Section 3.2.6 of [MDN]).
22841
 
+
22842
 
+
22843
 
+
22844
 
+
22845
 
+Stone                       Standards Track                     [Page 7]
22846
 
+
22847
 
+RFC 5429                Sieve Extension: Reject               March 2009
22848
 
+
22849
 
+
22850
 
+   In the following script, a message is rejected and returned to the
22851
 
+   sender.
22852
 
+
22853
 
+       Example:
22854
 
+               require ["reject"];
22855
 
+
22856
 
+               if header :contains "from" "coyote@desert.example.org" {
22857
 
+                   reject text:
22858
 
+       I am not taking mail from you, and I don't
22859
 
+       want your birdseed, either!
22860
 
+       .
22861
 
+                   ;
22862
 
+               }
22863
 
+
22864
 
+   For this script, the first part of the MDN might appear as follows:
22865
 
+
22866
 
+   ------------------------------------------------------------
22867
 
+   The message was refused by the recipient's mail filtering program.
22868
 
+   The reason given was as follows:
22869
 
+
22870
 
+   I am not taking mail from you, and I don't want your birdseed,
22871
 
+   either!
22872
 
+   ------------------------------------------------------------
22873
 
+
22874
 
+2.3.  Silent Upgrade from "reject" to "ereject"
22875
 
+
22876
 
+   Implementations MUST NOT silently upgrade "reject" actions to
22877
 
+   "ereject" actions in a Sieve script because this might lead to
22878
 
+   unpleasant changes of behavior not expected by the script owner.
22879
 
+
22880
 
+   User interfaces that present a generic rejection option, and generate
22881
 
+   Sieve script output, MAY switch from generating "reject" to "ereject"
22882
 
+   actions, so long as doing so does not create a confusing change for
22883
 
+   the script owner.
22884
 
+
22885
 
+   Script generators SHOULD ensure that a rejection action being
22886
 
+   executed as a result of an anti-spam/anti-virus positive test be done
22887
 
+   using the "ereject" action, as it is more suitable for such
22888
 
+   rejections.
22889
 
+
22890
 
+   Script generators MAY automatically upgrade scripts that previously
22891
 
+   used the "reject" action for anti-spam/anti-virus related rejections.
22892
 
+   Note that such generators MUST make sure that the target environment
22893
 
+   can support the "ereject" action.
22894
 
+
22895
 
+
22896
 
+
22897
 
+
22898
 
+
22899
 
+
22900
 
+
22901
 
+Stone                       Standards Track                     [Page 8]
22902
 
+
22903
 
+RFC 5429                Sieve Extension: Reject               March 2009
22904
 
+
22905
 
+
22906
 
+2.4.  Compatibility with Other Actions
22907
 
+
22908
 
+   This section applies equally to "reject" and "ereject" actions.  All
22909
 
+   references to the "reject" action in this section can be replaced
22910
 
+   with the "ereject" action.
22911
 
+
22912
 
+   A "reject" action cancels the implicit keep.
22913
 
+
22914
 
+   Implementations MUST prohibit the execution of more than one "reject"
22915
 
+   in a Sieve script.
22916
 
+
22917
 
+   "reject" MUST be incompatible with the "vacation" [VACATION] action.
22918
 
+   It is NOT RECOMMENDED that implementations permit the use of "reject"
22919
 
+   with actions that cause mail delivery, such as "keep", "fileinto",
22920
 
+   and "redirect".
22921
 
+
22922
 
+   Making "reject" compatible with actions that cause mail delivery
22923
 
+   violates the RFC 5321 [SMTP] principle that a message is either
22924
 
+   delivered or bounced back to the sender.  So bouncing a message back
22925
 
+   (rejecting) and delivering it will make the sender believe that the
22926
 
+   message was not delivered.
22927
 
+
22928
 
+   However, there are existing laws requiring certain organizations to
22929
 
+   archive all received messages, even the rejected ones.  Also, it can
22930
 
+   be quite useful to save copies of rejected messages for later
22931
 
+   analysis.
22932
 
+
22933
 
+   Any action that would modify the message body will not have an effect
22934
 
+   on the body of any message refused by "reject" using an SMTP response
22935
 
+   code and MUST NOT have any effect on the content of generated DSN/
22936
 
+   MDNs.
22937
 
+
22938
 
+2.5.  Details of Protocol-Level Refusal
22939
 
+
22940
 
+   If the "reason" string consists of multiple CRLF separated lines,
22941
 
+   then the reason text MUST be returned as a multiline SMTP/LMTP
22942
 
+   response, per Section 4.2.1 of [SMTP].  Any line MUST NOT exceed the
22943
 
+   SMTP limit on the maximal line length.  To make the "reason" string
22944
 
+   conform to any such limits, the server MAY insert CRLFs and turn the
22945
 
+   response into a multiline response.
22946
 
+
22947
 
+   In the following script (which assumes support for the "spamtest"
22948
 
+   [SPAMTEST] and "fileinto" extensions), messages that test highly
22949
 
+   positive for spam are refused.
22950
 
+
22951
 
+
22952
 
+
22953
 
+
22954
 
+
22955
 
+
22956
 
+
22957
 
+Stone                       Standards Track                     [Page 9]
22958
 
+
22959
 
+RFC 5429                Sieve Extension: Reject               March 2009
22960
 
+
22961
 
+
22962
 
+       Example:
22963
 
+               require ["ereject", "spamtest", "fileinto",
22964
 
+                        "comparator-i;ascii-numeric"];
22965
 
+
22966
 
+               if spamtest :value "ge"
22967
 
+                           :comparator "i;ascii-numeric" "6" {
22968
 
+                   ereject text:
22969
 
+       AntiSpam engine thinks your message is spam.
22970
 
+       It is therefore being refused.
22971
 
+       Please call 1-900-PAY-US if you want to reach us.
22972
 
+       .
22973
 
+                   ;
22974
 
+               } elsif spamtest :value "ge"
22975
 
+                                :comparator "i;ascii-numeric" "4" {
22976
 
+                   fileinto "Suspect";
22977
 
+               }
22978
 
+
22979
 
+   The following excerpt from an SMTP session shows it in action.
22980
 
+
22981
 
+         ...
22982
 
+         C: DATA
22983
 
+         S: 354 Send message, ending in CRLF.CRLF.
22984
 
+          ...
22985
 
+         C: .
22986
 
+         S: 550-AntiSpam engine thinks your message is spam.
22987
 
+         S: 550-It is therefore being refused.
22988
 
+         S: 550 Please call 1-900-PAY-US if you want to reach us.
22989
 
+
22990
 
+   If the SMTP/LMTP server supports RFC 2034 [ENHANCED-CODES], it MUST
22991
 
+   prepend an appropriate Enhanced Error Code to the "reason" text.
22992
 
+   Enhanced Error code 5.7.1 or a more generic 5.7.0 are RECOMMENDED.
22993
 
+   With an Enhanced Error Code, the response to a DATA command in the
22994
 
+   SMTP example below will look like:
22995
 
+
22996
 
+         S: 550-5.7.1 AntiSpam engine thinks your message is spam.
22997
 
+         S: 550-5.7.1 It is therefore being refused.
22998
 
+         S: 550 5.7.1 Please call 1-900-PAY-US if you want to reach us.
22999
 
+
23000
 
+   if the server selected "5.7.1" as appropriate.
23001
 
+
23002
 
+   If a Sieve implementation that supports "ereject" does not wish to
23003
 
+   immediately disclose the reason for rejection (for example, that it
23004
 
+   detected spam), it may delay immediately sending of the 550 error
23005
 
+   code by sending a 4XX error code on the first attempt to receive the
23006
 
+   message.
23007
 
+
23008
 
+
23009
 
+
23010
 
+
23011
 
+
23012
 
+
23013
 
+Stone                       Standards Track                    [Page 10]
23014
 
+
23015
 
+RFC 5429                Sieve Extension: Reject               March 2009
23016
 
+
23017
 
+
23018
 
+3.  Changes from RFC 3028
23019
 
+
23020
 
+   Clarified that the "reject" action cancels the implicit keep.
23021
 
+   Extended the list of allowable actions on "reject" to include
23022
 
+   protocol-level message rejection.
23023
 
+
23024
 
+   Added the "ereject" action that is similar to "reject", but will
23025
 
+   always favor protocol-level message rejection.
23026
 
+
23027
 
+4.  Security Considerations
23028
 
+
23029
 
+   The introduction to this document discusses why rejecting messages
23030
 
+   before delivery is better than accepting and bouncing them.
23031
 
+
23032
 
+   While the details of techniques that can be used to determine when to
23033
 
+   silently drop a non-delivery report are outside the scope of this
23034
 
+   document, the explicit permission this document gives to take such
23035
 
+   action may enable denial-of-service situations.  Techniques such as
23036
 
+   spam-checking, return-path verification, and others, can and do have
23037
 
+   false-positives.  Care should be exercised to prevent the loss of
23038
 
+   legitimate messages by failing to notify the sender of non-delivery.
23039
 
+
23040
 
+   Security issues associated with email auto-responders are fully
23041
 
+   discussed in the Security Considerations section of [RFC3834].  This
23042
 
+   document is not believed to introduce any additional security
23043
 
+   considerations in this general area.
23044
 
+
23045
 
+   The "ereject" extension does not raise any other security
23046
 
+   considerations that are not already present in the base [SIEVE]
23047
 
+   specification, and these issues are discussed in [SIEVE].
23048
 
+
23049
 
+5.  IANA Considerations
23050
 
+
23051
 
+   The following section provides the IANA registrations for the Sieve
23052
 
+   extensions specified in this document.
23053
 
+
23054
 
+5.1.  "reject" Extension Registration
23055
 
+
23056
 
+   IANA is requested to update the registration for the Sieve "reject"
23057
 
+   extension as detailed below:
23058
 
+
23059
 
+   Capability name: reject
23060
 
+   Description:     adds the "reject" action for refusing delivery
23061
 
+                    of a message.  The exact reason for refusal is
23062
 
+                    conveyed back to the client.
23063
 
+   RFC number:      RFC 5429
23064
 
+   Contact address: the Sieve discussion list <ietf-mta-filters@imc.org>
23065
 
+
23066
 
+
23067
 
+
23068
 
+
23069
 
+Stone                       Standards Track                    [Page 11]
23070
 
+
23071
 
+RFC 5429                Sieve Extension: Reject               March 2009
23072
 
+
23073
 
+
23074
 
+5.2.  "ereject" Extension Registration
23075
 
+
23076
 
+   IANA is requested to replace the preliminary registration of the
23077
 
+   Sieve refuse extension with the following registration:
23078
 
+
23079
 
+   Capability name: ereject
23080
 
+   Description:     adds the "ereject" action for refusing delivery
23081
 
+                    of a message.  The refusal should happen as early
23082
 
+                    as possible (e.g., at the protocol level) and might
23083
 
+                    not preserve the exact reason for refusal if it
23084
 
+                    contains non-US-ASCII text.
23085
 
+   RFC number:      RFC 5429
23086
 
+   Contact address: the Sieve discussion list <ietf-mta-filters@imc.org>
23087
 
+
23088
 
+6.  References
23089
 
+
23090
 
+6.1.  Normative References
23091
 
+
23092
 
+   [DSN]             Moore, K. and G. Vaudreuil, "An Extensible Message
23093
 
+                     Format for Delivery Status Notifications",
23094
 
+                     RFC 3464, January 2003.
23095
 
+
23096
 
+   [ENHANCED-CODES]  Freed, N., "SMTP Service Extension for Returning
23097
 
+                     Enhanced Error Codes", RFC 2034, October 1996.
23098
 
+
23099
 
+   [KEYWORDS]        Bradner, S., "Key words for use in RFCs to Indicate
23100
 
+                     Requirement Levels", BCP 14, RFC 2119, March 1997.
23101
 
+
23102
 
+   [LMTP]            Myers, J., "Local Mail Transfer Protocol",
23103
 
+                     RFC 2033, October 1996.
23104
 
+
23105
 
+   [MDN]             Hansen, T. and G. Vaudreuil, "Message Disposition
23106
 
+                     Notification", RFC 3798, May 2004.
23107
 
+
23108
 
+   [REPORT]          Vaudreuil, G., "The Multipart/Report Content Type
23109
 
+                     for the Reporting of Mail System Administrative
23110
 
+                     Messages", RFC 3462, January 2003.
23111
 
+
23112
 
+   [SIEVE]           Guenther, P. and T. Showalter, "Sieve: An Email
23113
 
+                     Filtering Language", RFC 5228, January 2008.
23114
 
+
23115
 
+   [SMTP]            Klensin, J., "Simple Mail Transfer Protocol",
23116
 
+                     RFC 5321, October 2008.
23117
 
+
23118
 
+   [UTF-8]           Yergeau, F., "UTF-8, a transformation format of ISO
23119
 
+                     10646", STD 63, RFC 3629, November 2003.
23120
 
+
23121
 
+
23122
 
+
23123
 
+
23124
 
+
23125
 
+Stone                       Standards Track                    [Page 12]
23126
 
+
23127
 
+RFC 5429                Sieve Extension: Reject               March 2009
23128
 
+
23129
 
+
23130
 
+   [VACATION]        Showalter, T. and N. Freed, "Sieve Email Filtering:
23131
 
+                     Vacation Extension", RFC 5230, January 2008.
23132
 
+
23133
 
+6.2.  Informative References
23134
 
+
23135
 
+   [EMAIL-ARCH]      Crocker, D., "Internet Mail Architecture", Work
23136
 
+                     in Progress, October 2008.
23137
 
+
23138
 
+   [Joe-DoS]         Frei, S., Silvestri, I., and G. Ollman, "Mail Non-
23139
 
+                     Delivery Notice Attacks", April 2004, <http://
23140
 
+                     www.techzoom.net/papers/
23141
 
+                     mail_non_delivery_notice_attacks_2004.pdf>.
23142
 
+
23143
 
+   [RFC3028]         Showalter, T., "Sieve: A Mail Filtering Language",
23144
 
+                     RFC 3028, January 2001.
23145
 
+
23146
 
+   [RFC3834]         Moore, K., "Recommendations for Automatic Responses
23147
 
+                     to Electronic Mail", RFC 3834, August 2004.
23148
 
+
23149
 
+   [SPAMTEST]        Daboo, C., "Sieve Email Filtering: Spamtest and
23150
 
+                     Virustest Extensions", RFC 5235, January 2008.
23151
 
+
23152
 
+   [UTF8-RESP]       Melnikov, A., "SMTP Language Extension", Work
23153
 
+                     in Progress, June 2007.
23154
 
+
23155
 
+
23156
 
+
23157
 
+
23158
 
+
23159
 
+
23160
 
+
23161
 
+
23162
 
+
23163
 
+
23164
 
+
23165
 
+
23166
 
+
23167
 
+
23168
 
+
23169
 
+
23170
 
+
23171
 
+
23172
 
+
23173
 
+
23174
 
+
23175
 
+
23176
 
+
23177
 
+
23178
 
+
23179
 
+
23180
 
+
23181
 
+Stone                       Standards Track                    [Page 13]
23182
 
+
23183
 
+RFC 5429                Sieve Extension: Reject               March 2009
23184
 
+
23185
 
+
23186
 
+Appendix A.  Acknowledgements
23187
 
+
23188
 
+   Thanks to Ned Freed, Cyrus Daboo, Arnt Gulbrandsen, Kristin Hubner,
23189
 
+   Mark E. Mallett, Philip Guenther, Michael Haardt, and Randy Gellens
23190
 
+   for comments and corrections.
23191
 
+
23192
 
+   The authors gratefully acknowledge the extensive work of Tim
23193
 
+   Showalter as the author of the RFC 3028, which originally defined the
23194
 
+   "reject" action.
23195
 
+
23196
 
+Appendix B.  Contributors
23197
 
+
23198
 
+   Matthew Elvey
23199
 
+   The Elvey Partnership, LLC
23200
 
+   1819 Polk Street, Suite 133
23201
 
+   San Francisco, CA  94109
23202
 
+   USA
23203
 
+
23204
 
+   EMail: matthew@elvey.com
23205
 
+
23206
 
+
23207
 
+   Alexey Melnikov
23208
 
+   Isode Limited
23209
 
+   5 Castle Business Village
23210
 
+   36 Station Road
23211
 
+   Hampton, Middlesex  TW12 2BX
23212
 
+   UK
23213
 
+
23214
 
+   EMail: Alexey.Melnikov@isode.com
23215
 
+
23216
 
+Author's Address
23217
 
+
23218
 
+   Aaron Stone (editor)
23219
 
+   Serendipity
23220
 
+   260 El Verano Ave
23221
 
+   Palo Alto, CA  94306
23222
 
+   USA
23223
 
+
23224
 
+   EMail: aaron@serendipity.palo-alto.ca.us
23225
 
+
23226
 
+
23227
 
+
23228
 
+
23229
 
+
23230
 
+
23231
 
+
23232
 
+
23233
 
+
23234
 
+
23235
 
+
23236
 
+
23237
 
+Stone                       Standards Track                    [Page 14]
23238
 
+
23239
 
diff -urN dovecot-1.2.4/dovecot-libsieve/doc/rfc/relational.rfc5231.txt dovecot-1.2.4.debian/dovecot-libsieve/doc/rfc/relational.rfc5231.txt
23240
 
--- dovecot-1.2.4/dovecot-libsieve/doc/rfc/relational.rfc5231.txt       1970-01-01 01:00:00.000000000 +0100
23241
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/doc/rfc/relational.rfc5231.txt        2008-08-25 10:25:08.000000000 +0200
23242
 
@@ -0,0 +1,507 @@
23243
 
+
23244
 
+
23245
 
+
23246
 
+
23247
 
+
23248
 
+
23249
 
+Network Working Group                                       W. Segmuller
23250
 
+Request for Comments: 5231                                      B. Leiba
23251
 
+Obsoletes: 3431                          IBM T.J. Watson Research Center
23252
 
+Category: Standards Track                                   January 2008
23253
 
+
23254
 
+
23255
 
+              Sieve Email Filtering: Relational Extension
23256
 
+
23257
 
+Status of This Memo
23258
 
+
23259
 
+   This document specifies an Internet standards track protocol for the
23260
 
+   Internet community, and requests discussion and suggestions for
23261
 
+   improvements.  Please refer to the current edition of the "Internet
23262
 
+   Official Protocol Standards" (STD 1) for the standardization state
23263
 
+   and status of this protocol.  Distribution of this memo is unlimited.
23264
 
+
23265
 
+Abstract
23266
 
+
23267
 
+   This document describes the RELATIONAL extension to the Sieve mail
23268
 
+   filtering language defined in RFC 3028.  This extension extends
23269
 
+   existing conditional tests in Sieve to allow relational operators.
23270
 
+   In addition to testing their content, it also allows for testing of
23271
 
+   the number of entities in header and envelope fields.
23272
 
+
23273
 
+   This document obsoletes RFC 3431.
23274
 
+
23275
 
+Table of Contents
23276
 
+
23277
 
+   1.  Introduction  . . . . . . . . . . . . . . . . . . . . . . . . . 2
23278
 
+   2.  Conventions Used in This Document . . . . . . . . . . . . . . . 2
23279
 
+   3.  Comparators . . . . . . . . . . . . . . . . . . . . . . . . . . 2
23280
 
+   4.  Match Types . . . . . . . . . . . . . . . . . . . . . . . . . . 3
23281
 
+     4.1.  Match Type VALUE  . . . . . . . . . . . . . . . . . . . . . 3
23282
 
+     4.2.  Match Type COUNT  . . . . . . . . . . . . . . . . . . . . . 3
23283
 
+   5.  Interaction with Other Sieve Actions  . . . . . . . . . . . . . 4
23284
 
+   6.  Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
23285
 
+   7.  Extended Example  . . . . . . . . . . . . . . . . . . . . . . . 6
23286
 
+   8.  Changes since RFC 3431  . . . . . . . . . . . . . . . . . . . . 6
23287
 
+   9.  IANA Considerations . . . . . . . . . . . . . . . . . . . . . . 7
23288
 
+   10. Security Considerations . . . . . . . . . . . . . . . . . . . . 7
23289
 
+   11. Normative References  . . . . . . . . . . . . . . . . . . . . . 7
23290
 
+
23291
 
+
23292
 
+
23293
 
+
23294
 
+
23295
 
+
23296
 
+
23297
 
+
23298
 
+
23299
 
+
23300
 
+Segmuller & Leiba           Standards Track                     [Page 1]
23301
 
+
23302
 
+RFC 5231              Sieve: Relational Extension           January 2008
23303
 
+
23304
 
+
23305
 
+1.  Introduction
23306
 
+
23307
 
+   The RELATIONAL extension to the Sieve mail filtering language [Sieve]
23308
 
+   provides relational operators on the address, envelope, and header
23309
 
+   tests.  This extension also provides a way of counting the entities
23310
 
+   in a message header or address field.
23311
 
+
23312
 
+   With this extension, the Sieve script may now determine if a field is
23313
 
+   greater than or less than a value instead of just equivalent.  One
23314
 
+   use is for the x-priority field: move messages with a priority
23315
 
+   greater than 3 to the "work on later" folder.  Mail could also be
23316
 
+   sorted by the from address.  Those userids that start with 'a'-'m' go
23317
 
+   to one folder, and the rest go to another folder.
23318
 
+
23319
 
+   The Sieve script can also determine the number of fields in the
23320
 
+   header, or the number of addresses in a recipient field, for example,
23321
 
+   whether there are more than 5 addresses in the to and cc fields.
23322
 
+
23323
 
+   The capability string associated with the extension defined in this
23324
 
+   document is "relational".
23325
 
+
23326
 
+2.  Conventions Used in This Document
23327
 
+
23328
 
+   The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
23329
 
+   "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
23330
 
+   document are to be interpreted as described in BCP 14, RFC 2119.
23331
 
+
23332
 
+   Conventions for notations are as in [Sieve] section 1.1, including
23333
 
+   the use of [Kwds] and the use of [ABNF].
23334
 
+
23335
 
+3.  Comparators
23336
 
+
23337
 
+   This document does not define any comparators or exempt any
23338
 
+   comparators from the require clause.  Any comparator used must be
23339
 
+   treated as defined in [Sieve].
23340
 
+
23341
 
+   The "i;ascii-numeric" comparator, as defined in [RFC4790], MUST be
23342
 
+   supported for any implementation of this extension.  The comparator
23343
 
+   "i;ascii-numeric" MUST support at least 32-bit unsigned integers.
23344
 
+
23345
 
+   Larger integers MAY be supported.  Note: the "i;ascii-numeric"
23346
 
+   comparator does not support negative numbers.
23347
 
+
23348
 
+
23349
 
+
23350
 
+
23351
 
+
23352
 
+
23353
 
+
23354
 
+
23355
 
+
23356
 
+Segmuller & Leiba           Standards Track                     [Page 2]
23357
 
+
23358
 
+RFC 5231              Sieve: Relational Extension           January 2008
23359
 
+
23360
 
+
23361
 
+4.  Match Types
23362
 
+
23363
 
+   This document defines two new match types.  They are the VALUE match
23364
 
+   type and the COUNT match type.
23365
 
+
23366
 
+   The syntax is:
23367
 
+
23368
 
+   MATCH-TYPE =/ COUNT / VALUE
23369
 
+
23370
 
+   COUNT = ":count" relational-match
23371
 
+
23372
 
+   VALUE = ":value" relational-match
23373
 
+
23374
 
+   relational-match = DQUOTE
23375
 
+           ("gt" / "ge" / "lt" / "le" / "eq" / "ne") DQUOTE
23376
 
+           ; "gt" means "greater than", the C operator ">".
23377
 
+           ; "ge" means "greater than or equal", the C operator ">=".
23378
 
+           ; "lt" means "less than", the C operator "<".
23379
 
+           ; "le" means "less than or equal", the C operator "<=".
23380
 
+           ; "eq" means "equal to", the C operator "==".
23381
 
+           ; "ne" means "not equal to", the C operator "!=".
23382
 
+
23383
 
+4.1.  Match Type VALUE
23384
 
+
23385
 
+   The VALUE match type does a relational comparison between strings.
23386
 
+
23387
 
+   The VALUE match type may be used with any comparator that returns
23388
 
+   sort information.
23389
 
+
23390
 
+   A value from the message is considered the left side of the relation.
23391
 
+   A value from the test expression, the key-list for address, envelope,
23392
 
+   and header tests, is the right side of the relation.
23393
 
+
23394
 
+   If there are multiple values on either side or both sides, the test
23395
 
+   is considered true if any pair is true.
23396
 
+
23397
 
+4.2.  Match Type COUNT
23398
 
+
23399
 
+   The COUNT match type first determines the number of the specified
23400
 
+   entities in the message and does a relational comparison of the
23401
 
+   number of entities, as defined below, to the values specified in the
23402
 
+   test expression.
23403
 
+
23404
 
+   The COUNT match type SHOULD only be used with numeric comparators.
23405
 
+
23406
 
+   The Address Test counts the number of addresses (the number of
23407
 
+   "mailbox" elements, as defined in [RFC2822]) in the specified fields.
23408
 
+   Group names are ignored, but the contained mailboxes are counted.
23409
 
+
23410
 
+
23411
 
+
23412
 
+Segmuller & Leiba           Standards Track                     [Page 3]
23413
 
+
23414
 
+RFC 5231              Sieve: Relational Extension           January 2008
23415
 
+
23416
 
+
23417
 
+   The Envelope Test counts the number of addresses in the specified
23418
 
+   envelope parts.  The envelope "to" will always have only one entry,
23419
 
+   which is the address of the user for whom the Sieve script is
23420
 
+   running.  Using this test, there is no way a Sieve script can
23421
 
+   determine if the message was actually sent to someone else.  The
23422
 
+   envelope "from" will be 0 if the MAIL FROM is empty, or 1 if MAIL
23423
 
+   FROM is not empty.
23424
 
+
23425
 
+   The Header Test counts the total number of instances of the specified
23426
 
+   fields.  This does not count individual addresses in the "to", "cc",
23427
 
+   and other recipient fields.
23428
 
+
23429
 
+   In all cases, if more than one field name is specified, the counts
23430
 
+   for all specified fields are added together to obtain the number for
23431
 
+   comparison.  Thus, specifying ["to", "cc"] in an address COUNT test
23432
 
+   compares the total number of "to" and "cc" addresses; if separate
23433
 
+   counts are desired, they must be done in two comparisons, perhaps
23434
 
+   joined by "allof" or "anyof".
23435
 
+
23436
 
+5.  Interaction with Other Sieve Actions
23437
 
+
23438
 
+   This specification adds two match types.  The VALUE match type only
23439
 
+   works with comparators that return sort information.  The COUNT match
23440
 
+   type only makes sense with numeric comparators.
23441
 
+
23442
 
+   There is no interaction with any other Sieve operations, nor with any
23443
 
+   known extensions.  In particular, this specification has no effect on
23444
 
+   implicit KEEP, nor on any explicit message actions.
23445
 
+
23446
 
+6.  Example
23447
 
+
23448
 
+   Using the message:
23449
 
+
23450
 
+      received: ...
23451
 
+      received: ...
23452
 
+      subject: example
23453
 
+      to: foo@example.com, baz@example.com
23454
 
+      cc: qux@example.com
23455
 
+
23456
 
+   The test:
23457
 
+
23458
 
+      address :count "ge" :comparator "i;ascii-numeric"
23459
 
+                      ["to", "cc"] ["3"]
23460
 
+
23461
 
+   would evaluate to true, and the test
23462
 
+
23463
 
+
23464
 
+
23465
 
+
23466
 
+
23467
 
+
23468
 
+Segmuller & Leiba           Standards Track                     [Page 4]
23469
 
+
23470
 
+RFC 5231              Sieve: Relational Extension           January 2008
23471
 
+
23472
 
+
23473
 
+      anyof ( address :count "ge" :comparator "i;ascii-numeric"
23474
 
+                      ["to"] ["3"],
23475
 
+              address :count "ge" :comparator "i;ascii-numeric"
23476
 
+                      ["cc"] ["3"] )
23477
 
+
23478
 
+   would evaluate to false.
23479
 
+
23480
 
+   To check the number of received fields in the header, the following
23481
 
+   test may be used:
23482
 
+
23483
 
+      header :count "ge" :comparator "i;ascii-numeric"
23484
 
+                      ["received"] ["3"]
23485
 
+
23486
 
+   This would evaluate to false.  But
23487
 
+
23488
 
+      header :count "ge" :comparator "i;ascii-numeric"
23489
 
+                      ["received", "subject"] ["3"]
23490
 
+
23491
 
+   would evaluate to true.
23492
 
+
23493
 
+   The test:
23494
 
+
23495
 
+      header :count "ge" :comparator "i;ascii-numeric"
23496
 
+                      ["to", "cc"] ["3"]
23497
 
+
23498
 
+   will always evaluate to false on an RFC 2822 compliant message
23499
 
+   [RFC2822], since a message can have at most one "to" field and at
23500
 
+   most one "cc" field.  This test counts the number of fields, not the
23501
 
+   number of addresses.
23502
 
+
23503
 
+
23504
 
+
23505
 
+
23506
 
+
23507
 
+
23508
 
+
23509
 
+
23510
 
+
23511
 
+
23512
 
+
23513
 
+
23514
 
+
23515
 
+
23516
 
+
23517
 
+
23518
 
+
23519
 
+
23520
 
+
23521
 
+
23522
 
+
23523
 
+
23524
 
+Segmuller & Leiba           Standards Track                     [Page 5]
23525
 
+
23526
 
+RFC 5231              Sieve: Relational Extension           January 2008
23527
 
+
23528
 
+
23529
 
+7.  Extended Example
23530
 
+
23531
 
+      require ["relational", "comparator-i;ascii-numeric", "fileinto"];
23532
 
+
23533
 
+      if header :value "lt" :comparator "i;ascii-numeric"
23534
 
+                ["x-priority"] ["3"]
23535
 
+      {
23536
 
+         fileinto "Priority";
23537
 
+      }
23538
 
+
23539
 
+      elsif address :count "gt" :comparator "i;ascii-numeric"
23540
 
+                 ["to"] ["5"]
23541
 
+      {
23542
 
+         # everything with more than 5 recipients in the "to" field
23543
 
+         # is considered SPAM
23544
 
+         fileinto "SPAM";
23545
 
+      }
23546
 
+
23547
 
+      elsif address :value "gt" :all :comparator "i;ascii-casemap"
23548
 
+                 ["from"] ["M"]
23549
 
+      {
23550
 
+         fileinto "From N-Z";
23551
 
+      } else {
23552
 
+         fileinto "From A-M";
23553
 
+      }
23554
 
+
23555
 
+      if allof ( address :count "eq" :comparator "i;ascii-numeric"
23556
 
+                         ["to", "cc"] ["1"] ,
23557
 
+                 address :all :comparator "i;ascii-casemap"
23558
 
+                         ["to", "cc"] ["me@foo.example.com"] )
23559
 
+      {
23560
 
+         fileinto "Only me";
23561
 
+      }
23562
 
+
23563
 
+8.  Changes since RFC 3431
23564
 
+
23565
 
+   Apart from several minor editorial/wording changes, the following
23566
 
+   list describes the notable changes to this specification since RFC
23567
 
+   3431.
23568
 
+
23569
 
+   o  Updated references, including changing the comparator reference
23570
 
+      from the Application Configuration Access Protocol (ACAP) to the
23571
 
+      "Internet Application Protocol Collation Registry" document
23572
 
+      [RFC4790].
23573
 
+
23574
 
+   o  Updated and corrected the examples.
23575
 
+
23576
 
+
23577
 
+
23578
 
+
23579
 
+
23580
 
+Segmuller & Leiba           Standards Track                     [Page 6]
23581
 
+
23582
 
+RFC 5231              Sieve: Relational Extension           January 2008
23583
 
+
23584
 
+
23585
 
+   o  Added definition comments to ABNF for "gt", "lt", etc.
23586
 
+
23587
 
+   o  Clarified what RFC 2822 elements are counted in the COUNT test.
23588
 
+
23589
 
+   o  Removed the requirement to strip white space from header fields
23590
 
+      before comparing; a more general version of this requirement has
23591
 
+      been added to the Sieve base spec.
23592
 
+
23593
 
+9.  IANA Considerations
23594
 
+
23595
 
+   The following template specifies the IANA registration of the
23596
 
+   relational Sieve extension specified in this document:
23597
 
+
23598
 
+   To: iana@iana.org
23599
 
+   Subject: Registration of new Sieve extension
23600
 
+
23601
 
+   Capability name: relational
23602
 
+   Description:     Extends existing conditional tests in Sieve language
23603
 
+                    to allow relational operators
23604
 
+   RFC number:      RFC 5231
23605
 
+   Contact address: The Sieve discussion list <ietf-mta-filters@imc.org>
23606
 
+
23607
 
+10.  Security Considerations
23608
 
+
23609
 
+   An implementation MUST ensure that the test for envelope "to" only
23610
 
+   reflects the delivery to the current user.  Using this test, it MUST
23611
 
+   not be possible for a user to determine if this message was delivered
23612
 
+   to someone else.
23613
 
+
23614
 
+   Additional security considerations are discussed in [Sieve].
23615
 
+
23616
 
+11.  Normative References
23617
 
+
23618
 
+   [ABNF]     Crocker, D., Ed. and P. Overell, "Augmented BNF for Syntax
23619
 
+              Specifications: ABNF", RFC 4234, October 2005.
23620
 
+
23621
 
+   [Kwds]     Bradner, S., "Key words for use in RFCs to Indicate
23622
 
+              Requirement Levels", RFC 2119, March 1997.
23623
 
+
23624
 
+   [RFC2822]  Resnick, P., "Internet Message Format", RFC 2822,
23625
 
+              April 2001.
23626
 
+
23627
 
+   [RFC4790]  Newman, C., Duerst, M., and A. Gulbrandsen, "Internet
23628
 
+              Application Protocol Collation Registry", RFC 4790,
23629
 
+              March 2007.
23630
 
+
23631
 
+   [Sieve]    Guenther, P., Ed. and T. Showalter, Ed., "Sieve: An Email
23632
 
+              Filtering Language", RFC 5228, January 2008.
23633
 
+
23634
 
+
23635
 
+
23636
 
+Segmuller & Leiba           Standards Track                     [Page 7]
23637
 
+
23638
 
+RFC 5231              Sieve: Relational Extension           January 2008
23639
 
+
23640
 
+
23641
 
+Authors' Addresses
23642
 
+
23643
 
+   Wolfgang Segmuller
23644
 
+   IBM T.J. Watson Research Center
23645
 
+   19 Skyline Drive
23646
 
+   Hawthorne, NY  10532
23647
 
+   US
23648
 
+
23649
 
+   Phone: +1 914 784 7408
23650
 
+   EMail: werewolf@us.ibm.com
23651
 
+
23652
 
+
23653
 
+   Barry Leiba
23654
 
+   IBM T.J. Watson Research Center
23655
 
+   19 Skyline Drive
23656
 
+   Hawthorne, NY  10532
23657
 
+   US
23658
 
+
23659
 
+   Phone: +1 914 784 7941
23660
 
+   EMail: leiba@watson.ibm.com
23661
 
+
23662
 
+
23663
 
+
23664
 
+
23665
 
+
23666
 
+
23667
 
+
23668
 
+
23669
 
+
23670
 
+
23671
 
+
23672
 
+
23673
 
+
23674
 
+
23675
 
+
23676
 
+
23677
 
+
23678
 
+
23679
 
+
23680
 
+
23681
 
+
23682
 
+
23683
 
+
23684
 
+
23685
 
+
23686
 
+
23687
 
+
23688
 
+
23689
 
+
23690
 
+
23691
 
+
23692
 
+Segmuller & Leiba           Standards Track                     [Page 8]
23693
 
+
23694
 
+RFC 5231              Sieve: Relational Extension           January 2008
23695
 
+
23696
 
+
23697
 
+Full Copyright Statement
23698
 
+
23699
 
+   Copyright (C) The IETF Trust (2008).
23700
 
+
23701
 
+   This document is subject to the rights, licenses and restrictions
23702
 
+   contained in BCP 78, and except as set forth therein, the authors
23703
 
+   retain all their rights.
23704
 
+
23705
 
+   This document and the information contained herein are provided on an
23706
 
+   "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS
23707
 
+   OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY, THE IETF TRUST AND
23708
 
+   THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS
23709
 
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF
23710
 
+   THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
23711
 
+   WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
23712
 
+
23713
 
+Intellectual Property
23714
 
+
23715
 
+   The IETF takes no position regarding the validity or scope of any
23716
 
+   Intellectual Property Rights or other rights that might be claimed to
23717
 
+   pertain to the implementation or use of the technology described in
23718
 
+   this document or the extent to which any license under such rights
23719
 
+   might or might not be available; nor does it represent that it has
23720
 
+   made any independent effort to identify any such rights.  Information
23721
 
+   on the procedures with respect to rights in RFC documents can be
23722
 
+   found in BCP 78 and BCP 79.
23723
 
+
23724
 
+   Copies of IPR disclosures made to the IETF Secretariat and any
23725
 
+   assurances of licenses to be made available, or the result of an
23726
 
+   attempt made to obtain a general license or permission for the use of
23727
 
+   such proprietary rights by implementers or users of this
23728
 
+   specification can be obtained from the IETF on-line IPR repository at
23729
 
+   http://www.ietf.org/ipr.
23730
 
+
23731
 
+   The IETF invites any interested party to bring to its attention any
23732
 
+   copyrights, patents or patent applications, or other proprietary
23733
 
+   rights that may cover technology that may be required to implement
23734
 
+   this standard.  Please address the information to the IETF at
23735
 
+   ietf-ipr@ietf.org.
23736
 
+
23737
 
+
23738
 
+
23739
 
+
23740
 
+
23741
 
+
23742
 
+
23743
 
+
23744
 
+
23745
 
+
23746
 
+
23747
 
+
23748
 
+Segmuller & Leiba           Standards Track                     [Page 9]
23749
 
+
23750
 
diff -urN dovecot-1.2.4/dovecot-libsieve/doc/rfc/RFC-questions.txt dovecot-1.2.4.debian/dovecot-libsieve/doc/rfc/RFC-questions.txt
23751
 
--- dovecot-1.2.4/dovecot-libsieve/doc/rfc/RFC-questions.txt    1970-01-01 01:00:00.000000000 +0100
23752
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/doc/rfc/RFC-questions.txt     2008-10-20 01:35:49.000000000 +0200
23753
 
@@ -0,0 +1,46 @@
23754
 
+Date: Sun, 19 Oct 2008 12:31:58 +0200
23755
 
+From: Stephan Bosch <stephan@rename-it.nl>
23756
 
+To: ietf-mta-filters@imc.org
23757
 
+Subject: Questions regarding RFC 5228
23758
 
+Content-Type: text/plain; charset=ISO-8859-1; format=flowed
23759
 
+Content-Transfer-Encoding: 7bit
23760
 
+
23761
 
+Hello,
23762
 
+
23763
 
+I am finishing up a first release of my Sieve implementation, and one of 
23764
 
+the TODO items that yet remains is getting some answers to questions 
23765
 
+that arose during development. I've collected these into a file an now I 
23766
 
+submit them to this list to get some clarification. Any help is greatly 
23767
 
+appreciated.
23768
 
+
23769
 
+* RFC 5228 (Sieve) : 5.1.  Test address:
23770
 
+"Implementations MUST restrict the address test to headers that contain 
23771
 
+addresses, but MUST include at least From, To, Cc, Bcc, Sender, 
23772
 
+Resent-From, and Resent-To, and it SHOULD include any other header that 
23773
 
+utilizes an "address-list" structured header body."
23774
 
+   
23775
 
+  -> Will this cause a compile error, or are the disallowed headers 
23776
 
+simply ignored? My implementation currently considers this to be a 
23777
 
+compile error.
23778
 
+  -> Given the variables extension, sometimes the specified header names 
23779
 
+aren't known until runtime. If the previous answer was to cause a 
23780
 
+compile error, should this abort the script at runtime?
23781
 
+    
23782
 
+* RFC 5228 (Sieve) : 5.4.  Test envelope:
23783
 
+"The "envelope" test is true if the specified part of the [SMTP] (or 
23784
 
+equivalent) envelope matches the specified key.  This specification 
23785
 
+defines the interpretation of the (case insensitive) "from" and "to" 
23786
 
+envelope-parts.  Additional envelope-parts may be defined by other 
23787
 
+extensions; implementations SHOULD consider unknown envelope parts an 
23788
 
+error."
23789
 
+   
23790
 
+  -> Given the variables extension, sometimes the specified envelope 
23791
 
+parts aren't known until runtime. Should invalid ones abort the script 
23792
 
+or is ignoring them a better practice?
23793
 
+
23794
 
+Regards,
23795
 
+
23796
 
+--
23797
 
+Stephan Bosch
23798
 
+stephan@rename-it.nl
23799
 
+
23800
 
diff -urN dovecot-1.2.4/dovecot-libsieve/doc/rfc/sieve.rfc5228.txt dovecot-1.2.4.debian/dovecot-libsieve/doc/rfc/sieve.rfc5228.txt
23801
 
--- dovecot-1.2.4/dovecot-libsieve/doc/rfc/sieve.rfc5228.txt    1970-01-01 01:00:00.000000000 +0100
23802
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/doc/rfc/sieve.rfc5228.txt     2008-07-18 12:11:28.000000000 +0200
23803
 
@@ -0,0 +1,2355 @@
23804
 
+
23805
 
+
23806
 
+
23807
 
+
23808
 
+
23809
 
+
23810
 
+Network Working Group                                   P. Guenther, Ed.
23811
 
+Request for Comments: 5228                                Sendmail, Inc.
23812
 
+Obsoletes: 3028                                        T. Showalter, Ed.
23813
 
+Category: Standards Track                                   January 2008
23814
 
+
23815
 
+
23816
 
+                   Sieve: An Email Filtering Language
23817
 
+
23818
 
+Status of This Memo
23819
 
+
23820
 
+   This document specifies an Internet standards track protocol for the
23821
 
+   Internet community, and requests discussion and suggestions for
23822
 
+   improvements.  Please refer to the current edition of the "Internet
23823
 
+   Official Protocol Standards" (STD 1) for the standardization state
23824
 
+   and status of this protocol.  Distribution of this memo is unlimited.
23825
 
+
23826
 
+Abstract
23827
 
+
23828
 
+   This document describes a language for filtering email messages at
23829
 
+   time of final delivery.  It is designed to be implementable on either
23830
 
+   a mail client or mail server.  It is meant to be extensible, simple,
23831
 
+   and independent of access protocol, mail architecture, and operating
23832
 
+   system.  It is suitable for running on a mail server where users may
23833
 
+   not be allowed to execute arbitrary programs, such as on black box
23834
 
+   Internet Message Access Protocol (IMAP) servers, as the base language
23835
 
+   has no variables, loops, or ability to shell out to external
23836
 
+   programs.
23837
 
+
23838
 
+
23839
 
+
23840
 
+
23841
 
+
23842
 
+
23843
 
+
23844
 
+
23845
 
+
23846
 
+
23847
 
+
23848
 
+
23849
 
+
23850
 
+
23851
 
+
23852
 
+
23853
 
+
23854
 
+
23855
 
+
23856
 
+
23857
 
+
23858
 
+
23859
 
+
23860
 
+
23861
 
+Guenther & Showalter        Standards Track                     [Page 1]
23862
 
+
23863
 
+RFC 5228           Sieve: An Email Filtering Language       January 2008
23864
 
+
23865
 
+
23866
 
+Table of Contents
23867
 
+
23868
 
+   1. Introduction ....................................................4
23869
 
+      1.1. Conventions Used in This Document ..........................4
23870
 
+      1.2. Example Mail Messages ......................................5
23871
 
+   2. Design ..........................................................6
23872
 
+      2.1. Form of the Language .......................................6
23873
 
+      2.2. Whitespace .................................................7
23874
 
+      2.3. Comments ...................................................7
23875
 
+      2.4. Literal Data ...............................................7
23876
 
+           2.4.1. Numbers .............................................7
23877
 
+           2.4.2. Strings .............................................8
23878
 
+                  2.4.2.1. String Lists ...............................9
23879
 
+                  2.4.2.2. Headers ....................................9
23880
 
+                  2.4.2.3. Addresses .................................10
23881
 
+                  2.4.2.4. Encoding Characters Using
23882
 
+                           "encoded-character" .......................10
23883
 
+      2.5. Tests .....................................................11
23884
 
+           2.5.1. Test Lists .........................................12
23885
 
+      2.6. Arguments .................................................12
23886
 
+           2.6.1. Positional Arguments ...............................12
23887
 
+           2.6.2. Tagged Arguments ...................................12
23888
 
+           2.6.3. Optional Arguments .................................13
23889
 
+           2.6.4. Types of Arguments .................................13
23890
 
+      2.7. String Comparison .........................................13
23891
 
+           2.7.1. Match Type .........................................14
23892
 
+           2.7.2. Comparisons across Character Sets ..................15
23893
 
+           2.7.3. Comparators ........................................15
23894
 
+           2.7.4. Comparisons against Addresses ......................16
23895
 
+      2.8. Blocks ....................................................17
23896
 
+      2.9. Commands ..................................................17
23897
 
+      2.10. Evaluation ...............................................18
23898
 
+           2.10.1. Action Interaction ................................18
23899
 
+           2.10.2. Implicit Keep .....................................18
23900
 
+           2.10.3. Message Uniqueness in a Mailbox ...................19
23901
 
+           2.10.4. Limits on Numbers of Actions ......................19
23902
 
+           2.10.5. Extensions and Optional Features ..................19
23903
 
+           2.10.6. Errors ............................................20
23904
 
+           2.10.7. Limits on Execution ...............................20
23905
 
+   3. Control Commands ...............................................21
23906
 
+      3.1. Control if ................................................21
23907
 
+      3.2. Control require ...........................................22
23908
 
+      3.3. Control stop ..............................................22
23909
 
+   4. Action Commands ................................................23
23910
 
+      4.1. Action fileinto ...........................................23
23911
 
+      4.2. Action redirect ...........................................23
23912
 
+      4.3. Action keep ...............................................24
23913
 
+      4.4. Action discard ............................................25
23914
 
+
23915
 
+
23916
 
+
23917
 
+Guenther & Showalter        Standards Track                     [Page 2]
23918
 
+
23919
 
+RFC 5228           Sieve: An Email Filtering Language       January 2008
23920
 
+
23921
 
+
23922
 
+   5. Test Commands ..................................................26
23923
 
+      5.1. Test address ..............................................26
23924
 
+      5.2. Test allof ................................................27
23925
 
+      5.3. Test anyof ................................................27
23926
 
+      5.4. Test envelope .............................................27
23927
 
+      5.5. Test exists ...............................................28
23928
 
+      5.6. Test false ................................................28
23929
 
+      5.7. Test header ...............................................29
23930
 
+      5.8. Test not ..................................................29
23931
 
+      5.9. Test size .................................................29
23932
 
+      5.10. Test true ................................................30
23933
 
+   6. Extensibility ..................................................30
23934
 
+      6.1. Capability String .........................................31
23935
 
+      6.2. IANA Considerations .......................................31
23936
 
+           6.2.1. Template for Capability Registrations ..............32
23937
 
+           6.2.2. Handling of Existing Capability Registrations ......32
23938
 
+           6.2.3. Initial Capability Registrations ...................32
23939
 
+      6.3. Capability Transport ......................................33
23940
 
+   7. Transmission ...................................................33
23941
 
+   8. Parsing ........................................................34
23942
 
+      8.1. Lexical Tokens ............................................34
23943
 
+      8.2. Grammar ...................................................36
23944
 
+      8.3. Statement Elements ........................................36
23945
 
+   9. Extended Example ...............................................37
23946
 
+   10. Security Considerations .......................................38
23947
 
+   11. Acknowledgments ...............................................39
23948
 
+   12. Normative References ..........................................39
23949
 
+   13. Informative References ........................................40
23950
 
+   14. Changes from RFC 3028 .........................................41
23951
 
+
23952
 
+
23953
 
+
23954
 
+
23955
 
+
23956
 
+
23957
 
+
23958
 
+
23959
 
+
23960
 
+
23961
 
+
23962
 
+
23963
 
+
23964
 
+
23965
 
+
23966
 
+
23967
 
+
23968
 
+
23969
 
+
23970
 
+
23971
 
+
23972
 
+
23973
 
+Guenther & Showalter        Standards Track                     [Page 3]
23974
 
+
23975
 
+RFC 5228           Sieve: An Email Filtering Language       January 2008
23976
 
+
23977
 
+
23978
 
+1.  Introduction
23979
 
+
23980
 
+   This memo documents a language that can be used to create filters for
23981
 
+   electronic mail.  It is not tied to any particular operating system
23982
 
+   or mail architecture.  It requires the use of [IMAIL]-compliant
23983
 
+   messages, but should otherwise generalize to many systems.
23984
 
+
23985
 
+   The language is powerful enough to be useful but limited in order to
23986
 
+   allow for a safe server-side filtering system.  The intention is to
23987
 
+   make it impossible for users to do anything more complex (and
23988
 
+   dangerous) than write simple mail filters, along with facilitating
23989
 
+   the use of graphical user interfaces (GUIs) for filter creation and
23990
 
+   manipulation.  The base language was not designed to be Turing-
23991
 
+   complete: it does not have a loop control structure or functions.
23992
 
+
23993
 
+   Scripts written in Sieve are executed during final delivery, when the
23994
 
+   message is moved to the user-accessible mailbox.  In systems where
23995
 
+   the Mail Transfer Agent (MTA) does final delivery, such as
23996
 
+   traditional Unix mail, it is reasonable to filter when the MTA
23997
 
+   deposits mail into the user's mailbox.
23998
 
+
23999
 
+   There are a number of reasons to use a filtering system.  Mail
24000
 
+   traffic for most users has been increasing due to increased usage of
24001
 
+   email, the emergence of unsolicited email as a form of advertising,
24002
 
+   and increased usage of mailing lists.
24003
 
+
24004
 
+   Experience at Carnegie Mellon has shown that if a filtering system is
24005
 
+   made available to users, many will make use of it in order to file
24006
 
+   messages from specific users or mailing lists.  However, many others
24007
 
+   did not make use of the Andrew system's FLAMES filtering language
24008
 
+   [FLAMES] due to difficulty in setting it up.
24009
 
+
24010
 
+   Because of the expectation that users will make use of filtering if
24011
 
+   it is offered and easy to use, this language has been made simple
24012
 
+   enough to allow many users to make use of it, but rich enough that it
24013
 
+   can be used productively.  However, it is expected that GUI-based
24014
 
+   editors will be the preferred way of editing filters for a large
24015
 
+   number of users.
24016
 
+
24017
 
+1.1.  Conventions Used in This Document
24018
 
+
24019
 
+   In the sections of this document that discuss the requirements of
24020
 
+   various keywords and operators, the following conventions have been
24021
 
+   adopted.
24022
 
+
24023
 
+   The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
24024
 
+   "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
24025
 
+   document are to be interpreted as described in [KEYWORDS].
24026
 
+
24027
 
+
24028
 
+
24029
 
+Guenther & Showalter        Standards Track                     [Page 4]
24030
 
+
24031
 
+RFC 5228           Sieve: An Email Filtering Language       January 2008
24032
 
+
24033
 
+
24034
 
+   Each section on a command (test, action, or control) has a line
24035
 
+   labeled "Usage:".  This line describes the usage of the command,
24036
 
+   including its name and its arguments.  Required arguments are listed
24037
 
+   inside angle brackets ("<" and ">").  Optional arguments are listed
24038
 
+   inside square brackets ("[" and "]").  Each argument is followed by
24039
 
+   its type, so "<key: string>" represents an argument called "key" that
24040
 
+   is a string.  Literal strings are represented with double-quoted
24041
 
+   strings.  Alternatives are separated with slashes, and parentheses
24042
 
+   are used for grouping, similar to [ABNF].
24043
 
+
24044
 
+   In the "Usage:" line, there are three special pieces of syntax that
24045
 
+   are frequently repeated, MATCH-TYPE, COMPARATOR, and ADDRESS-PART.
24046
 
+   These are discussed in sections 2.7.1, 2.7.3, and 2.7.4,
24047
 
+   respectively.
24048
 
+
24049
 
+   The formal grammar for these commands is defined in section 8 and is
24050
 
+   the authoritative reference on how to construct commands, but the
24051
 
+   formal grammar does not specify the order, semantics, number or types
24052
 
+   of arguments to commands, or the legal command names.  The intent is
24053
 
+   to allow for extension without changing the grammar.
24054
 
+
24055
 
+1.2.  Example Mail Messages
24056
 
+
24057
 
+   The following mail messages will be used throughout this document in
24058
 
+   examples.
24059
 
+
24060
 
+   Message A
24061
 
+   -----------------------------------------------------------
24062
 
+   Date: Tue, 1 Apr 1997 09:06:31 -0800 (PST)
24063
 
+   From: coyote@desert.example.org
24064
 
+   To: roadrunner@acme.example.com
24065
 
+   Subject: I have a present for you
24066
 
+
24067
 
+   Look, I'm sorry about the whole anvil thing, and I really
24068
 
+   didn't mean to try and drop it on you from the top of the
24069
 
+   cliff.  I want to try to make it up to you.  I've got some
24070
 
+   great birdseed over here at my place--top of the line
24071
 
+   stuff--and if you come by, I'll have it all wrapped up
24072
 
+   for you.  I'm really sorry for all the problems I've caused
24073
 
+   for you over the years, but I know we can work this out.
24074
 
+   --
24075
 
+   Wile E. Coyote   "Super Genius"   coyote@desert.example.org
24076
 
+   -----------------------------------------------------------
24077
 
+
24078
 
+
24079
 
+
24080
 
+
24081
 
+
24082
 
+
24083
 
+
24084
 
+
24085
 
+Guenther & Showalter        Standards Track                     [Page 5]
24086
 
+
24087
 
+RFC 5228           Sieve: An Email Filtering Language       January 2008
24088
 
+
24089
 
+
24090
 
+   Message B
24091
 
+   -----------------------------------------------------------
24092
 
+   From: youcouldberich!@reply-by-postal-mail.invalid
24093
 
+   Sender: b1ff@de.res.example.com
24094
 
+   To: rube@landru.example.com
24095
 
+   Date:  Mon, 31 Mar 1997 18:26:10 -0800
24096
 
+   Subject: $$$ YOU, TOO, CAN BE A MILLIONAIRE! $$$
24097
 
+
24098
 
+   YOU MAY HAVE ALREADY WON TEN MILLION DOLLARS, BUT I DOUBT
24099
 
+   IT!  SO JUST POST THIS TO SIX HUNDRED NEWSGROUPS!  IT WILL
24100
 
+   GUARANTEE THAT YOU GET AT LEAST FIVE RESPONSES WITH MONEY!
24101
 
+   MONEY! MONEY! COLD HARD CASH!  YOU WILL RECEIVE OVER
24102
 
+   $20,000 IN LESS THAN TWO MONTHS!  AND IT'S LEGAL!!!!!!!!!
24103
 
+   !!!!!!!!!!!!!!!!!!111111111!!!!!!!11111111111!!1  JUST
24104
 
+   SEND $5 IN SMALL, UNMARKED BILLS TO THE ADDRESSES BELOW!
24105
 
+   -----------------------------------------------------------
24106
 
+
24107
 
+2.  Design
24108
 
+
24109
 
+2.1.  Form of the Language
24110
 
+
24111
 
+   The language consists of a set of commands.  Each command consists of
24112
 
+   a set of tokens delimited by whitespace.  The command identifier is
24113
 
+   the first token and it is followed by zero or more argument tokens.
24114
 
+   Arguments may be literal data, tags, blocks of commands, or test
24115
 
+   commands.
24116
 
+
24117
 
+   With the exceptions of strings and comments, the language is limited
24118
 
+   to US-ASCII characters.  Strings and comments may contain octets
24119
 
+   outside the US-ASCII range.  Specifically, they will normally be in
24120
 
+   UTF-8, as specified in [UTF-8].  NUL (US-ASCII 0) is never permitted
24121
 
+   in scripts, while CR and LF can only appear as the CRLF line ending.
24122
 
+
24123
 
+      Note: While this specification permits arbitrary octets to appear
24124
 
+      in Sieve scripts inside strings and comments, this has made it
24125
 
+      difficult to robustly handle Sieve scripts in programs that are
24126
 
+      sensitive to the encodings used.  The "encoded-character"
24127
 
+      capability (section 2.4.2.4) provides an alternative means of
24128
 
+      representing such octets in strings using just US-ASCII
24129
 
+      characters.  As such, the use of non-UTF-8 text in scripts should
24130
 
+      be considered a deprecated feature that may be abandoned.
24131
 
+
24132
 
+   Tokens other than strings are considered case-insensitive.
24133
 
+
24134
 
+
24135
 
+
24136
 
+
24137
 
+
24138
 
+
24139
 
+
24140
 
+
24141
 
+Guenther & Showalter        Standards Track                     [Page 6]
24142
 
+
24143
 
+RFC 5228           Sieve: An Email Filtering Language       January 2008
24144
 
+
24145
 
+
24146
 
+2.2.  Whitespace
24147
 
+
24148
 
+   Whitespace is used to separate tokens.  Whitespace is made up of
24149
 
+   tabs, newlines (CRLF, never just CR or LF), and the space character.
24150
 
+   The amount of whitespace used is not significant.
24151
 
+
24152
 
+2.3.  Comments
24153
 
+
24154
 
+   Two types of comments are offered.  Comments are semantically
24155
 
+   equivalent to whitespace and can be used anyplace that whitespace is
24156
 
+   (with one exception in multi-line strings, as described in the
24157
 
+   grammar).
24158
 
+
24159
 
+   Hash comments begin with a "#" character that is not contained within
24160
 
+   a string and continue until the next CRLF.
24161
 
+
24162
 
+   Example:  if size :over 100k { # this is a comment
24163
 
+                discard;
24164
 
+             }
24165
 
+
24166
 
+   Bracketed comments begin with the token "/*" and end with "*/"
24167
 
+   outside of a string.  Bracketed comments may span multiple lines.
24168
 
+   Bracketed comments do not nest.
24169
 
+
24170
 
+   Example:  if size :over 100K { /* this is a comment
24171
 
+                this is still a comment */ discard /* this is a comment
24172
 
+                */ ;
24173
 
+             }
24174
 
+
24175
 
+2.4.  Literal Data
24176
 
+
24177
 
+   Literal data means data that is not executed, merely evaluated "as
24178
 
+   is", to be used as arguments to commands.  Literal data is limited to
24179
 
+   numbers, strings, and string lists.
24180
 
+
24181
 
+2.4.1.  Numbers
24182
 
+
24183
 
+   Numbers are given as ordinary decimal numbers.  As a shorthand for
24184
 
+   expressing larger values, such as message sizes, a suffix of "K",
24185
 
+   "M", or "G" MAY be appended to indicate a multiple of a power of two.
24186
 
+   To be comparable with the power-of-two-based versions of SI units
24187
 
+   that computers frequently use, "K" specifies kibi-, or 1,024 (2^10)
24188
 
+   times the value of the number; "M" specifies mebi-, or 1,048,576
24189
 
+   (2^20) times the value of the number; and "G" specifies gibi-, or
24190
 
+   1,073,741,824 (2^30) times the value of the number [BINARY-SI].
24191
 
+
24192
 
+
24193
 
+
24194
 
+
24195
 
+
24196
 
+
24197
 
+Guenther & Showalter        Standards Track                     [Page 7]
24198
 
+
24199
 
+RFC 5228           Sieve: An Email Filtering Language       January 2008
24200
 
+
24201
 
+
24202
 
+   Implementations MUST support integer values in the inclusive range
24203
 
+   zero to 2,147,483,647 (2^31 - 1), but MAY support larger values.
24204
 
+
24205
 
+   Only non-negative integers are permitted by this specification.
24206
 
+
24207
 
+2.4.2.  Strings
24208
 
+
24209
 
+   Scripts involve large numbers of string values as they are used for
24210
 
+   pattern matching, addresses, textual bodies, etc.  Typically, short
24211
 
+   quoted strings suffice for most uses, but a more convenient form is
24212
 
+   provided for longer strings such as bodies of messages.
24213
 
+
24214
 
+   A quoted string starts and ends with a single double quote (the <">
24215
 
+   character, US-ASCII 34).  A backslash ("\", US-ASCII 92) inside of a
24216
 
+   quoted string is followed by either another backslash or a double
24217
 
+   quote.  These two-character sequences represent a single backslash or
24218
 
+   double quote within the value, respectively.
24219
 
+
24220
 
+   Scripts SHOULD NOT escape other characters with a backslash.
24221
 
+
24222
 
+   An undefined escape sequence (such as "\a" in a context where "a" has
24223
 
+   no special meaning) is interpreted as if there were no backslash (in
24224
 
+   this case, "\a" is just "a"), though that may be changed by
24225
 
+   extensions.
24226
 
+
24227
 
+   Non-printing characters such as tabs, CRLF, and control characters
24228
 
+   are permitted in quoted strings.  Quoted strings MAY span multiple
24229
 
+   lines.  An unencoded NUL (US-ASCII 0) is not allowed in strings; see
24230
 
+   section 2.4.2.4 for how it can be encoded.
24231
 
+
24232
 
+   As message header data is converted to [UTF-8] for comparison (see
24233
 
+   section 2.7.2), most string values will use the UTF-8 encoding.
24234
 
+   However, implementations MUST accept all strings that match the
24235
 
+   grammar in section 8.  The ability to use non-UTF-8 encoded strings
24236
 
+   matches existing practice and has proven to be useful both in tests
24237
 
+   for invalid data and in arguments containing raw MIME parts for
24238
 
+   extension actions that generate outgoing messages.
24239
 
+
24240
 
+   For entering larger amounts of text, such as an email message, a
24241
 
+   multi-line form is allowed.  It starts with the keyword "text:",
24242
 
+   followed by a CRLF, and ends with the sequence of a CRLF, a single
24243
 
+   period, and another CRLF.  The CRLF before the final period is
24244
 
+   considered part of the value.  In order to allow the message to
24245
 
+   contain lines with a single dot, lines are dot-stuffed.  That is,
24246
 
+   when composing a message body, an extra '.' is added before each line
24247
 
+   that begins with a '.'.  When the server interprets the script, these
24248
 
+   extra dots are removed.  Note that a line that begins with a dot
24249
 
+   followed by a non-dot character is not interpreted as dot-stuffed;
24250
 
+
24251
 
+
24252
 
+
24253
 
+Guenther & Showalter        Standards Track                     [Page 8]
24254
 
+
24255
 
+RFC 5228           Sieve: An Email Filtering Language       January 2008
24256
 
+
24257
 
+
24258
 
+   that is, ".foo" is interpreted as ".foo".  However, because this is
24259
 
+   potentially ambiguous, scripts SHOULD be properly dot-stuffed so such
24260
 
+   lines do not appear.
24261
 
+
24262
 
+   Note that a hashed comment or whitespace may occur in between the
24263
 
+   "text:" and the CRLF, but not within the string itself.  Bracketed
24264
 
+   comments are not allowed here.
24265
 
+
24266
 
+2.4.2.1.  String Lists
24267
 
+
24268
 
+   When matching patterns, it is frequently convenient to match against
24269
 
+   groups of strings instead of single strings.  For this reason, a list
24270
 
+   of strings is allowed in many tests, implying that if the test is
24271
 
+   true using any one of the strings, then the test is true.
24272
 
+
24273
 
+   For instance, the test 'header :contains ["To", "Cc"]
24274
 
+   ["me@example.com", "me00@landru.example.com"]' is true if either a To
24275
 
+   header or Cc header of the input message contains either of the email
24276
 
+   addresses "me@example.com" or "me00@landru.example.com".
24277
 
+
24278
 
+   Conversely, in any case where a list of strings is appropriate, a
24279
 
+   single string is allowed without being a member of a list: it is
24280
 
+   equivalent to a list with a single member.  This means that the test
24281
 
+   'exists "To"' is equivalent to the test 'exists ["To"]'.
24282
 
+
24283
 
+2.4.2.2.  Headers
24284
 
+
24285
 
+   Headers are a subset of strings.  In the Internet Message
24286
 
+   Specification [IMAIL], each header line is allowed to have whitespace
24287
 
+   nearly anywhere in the line, including after the field name and
24288
 
+   before the subsequent colon.  Extra spaces between the header name
24289
 
+   and the ":" in a header field are ignored.
24290
 
+
24291
 
+   A header name never contains a colon.  The "From" header refers to a
24292
 
+   line beginning "From:" (or "From   :", etc.).  No header will match
24293
 
+   the string "From:" due to the trailing colon.
24294
 
+
24295
 
+   Similarly, no header will match a syntactically invalid header name.
24296
 
+   An implementation MUST NOT cause an error for syntactically invalid
24297
 
+   header names in tests.
24298
 
+
24299
 
+   Header lines are unfolded as described in [IMAIL] section 2.2.3.
24300
 
+   Interpretation of header data SHOULD be done according to [MIME3]
24301
 
+   section 6.2 (see section 2.7.2 below for details).
24302
 
+
24303
 
+
24304
 
+
24305
 
+
24306
 
+
24307
 
+
24308
 
+
24309
 
+Guenther & Showalter        Standards Track                     [Page 9]
24310
 
+
24311
 
+RFC 5228           Sieve: An Email Filtering Language       January 2008
24312
 
+
24313
 
+
24314
 
+2.4.2.3.  Addresses
24315
 
+
24316
 
+   A number of commands call for email addresses, which are also a
24317
 
+   subset of strings.  When these addresses are used in outbound
24318
 
+   contexts, addresses must be compliant with [IMAIL], but are further
24319
 
+   constrained within this document.  Using the symbols defined in
24320
 
+   [IMAIL], section 3, the syntax of an address is:
24321
 
+
24322
 
+   sieve-address = addr-spec                ; simple address
24323
 
+                 / phrase "<" addr-spec ">" ; name & addr-spec
24324
 
+
24325
 
+   That is, routes and group syntax are not permitted.  If multiple
24326
 
+   addresses are required, use a string list.  Named groups are not
24327
 
+   permitted.
24328
 
+
24329
 
+   It is an error for a script to execute an action with a value for use
24330
 
+   as an outbound address that doesn't match the "sieve-address" syntax.
24331
 
+
24332
 
+2.4.2.4.  Encoding Characters Using "encoded-character"
24333
 
+
24334
 
+   When the "encoded-character" extension is in effect, certain
24335
 
+   character sequences in strings are replaced by their decoded value.
24336
 
+   This happens after escape sequences are interpreted and dot-
24337
 
+   unstuffing has been done.  Implementations SHOULD support "encoded-
24338
 
+   character".
24339
 
+
24340
 
+   Arbitrary octets can be embedded in strings by using the syntax
24341
 
+   encoded-arb-octets.  The sequence is replaced by the octets with the
24342
 
+   hexadecimal values given by each hex-pair.
24343
 
+
24344
 
+   blank                = WSP / CRLF
24345
 
+   encoded-arb-octets   = "${hex:" hex-pair-seq "}"
24346
 
+   hex-pair-seq         = *blank hex-pair *(1*blank hex-pair) *blank
24347
 
+   hex-pair             = 1*2HEXDIG
24348
 
+
24349
 
+   Where WSP and HEXDIG non-terminals are defined in Appendix B.1 of
24350
 
+   [ABNF].
24351
 
+
24352
 
+   It may be inconvenient or undesirable to enter Unicode characters
24353
 
+   verbatim, and for these cases the syntax encoded-unicode-char can be
24354
 
+   used.  The sequence is replaced by the UTF-8 encoding of the
24355
 
+   specified Unicode characters, which are identified by the hexadecimal
24356
 
+   value of unicode-hex.
24357
 
+
24358
 
+   encoded-unicode-char = "${unicode:" unicode-hex-seq "}"
24359
 
+   unicode-hex-seq      = *blank unicode-hex
24360
 
+                          *(1*blank unicode-hex) *blank
24361
 
+   unicode-hex          = 1*HEXDIG
24362
 
+
24363
 
+
24364
 
+
24365
 
+Guenther & Showalter        Standards Track                    [Page 10]
24366
 
+
24367
 
+RFC 5228           Sieve: An Email Filtering Language       January 2008
24368
 
+
24369
 
+
24370
 
+   It is an error for a script to use a hexadecimal value that isn't in
24371
 
+   either the range 0 to D7FF or the range E000 to 10FFFF.  (The range
24372
 
+   D800 to DFFF is excluded as those character numbers are only used as
24373
 
+   part of the UTF-16 encoding form and are not applicable to the UTF-8
24374
 
+   encoding that the syntax here represents.)
24375
 
+
24376
 
+      Note: Implementations MUST NOT raise an error for an out-of-range
24377
 
+      Unicode value unless the sequence containing it is well-formed
24378
 
+      according to the grammar.
24379
 
+
24380
 
+   The capability string for use with the require command is "encoded-
24381
 
+   character".
24382
 
+
24383
 
+   In the following script, message B is discarded, since the specified
24384
 
+   test string is equivalent to "$$$".
24385
 
+
24386
 
+   Example:  require "encoded-character";
24387
 
+             if header :contains "Subject" "$${hex:24 24}" {
24388
 
+                discard;
24389
 
+             }
24390
 
+   The following examples demonstrate valid and invalid encodings and
24391
 
+   how they are handled:
24392
 
+
24393
 
+     "$${hex:40}"         -> "$@"
24394
 
+     "${hex: 40 }"        -> "@"
24395
 
+     "${HEX: 40}"         -> "@"
24396
 
+     "${hex:40"           -> "${hex:40"
24397
 
+     "${hex:400}"         -> "${hex:400}"
24398
 
+     "${hex:4${hex:30}}"  -> "${hex:40}"
24399
 
+     "${unicode:40}"      -> "@"
24400
 
+     "${ unicode:40}"     -> "${ unicode:40}"
24401
 
+     "${UNICODE:40}"      -> "@"
24402
 
+     "${UnICoDE:0000040}" -> "@"
24403
 
+     "${Unicode:40}"      -> "@"
24404
 
+     "${Unicode:Cool}"    -> "${Unicode:Cool}"
24405
 
+     "${unicode:200000}"  -> error
24406
 
+     "${Unicode:DF01}     -> error
24407
 
+
24408
 
+2.5.  Tests
24409
 
+
24410
 
+   Tests are given as arguments to commands in order to control their
24411
 
+   actions.  In this document, tests are given to if/elsif to decide
24412
 
+   which block of code is run.
24413
 
+
24414
 
+
24415
 
+
24416
 
+
24417
 
+
24418
 
+
24419
 
+
24420
 
+
24421
 
+Guenther & Showalter        Standards Track                    [Page 11]
24422
 
+
24423
 
+RFC 5228           Sieve: An Email Filtering Language       January 2008
24424
 
+
24425
 
+
24426
 
+2.5.1.  Test Lists
24427
 
+
24428
 
+   Some tests ("allof" and "anyof", which implement logical "and" and
24429
 
+   logical "or", respectively) may require more than a single test as an
24430
 
+   argument.  The test-list syntax element provides a way of grouping
24431
 
+   tests as a comma-separated list in parentheses.
24432
 
+
24433
 
+   Example:  if anyof (not exists ["From", "Date"],
24434
 
+                   header :contains "from" "fool@example.com") {
24435
 
+                discard;
24436
 
+             }
24437
 
+
24438
 
+2.6.  Arguments
24439
 
+
24440
 
+   In order to specify what to do, most commands take arguments.  There
24441
 
+   are three types of arguments: positional, tagged, and optional.
24442
 
+
24443
 
+   It is an error for a script, on a single command, to use conflicting
24444
 
+   arguments or to use a tagged or optional argument more than once.
24445
 
+
24446
 
+2.6.1.  Positional Arguments
24447
 
+
24448
 
+   Positional arguments are given to a command that discerns their
24449
 
+   meaning based on their order.  When a command takes positional
24450
 
+   arguments, all positional arguments must be supplied and must be in
24451
 
+   the order prescribed.
24452
 
+
24453
 
+2.6.2.  Tagged Arguments
24454
 
+
24455
 
+   This document provides for tagged arguments in the style of
24456
 
+   CommonLISP.  These are also similar to flags given to commands in
24457
 
+   most command-line systems.
24458
 
+
24459
 
+   A tagged argument is an argument for a command that begins with ":"
24460
 
+   followed by a tag naming the argument, such as ":contains".  This
24461
 
+   argument means that zero or more of the next tokens have some
24462
 
+   particular meaning depending on the argument.  These next tokens may
24463
 
+   be literal data, but they are never blocks.
24464
 
+
24465
 
+   Tagged arguments are similar to positional arguments, except that
24466
 
+   instead of the meaning being derived from the command, it is derived
24467
 
+   from the tag.
24468
 
+
24469
 
+   Tagged arguments must appear before positional arguments, but they
24470
 
+   may appear in any order with other tagged arguments.  For simplicity
24471
 
+   of the specification, this is not expressed in the syntax definitions
24472
 
+
24473
 
+
24474
 
+
24475
 
+
24476
 
+
24477
 
+Guenther & Showalter        Standards Track                    [Page 12]
24478
 
+
24479
 
+RFC 5228           Sieve: An Email Filtering Language       January 2008
24480
 
+
24481
 
+
24482
 
+   with commands, but they still may be reordered arbitrarily provided
24483
 
+   they appear before positional arguments.  Tagged arguments may be
24484
 
+   mixed with optional arguments.
24485
 
+
24486
 
+   Tagged arguments SHOULD NOT take tagged arguments as arguments.
24487
 
+
24488
 
+2.6.3.  Optional Arguments
24489
 
+
24490
 
+   Optional arguments are exactly like tagged arguments except that they
24491
 
+   may be left out, in which case a default value is implied.  Because
24492
 
+   optional arguments tend to result in shorter scripts, they have been
24493
 
+   used far more than tagged arguments.
24494
 
+
24495
 
+   One particularly noteworthy case is the ":comparator" argument, which
24496
 
+   allows the user to specify which comparator [COLLATION] will be used
24497
 
+   to compare two strings, since different languages may impose
24498
 
+   different orderings on UTF-8 [UTF-8] strings.
24499
 
+
24500
 
+2.6.4.  Types of Arguments
24501
 
+
24502
 
+   Abstractly, arguments may be literal data, tests, or blocks of
24503
 
+   commands.  In this way, an "if" control structure is merely a command
24504
 
+   that happens to take a test and a block as arguments and may execute
24505
 
+   the block of code.
24506
 
+
24507
 
+   However, this abstraction is ambiguous from a parsing standpoint.
24508
 
+
24509
 
+   The grammar in section 8.2 presents a parsable version of this:
24510
 
+   Arguments are string lists (string-lists), numbers, and tags, which
24511
 
+   may be followed by a test or a test list (test-list), which may be
24512
 
+   followed by a block of commands.  No more than one test or test list,
24513
 
+   or more than one block of commands, may be used, and commands that
24514
 
+   end with a block of commands do not end with semicolons.
24515
 
+
24516
 
+2.7.  String Comparison
24517
 
+
24518
 
+   When matching one string against another, there are a number of ways
24519
 
+   of performing the match operation.  These are accomplished with three
24520
 
+   types of matches: an exact match, a substring match, and a wildcard
24521
 
+   glob-style match.  These are described below.
24522
 
+
24523
 
+   In order to provide for matches between character sets and case
24524
 
+   insensitivity, Sieve uses the comparators defined in the Internet
24525
 
+   Application Protocol Collation Registry [COLLATION].
24526
 
+
24527
 
+
24528
 
+
24529
 
+
24530
 
+
24531
 
+
24532
 
+
24533
 
+Guenther & Showalter        Standards Track                    [Page 13]
24534
 
+
24535
 
+RFC 5228           Sieve: An Email Filtering Language       January 2008
24536
 
+
24537
 
+
24538
 
+   However, when a string represents the name of a header, the
24539
 
+   comparator is never user-specified.  Header comparisons are always
24540
 
+   done with the "i;ascii-casemap" operator, i.e., case-insensitive
24541
 
+   comparisons, because this is the way things are defined in the
24542
 
+   message specification [IMAIL].
24543
 
+
24544
 
+2.7.1.  Match Type
24545
 
+
24546
 
+   Commands that perform string comparisons may have an optional match
24547
 
+   type argument.  The three match types in this specification are
24548
 
+   ":contains", ":is", and ":matches".
24549
 
+
24550
 
+   The ":contains" match type describes a substring match.  If the value
24551
 
+   argument contains the key argument as a substring, the match is true.
24552
 
+   For instance, the string "frobnitzm" contains "frob" and "nit", but
24553
 
+   not "fbm".  The empty key ("") is contained in all values.
24554
 
+
24555
 
+   The ":is" match type describes an absolute match; if the contents of
24556
 
+   the first string are absolutely the same as the contents of the
24557
 
+   second string, they match.  Only the string "frobnitzm" is the string
24558
 
+   "frobnitzm".  The empty key ("") only ":is" matches with the empty
24559
 
+   value.
24560
 
+
24561
 
+   The ":matches" match type specifies a wildcard match using the
24562
 
+   characters "*" and "?"; the entire value must be matched.  "*"
24563
 
+   matches zero or more characters in the value and "?" matches a single
24564
 
+   character in the value, where the comparator that is used (see
24565
 
+   section 2.7.3) defines what a character is.  For example, the
24566
 
+   comparators "i;octet" and "i;ascii-casemap" define a character to be
24567
 
+   a single octet, so "?"  will always match exactly one octet when one
24568
 
+   of those comparators is in use.  In contrast, a Unicode-based
24569
 
+   comparator would define a character to be any UTF-8 octet sequence
24570
 
+   encoding one Unicode character and thus "?" may match more than one
24571
 
+   octet.  "?" and "*" may be escaped as "\\?" and "\\*" in strings to
24572
 
+   match against themselves.  The first backslash escapes the second
24573
 
+   backslash; together, they escape the "*".  This is awkward, but it is
24574
 
+   commonplace in several programming languages that use globs and
24575
 
+   regular expressions.
24576
 
+
24577
 
+   In order to specify what type of match is supposed to happen,
24578
 
+   commands that support matching take optional arguments ":matches",
24579
 
+   ":is", and ":contains".  Commands default to using ":is" matching if
24580
 
+   no match type argument is supplied.  Note that these modifiers
24581
 
+   interact with comparators; in particular, only comparators that
24582
 
+   support the "substring match" operation are suitable for matching
24583
 
+   with ":contains" or ":matches".  It is an error to use a comparator
24584
 
+   with ":contains" or ":matches" that is not compatible with it.
24585
 
+
24586
 
+
24587
 
+
24588
 
+
24589
 
+Guenther & Showalter        Standards Track                    [Page 14]
24590
 
+
24591
 
+RFC 5228           Sieve: An Email Filtering Language       January 2008
24592
 
+
24593
 
+
24594
 
+   It is an error to give more than one of these arguments to a given
24595
 
+   command.
24596
 
+
24597
 
+   For convenience, the "MATCH-TYPE" syntax element is defined here as
24598
 
+   follows:
24599
 
+
24600
 
+   Syntax:   ":is" / ":contains" / ":matches"
24601
 
+
24602
 
+2.7.2.  Comparisons across Character Sets
24603
 
+
24604
 
+   Messages may involve a number of character sets.  In order for
24605
 
+   comparisons to work across character sets, implementations SHOULD
24606
 
+   implement the following behavior:
24607
 
+
24608
 
+      Comparisons are performed on octets.  Implementations convert text
24609
 
+      from header fields in all charsets [MIME3] to Unicode, encoded as
24610
 
+      UTF-8, as input to the comparator (see section 2.7.3).
24611
 
+      Implementations MUST be capable of converting US-ASCII, ISO-8859-
24612
 
+      1, the US-ASCII subset of ISO-8859-* character sets, and UTF-8.
24613
 
+      Text that the implementation cannot convert to Unicode for any
24614
 
+      reason MAY be treated as plain US-ASCII (including any [MIME3]
24615
 
+      syntax) or processed according to local conventions.  An encoded
24616
 
+      NUL octet (character zero) SHOULD NOT cause early termination of
24617
 
+      the header content being compared against.
24618
 
+
24619
 
+   If implementations fail to support the above behavior, they MUST
24620
 
+   conform to the following:
24621
 
+
24622
 
+      No two strings can be considered equal if one contains octets
24623
 
+      greater than 127.
24624
 
+
24625
 
+2.7.3.  Comparators
24626
 
+
24627
 
+   In order to allow for language-independent, case-independent matches,
24628
 
+   the match type may be coupled with a comparator name.  The Internet
24629
 
+   Application Protocol Collation Registry [COLLATION] provides the
24630
 
+   framework for describing and naming comparators.
24631
 
+
24632
 
+   All implementations MUST support the "i;octet" comparator (simply
24633
 
+   compares octets) and the "i;ascii-casemap" comparator (which treats
24634
 
+   uppercase and lowercase characters in the US-ASCII subset of UTF-8 as
24635
 
+   the same).  If left unspecified, the default is "i;ascii-casemap".
24636
 
+
24637
 
+   Some comparators may not be usable with substring matches; that is,
24638
 
+   they may only work with ":is".  It is an error to try to use a
24639
 
+   comparator with ":matches" or ":contains" that is not compatible with
24640
 
+   it.
24641
 
+
24642
 
+
24643
 
+
24644
 
+
24645
 
+Guenther & Showalter        Standards Track                    [Page 15]
24646
 
+
24647
 
+RFC 5228           Sieve: An Email Filtering Language       January 2008
24648
 
+
24649
 
+
24650
 
+   Sieve treats a comparator result of "undefined" the same as a result
24651
 
+   of "no-match".  That is, this base specification does not provide any
24652
 
+   means to directly detect invalid comparator input.
24653
 
+
24654
 
+   A comparator is specified by the ":comparator" option with commands
24655
 
+   that support matching.  This option is followed by a string providing
24656
 
+   the name of the comparator to be used.  For convenience, the syntax
24657
 
+   of a comparator is abbreviated to "COMPARATOR", and (repeated in
24658
 
+   several tests) is as follows:
24659
 
+
24660
 
+   Syntax:   ":comparator" <comparator-name: string>
24661
 
+
24662
 
+   So in this example,
24663
 
+
24664
 
+   Example:  if header :contains :comparator "i;octet" "Subject"
24665
 
+                   "MAKE MONEY FAST" {
24666
 
+                discard;
24667
 
+             }
24668
 
+
24669
 
+   would discard any message with subjects like "You can MAKE MONEY
24670
 
+   FAST", but not "You can Make Money Fast", since the comparator used
24671
 
+   is case-sensitive.
24672
 
+
24673
 
+   Comparators other than "i;octet" and "i;ascii-casemap" must be
24674
 
+   declared with require, as they are extensions.  If a comparator
24675
 
+   declared with require is not known, it is an error, and execution
24676
 
+   fails.  If the comparator is not declared with require, it is also an
24677
 
+   error, even if the comparator is supported.  (See section 2.10.5.)
24678
 
+
24679
 
+   Both ":matches" and ":contains" match types are compatible with the
24680
 
+   "i;octet" and "i;ascii-casemap" comparators and may be used with
24681
 
+   them.
24682
 
+
24683
 
+   It is an error to give more than one of these arguments to a given
24684
 
+   command.
24685
 
+
24686
 
+2.7.4.  Comparisons against Addresses
24687
 
+
24688
 
+   Addresses are one of the most frequent things represented as strings.
24689
 
+   These are structured, and being able to compare against the local-
24690
 
+   part or the domain of an address is useful, so some tests that act
24691
 
+   exclusively on addresses take an additional optional argument that
24692
 
+   specifies what the test acts on.
24693
 
+
24694
 
+   These optional arguments are ":localpart", ":domain", and ":all",
24695
 
+   which act on the local-part (left side), the domain-part (right
24696
 
+   side), and the whole address.
24697
 
+
24698
 
+
24699
 
+
24700
 
+
24701
 
+Guenther & Showalter        Standards Track                    [Page 16]
24702
 
+
24703
 
+RFC 5228           Sieve: An Email Filtering Language       January 2008
24704
 
+
24705
 
+
24706
 
+   If an address is not syntactically valid, then it will not be matched
24707
 
+   by tests specifying ":localpart" or ":domain".
24708
 
+
24709
 
+   The kind of comparison done, such as whether or not the test done is
24710
 
+   case-insensitive, is specified as a comparator argument to the test.
24711
 
+
24712
 
+   If an optional address-part is omitted, the default is ":all".
24713
 
+
24714
 
+   It is an error to give more than one of these arguments to a given
24715
 
+   command.
24716
 
+
24717
 
+   For convenience, the "ADDRESS-PART" syntax element is defined here as
24718
 
+   follows:
24719
 
+
24720
 
+   Syntax:   ":localpart" / ":domain" / ":all"
24721
 
+
24722
 
+2.8.  Blocks
24723
 
+
24724
 
+   Blocks are sets of commands enclosed within curly braces and supplied
24725
 
+   as the final argument to a command.  Such a command is a control
24726
 
+   structure: when executed it has control over the number of times the
24727
 
+   commands in the block are executed.
24728
 
+
24729
 
+   With the commands supplied in this memo, there are no loops.  The
24730
 
+   control structures supplied--if, elsif, and else--run a block either
24731
 
+   once or not at all.
24732
 
+
24733
 
+2.9.  Commands
24734
 
+
24735
 
+   Sieve scripts are sequences of commands.  Commands can take any of
24736
 
+   the tokens above as arguments, and arguments may be either tagged or
24737
 
+   positional arguments.  Not all commands take all arguments.
24738
 
+
24739
 
+   There are three kinds of commands: test commands, action commands,
24740
 
+   and control commands.
24741
 
+
24742
 
+   The simplest is an action command.  An action command is an
24743
 
+   identifier followed by zero or more arguments, terminated by a
24744
 
+   semicolon.  Action commands do not take tests or blocks as arguments.
24745
 
+   The actions referenced in this document are:
24746
 
+
24747
 
+    - keep, to save the message in the default location
24748
 
+    - fileinto, to save the message in a specific mailbox
24749
 
+    - redirect, to forward the message to another address
24750
 
+    - discard, to silently throw away the message
24751
 
+
24752
 
+
24753
 
+
24754
 
+
24755
 
+
24756
 
+
24757
 
+Guenther & Showalter        Standards Track                    [Page 17]
24758
 
+
24759
 
+RFC 5228           Sieve: An Email Filtering Language       January 2008
24760
 
+
24761
 
+
24762
 
+   A control command is a command that affects the parsing or the flow
24763
 
+   of execution of the Sieve script in some way.  A control structure is
24764
 
+   a control command that ends with a block instead of a semicolon.
24765
 
+
24766
 
+   A test command is used as part of a control command.  It is used to
24767
 
+   specify whether or not the block of code given to the control command
24768
 
+   is executed.
24769
 
+
24770
 
+2.10.  Evaluation
24771
 
+
24772
 
+2.10.1.  Action Interaction
24773
 
+
24774
 
+   Some actions cannot be used with other actions because the result
24775
 
+   would be absurd.  These restrictions are noted throughout this memo.
24776
 
+
24777
 
+   Extension actions MUST state how they interact with actions defined
24778
 
+   in this specification.
24779
 
+
24780
 
+2.10.2.  Implicit Keep
24781
 
+
24782
 
+   Previous experience with filtering systems suggests that cases tend
24783
 
+   to be missed in scripts.  To prevent errors, Sieve has an "implicit
24784
 
+   keep".
24785
 
+
24786
 
+   An implicit keep is a keep action (see section 4.3) performed in
24787
 
+   absence of any action that cancels the implicit keep.
24788
 
+
24789
 
+   An implicit keep is performed if a message is not written to a
24790
 
+   mailbox, redirected to a new address, or explicitly thrown out.  That
24791
 
+   is, if a fileinto, a keep, a redirect, or a discard is performed, an
24792
 
+   implicit keep is not.
24793
 
+
24794
 
+   Some actions may be defined to not cancel the implicit keep.  These
24795
 
+   actions may not directly affect the delivery of a message, and are
24796
 
+   used for their side effects.  None of the actions specified in this
24797
 
+   document meet that criteria, but extension actions may.
24798
 
+
24799
 
+   For instance, with any of the short messages offered above, the
24800
 
+   following script produces no actions.
24801
 
+
24802
 
+   Example:  if size :over 500K { discard; }
24803
 
+
24804
 
+   As a result, the implicit keep is taken.
24805
 
+
24806
 
+
24807
 
+
24808
 
+
24809
 
+
24810
 
+
24811
 
+
24812
 
+
24813
 
+Guenther & Showalter        Standards Track                    [Page 18]
24814
 
+
24815
 
+RFC 5228           Sieve: An Email Filtering Language       January 2008
24816
 
+
24817
 
+
24818
 
+2.10.3.  Message Uniqueness in a Mailbox
24819
 
+
24820
 
+   Implementations SHOULD NOT deliver a message to the same mailbox more
24821
 
+   than once, even if a script explicitly asks for a message to be
24822
 
+   written to a mailbox twice.
24823
 
+
24824
 
+   The test for equality of two messages is implementation-defined.
24825
 
+
24826
 
+   If a script asks for a message to be written to a mailbox twice, it
24827
 
+   MUST NOT be treated as an error.
24828
 
+
24829
 
+2.10.4.  Limits on Numbers of Actions
24830
 
+
24831
 
+   Site policy MAY limit the number of actions taken and MAY impose
24832
 
+   restrictions on which actions can be used together.  In the event
24833
 
+   that a script hits a policy limit on the number of actions taken for
24834
 
+   a particular message, an error occurs.
24835
 
+
24836
 
+   Implementations MUST allow at least one keep or one fileinto.  If
24837
 
+   fileinto is not implemented, implementations MUST allow at least one
24838
 
+   keep.
24839
 
+
24840
 
+2.10.5.  Extensions and Optional Features
24841
 
+
24842
 
+   Because of the differing capabilities of many mail systems, several
24843
 
+   features of this specification are optional.  Before any of these
24844
 
+   extensions can be executed, they must be declared with the "require"
24845
 
+   action.
24846
 
+
24847
 
+   If an extension is not enabled with "require", implementations MUST
24848
 
+   treat it as if they did not support it at all.  This protects scripts
24849
 
+   from having their behavior altered by extensions that the script
24850
 
+   author might not have even been aware of.
24851
 
+
24852
 
+   Implementations MUST NOT execute any Sieve script test or command
24853
 
+   subsequent to "require" if one of the required extensions is
24854
 
+   unavailable.
24855
 
+
24856
 
+      Note: The reason for this restriction is that prior experiences
24857
 
+      with languages such as LISP and Tcl suggest that this is a
24858
 
+      workable way of noting that a given script uses an extension.
24859
 
+
24860
 
+   Extensions that define actions MUST state how they interact with
24861
 
+   actions discussed in the base specification.
24862
 
+
24863
 
+
24864
 
+
24865
 
+
24866
 
+
24867
 
+
24868
 
+
24869
 
+Guenther & Showalter        Standards Track                    [Page 19]
24870
 
+
24871
 
+RFC 5228           Sieve: An Email Filtering Language       January 2008
24872
 
+
24873
 
+
24874
 
+2.10.6.  Errors
24875
 
+
24876
 
+   In any programming language, there are compile-time and run-time
24877
 
+   errors.
24878
 
+
24879
 
+   Compile-time errors are ones in syntax that are detectable if a
24880
 
+   syntax check is done.
24881
 
+
24882
 
+   Run-time errors are not detectable until the script is run.  This
24883
 
+   includes transient failures like disk full conditions, but also
24884
 
+   includes issues like invalid combinations of actions.
24885
 
+
24886
 
+   When an error occurs in a Sieve script, all processing stops.
24887
 
+
24888
 
+   Implementations MAY choose to do a full parse, then evaluate the
24889
 
+   script, then do all actions.  Implementations might even go so far as
24890
 
+   to ensure that execution is atomic (either all actions are executed
24891
 
+   or none are executed).
24892
 
+
24893
 
+   Other implementations may choose to parse and run at the same time.
24894
 
+   Such implementations are simpler, but have issues with partial
24895
 
+   failure (some actions happen, others don't).
24896
 
+
24897
 
+   Implementations MUST perform syntactic, semantic, and run-time checks
24898
 
+   on code that is actually executed.  Implementations MAY perform those
24899
 
+   checks or any part of them on code that is not reached during
24900
 
+   execution.
24901
 
+
24902
 
+   When an error happens, implementations MUST notify the user that an
24903
 
+   error occurred and which actions (if any) were taken, and do an
24904
 
+   implicit keep.
24905
 
+
24906
 
+2.10.7.  Limits on Execution
24907
 
+
24908
 
+   Implementations may limit certain constructs.  However, this
24909
 
+   specification places a lower bound on some of these limits.
24910
 
+
24911
 
+   Implementations MUST support fifteen levels of nested blocks.
24912
 
+
24913
 
+   Implementations MUST support fifteen levels of nested test lists.
24914
 
+
24915
 
+
24916
 
+
24917
 
+
24918
 
+
24919
 
+
24920
 
+
24921
 
+
24922
 
+
24923
 
+
24924
 
+
24925
 
+Guenther & Showalter        Standards Track                    [Page 20]
24926
 
+
24927
 
+RFC 5228           Sieve: An Email Filtering Language       January 2008
24928
 
+
24929
 
+
24930
 
+3.  Control Commands
24931
 
+
24932
 
+   Control structures are needed to allow for multiple and conditional
24933
 
+   actions.
24934
 
+
24935
 
+3.1.  Control if
24936
 
+
24937
 
+   There are three pieces to if: "if", "elsif", and "else".  Each is
24938
 
+   actually a separate command in terms of the grammar.  However, an
24939
 
+   elsif or else MUST only follow an if or elsif.  An error occurs if
24940
 
+   these conditions are not met.
24941
 
+
24942
 
+   Usage:   if <test1: test> <block1: block>
24943
 
+
24944
 
+   Usage:   elsif <test2: test> <block2: block>
24945
 
+
24946
 
+   Usage:   else <block3: block>
24947
 
+
24948
 
+   The semantics are similar to those of any of the many other
24949
 
+   programming languages these control structures appear in.  When the
24950
 
+   interpreter sees an "if", it evaluates the test associated with it.
24951
 
+   If the test is true, it executes the block associated with it.
24952
 
+
24953
 
+   If the test of the "if" is false, it evaluates the test of the first
24954
 
+   "elsif" (if any).  If the test of "elsif" is true, it runs the
24955
 
+   elsif's block.  An elsif may be followed by an elsif, in which case,
24956
 
+   the interpreter repeats this process until it runs out of elsifs.
24957
 
+
24958
 
+   When the interpreter runs out of elsifs, there may be an "else" case.
24959
 
+   If there is, and none of the if or elsif tests were true, the
24960
 
+   interpreter runs the else's block.
24961
 
+
24962
 
+   This provides a way of performing exactly one of the blocks in the
24963
 
+   chain.
24964
 
+
24965
 
+   In the following example, both messages A and B are dropped.
24966
 
+
24967
 
+   Example:  require "fileinto";
24968
 
+             if header :contains "from" "coyote" {
24969
 
+                discard;
24970
 
+             } elsif header :contains ["subject"] ["$$$"] {
24971
 
+                discard;
24972
 
+             } else {
24973
 
+                fileinto "INBOX";
24974
 
+             }
24975
 
+
24976
 
+
24977
 
+
24978
 
+
24979
 
+
24980
 
+
24981
 
+Guenther & Showalter        Standards Track                    [Page 21]
24982
 
+
24983
 
+RFC 5228           Sieve: An Email Filtering Language       January 2008
24984
 
+
24985
 
+
24986
 
+   When the script below is run over message A, it redirects the message
24987
 
+   to acm@example.com; message B, to postmaster@example.com; any other
24988
 
+   message is redirected to field@example.com.
24989
 
+
24990
 
+   Example:  if header :contains ["From"] ["coyote"] {
24991
 
+                redirect "acm@example.com";
24992
 
+             } elsif header :contains "Subject" "$$$" {
24993
 
+                redirect "postmaster@example.com";
24994
 
+             } else {
24995
 
+                redirect "field@example.com";
24996
 
+             }
24997
 
+
24998
 
+   Note that this definition prohibits the "... else if ..." sequence
24999
 
+   used by C.  This is intentional, because this construct produces a
25000
 
+   shift-reduce conflict.
25001
 
+
25002
 
+3.2.  Control require
25003
 
+
25004
 
+   Usage:   require <capabilities: string-list>
25005
 
+
25006
 
+   The require action notes that a script makes use of a certain
25007
 
+   extension.  Such a declaration is required to use the extension, as
25008
 
+   discussed in section 2.10.5.  Multiple capabilities can be declared
25009
 
+   with a single require.
25010
 
+
25011
 
+   The require command, if present, MUST be used before anything other
25012
 
+   than a require can be used.  An error occurs if a require appears
25013
 
+   after a command other than require.
25014
 
+
25015
 
+   Example:  require ["fileinto", "reject"];
25016
 
+
25017
 
+   Example:  require "fileinto";
25018
 
+             require "vacation";
25019
 
+
25020
 
+3.3.  Control stop
25021
 
+
25022
 
+   Usage:   stop
25023
 
+
25024
 
+   The "stop" action ends all processing.  If the implicit keep has not
25025
 
+   been cancelled, then it is taken.
25026
 
+
25027
 
+
25028
 
+
25029
 
+
25030
 
+
25031
 
+
25032
 
+
25033
 
+
25034
 
+
25035
 
+
25036
 
+
25037
 
+Guenther & Showalter        Standards Track                    [Page 22]
25038
 
+
25039
 
+RFC 5228           Sieve: An Email Filtering Language       January 2008
25040
 
+
25041
 
+
25042
 
+4.  Action Commands
25043
 
+
25044
 
+   This document supplies four actions that may be taken on a message:
25045
 
+   keep, fileinto, redirect, and discard.
25046
 
+
25047
 
+   Implementations MUST support the "keep", "discard", and "redirect"
25048
 
+   actions.
25049
 
+
25050
 
+   Implementations SHOULD support "fileinto".
25051
 
+
25052
 
+   Implementations MAY limit the number of certain actions taken (see
25053
 
+   section 2.10.4).
25054
 
+
25055
 
+4.1.  Action fileinto
25056
 
+
25057
 
+   Usage:   fileinto <mailbox: string>
25058
 
+
25059
 
+   The "fileinto" action delivers the message into the specified
25060
 
+   mailbox.  Implementations SHOULD support fileinto, but in some
25061
 
+   environments this may be impossible.  Implementations MAY place
25062
 
+   restrictions on mailbox names; use of an invalid mailbox name MAY be
25063
 
+   treated as an error or result in delivery to an implementation-
25064
 
+   defined mailbox.  If the specified mailbox doesn't exist, the
25065
 
+   implementation MAY treat it as an error, create the mailbox, or
25066
 
+   deliver the message to an implementation-defined mailbox.  If the
25067
 
+   implementation uses a different encoding scheme than UTF-8 for
25068
 
+   mailbox names, it SHOULD reencode the mailbox name from UTF-8 to its
25069
 
+   encoding scheme.  For example, the Internet Message Access Protocol
25070
 
+   [IMAP] uses modified UTF-7, such that a mailbox argument of "odds &
25071
 
+   ends" would appear in IMAP as "odds &- ends".
25072
 
+
25073
 
+   The capability string for use with the require command is "fileinto".
25074
 
+
25075
 
+   In the following script, message A is filed into mailbox
25076
 
+   "INBOX.harassment".
25077
 
+
25078
 
+   Example:  require "fileinto";
25079
 
+             if header :contains ["from"] "coyote" {
25080
 
+                fileinto "INBOX.harassment";
25081
 
+             }
25082
 
+
25083
 
+4.2.  Action redirect
25084
 
+
25085
 
+   Usage:   redirect <address: string>
25086
 
+
25087
 
+   The "redirect" action is used to send the message to another user at
25088
 
+   a supplied address, as a mail forwarding feature does.  The
25089
 
+   "redirect" action makes no changes to the message body or existing
25090
 
+
25091
 
+
25092
 
+
25093
 
+Guenther & Showalter        Standards Track                    [Page 23]
25094
 
+
25095
 
+RFC 5228           Sieve: An Email Filtering Language       January 2008
25096
 
+
25097
 
+
25098
 
+   headers, but it may add new headers.  In particular, existing
25099
 
+   Received headers MUST be preserved and the count of Received headers
25100
 
+   in the outgoing message MUST be larger than the same count on the
25101
 
+   message as received by the implementation.  (An implementation that
25102
 
+   adds a Received header before processing the message does not need to
25103
 
+   add another when redirecting.)
25104
 
+
25105
 
+   The message is sent back out with the address from the redirect
25106
 
+   command as an envelope recipient.  Implementations MAY combine
25107
 
+   separate redirects for a given message into a single submission with
25108
 
+   multiple envelope recipients.  (This is not a Mail User Agent (MUA)-
25109
 
+   style forward, which creates a new message with a different sender
25110
 
+   and message ID, wrapping the old message in a new one.)
25111
 
+
25112
 
+   The envelope sender address on the outgoing message is chosen by the
25113
 
+   sieve implementation.  It MAY be copied from the message being
25114
 
+   processed.  However, if the message being processed has an empty
25115
 
+   envelope sender address the outgoing message MUST also have an empty
25116
 
+   envelope sender address.  This last requirement is imposed to prevent
25117
 
+   loops in the case where a message is redirected to an invalid address
25118
 
+   when then returns a delivery status notification that also ends up
25119
 
+   being redirected to the same invalid address.
25120
 
+
25121
 
+   A simple script can be used for redirecting all mail:
25122
 
+
25123
 
+   Example:  redirect "bart@example.com";
25124
 
+
25125
 
+   Implementations MUST take measures to implement loop control,
25126
 
+   possibly including adding headers to the message or counting Received
25127
 
+   headers as specified in section 6.2 of [SMTP].  If an implementation
25128
 
+   detects a loop, it causes an error.
25129
 
+
25130
 
+   Implementations MUST provide means of limiting the number of
25131
 
+   redirects a Sieve script can perform.  See section 10 for more
25132
 
+   details.
25133
 
+
25134
 
+   Implementations MAY ignore a redirect action silently due to policy
25135
 
+   reasons.  For example, an implementation MAY choose not to redirect
25136
 
+   to an address that is known to be undeliverable.  Any ignored
25137
 
+   redirect MUST NOT cancel the implicit keep.
25138
 
+
25139
 
+4.3.  Action keep
25140
 
+
25141
 
+   Usage:   keep
25142
 
+
25143
 
+   The "keep" action is whatever action is taken in lieu of all other
25144
 
+   actions, if no filtering happens at all; generally, this simply means
25145
 
+   to file the message into the user's main mailbox.  This command
25146
 
+
25147
 
+
25148
 
+
25149
 
+Guenther & Showalter        Standards Track                    [Page 24]
25150
 
+
25151
 
+RFC 5228           Sieve: An Email Filtering Language       January 2008
25152
 
+
25153
 
+
25154
 
+   provides a way to execute this action without needing to know the
25155
 
+   name of the user's main mailbox, providing a way to call it without
25156
 
+   needing to understand the user's setup or the underlying mail system.
25157
 
+
25158
 
+   For instance, in an implementation where the IMAP server is running
25159
 
+   scripts on behalf of the user at time of delivery, a keep command is
25160
 
+   equivalent to a fileinto "INBOX".
25161
 
+
25162
 
+   Example:  if size :under 1M { keep; } else { discard; }
25163
 
+
25164
 
+   Note that the above script is identical to the one below.
25165
 
+
25166
 
+   Example:  if not size :under 1M { discard; }
25167
 
+
25168
 
+4.4.  Action discard
25169
 
+
25170
 
+   Usage:   discard
25171
 
+
25172
 
+   Discard is used to silently throw away the message.  It does so by
25173
 
+   simply canceling the implicit keep.  If discard is used with other
25174
 
+   actions, the other actions still happen.  Discard is compatible with
25175
 
+   all other actions.  (For instance, fileinto+discard is equivalent to
25176
 
+   fileinto.)
25177
 
+
25178
 
+   Discard MUST be silent; that is, it MUST NOT return a non-delivery
25179
 
+   notification of any kind ([DSN], [MDN], or otherwise).
25180
 
+
25181
 
+   In the following script, any mail from "idiot@example.com" is thrown
25182
 
+   out.
25183
 
+
25184
 
+   Example:  if header :contains ["from"] ["idiot@example.com"] {
25185
 
+                discard;
25186
 
+             }
25187
 
+
25188
 
+   While an important part of this language, "discard" has the potential
25189
 
+   to create serious problems for users: Students who leave themselves
25190
 
+   logged in to an unattended machine in a public computer lab may find
25191
 
+   their script changed to just "discard".  In order to protect users in
25192
 
+   this situation (along with similar situations), implementations MAY
25193
 
+   keep messages destroyed by a script for an indefinite period, and MAY
25194
 
+   disallow scripts that throw out all mail.
25195
 
+
25196
 
+
25197
 
+
25198
 
+
25199
 
+
25200
 
+
25201
 
+
25202
 
+
25203
 
+
25204
 
+
25205
 
+Guenther & Showalter        Standards Track                    [Page 25]
25206
 
+
25207
 
+RFC 5228           Sieve: An Email Filtering Language       January 2008
25208
 
+
25209
 
+
25210
 
+5.  Test Commands
25211
 
+
25212
 
+   Tests are used in conditionals to decide which part(s) of the
25213
 
+   conditional to execute.
25214
 
+
25215
 
+   Implementations MUST support these tests: "address", "allof",
25216
 
+   "anyof", "exists", "false", "header", "not", "size", and "true".
25217
 
+
25218
 
+   Implementations SHOULD support the "envelope" test.
25219
 
+
25220
 
+5.1.  Test address
25221
 
+
25222
 
+   Usage:   address [COMPARATOR] [ADDRESS-PART] [MATCH-TYPE]
25223
 
+            <header-list: string-list> <key-list: string-list>
25224
 
+
25225
 
+   The "address" test matches Internet addresses in structured headers
25226
 
+   that contain addresses.  It returns true if any header contains any
25227
 
+   key in the specified part of the address, as modified by the
25228
 
+   comparator and the match keyword.  Whether there are other addresses
25229
 
+   present in the header doesn't affect this test; this test does not
25230
 
+   provide any way to determine whether an address is the only address
25231
 
+   in a header.
25232
 
+
25233
 
+   Like envelope and header, this test returns true if any combination
25234
 
+   of the header-list and key-list arguments match and returns false
25235
 
+   otherwise.
25236
 
+
25237
 
+   Internet email addresses [IMAIL] have the somewhat awkward
25238
 
+   characteristic that the local-part to the left of the at-sign is
25239
 
+   considered case sensitive, and the domain-part to the right of the
25240
 
+   at-sign is case insensitive.  The "address" command does not deal
25241
 
+   with this itself, but provides the ADDRESS-PART argument for allowing
25242
 
+   users to deal with it.
25243
 
+
25244
 
+   The address primitive never acts on the phrase part of an email
25245
 
+   address or on comments within that address.  It also never acts on
25246
 
+   group names, although it does act on the addresses within the group
25247
 
+   construct.
25248
 
+
25249
 
+   Implementations MUST restrict the address test to headers that
25250
 
+   contain addresses, but MUST include at least From, To, Cc, Bcc,
25251
 
+   Sender, Resent-From, and Resent-To, and it SHOULD include any other
25252
 
+   header that utilizes an "address-list" structured header body.
25253
 
+
25254
 
+   Example:  if address :is :all "from" "tim@example.com" {
25255
 
+                discard;
25256
 
+             }
25257
 
+
25258
 
+
25259
 
+
25260
 
+
25261
 
+Guenther & Showalter        Standards Track                    [Page 26]
25262
 
+
25263
 
+RFC 5228           Sieve: An Email Filtering Language       January 2008
25264
 
+
25265
 
+
25266
 
+5.2.  Test allof
25267
 
+
25268
 
+   Usage:   allof <tests: test-list>
25269
 
+
25270
 
+   The "allof" test performs a logical AND on the tests supplied to it.
25271
 
+
25272
 
+   Example:  allof (false, false)  =>   false
25273
 
+             allof (false, true)   =>   false
25274
 
+             allof (true,  true)   =>   true
25275
 
+
25276
 
+   The allof test takes as its argument a test-list.
25277
 
+
25278
 
+5.3.  Test anyof
25279
 
+
25280
 
+   Usage:   anyof <tests: test-list>
25281
 
+
25282
 
+   The "anyof" test performs a logical OR on the tests supplied to it.
25283
 
+
25284
 
+   Example:  anyof (false, false)  =>   false
25285
 
+             anyof (false, true)   =>   true
25286
 
+             anyof (true,  true)   =>   true
25287
 
+
25288
 
+5.4.  Test envelope
25289
 
+
25290
 
+   Usage:   envelope [COMPARATOR] [ADDRESS-PART] [MATCH-TYPE]
25291
 
+            <envelope-part: string-list> <key-list: string-list>
25292
 
+
25293
 
+   The "envelope" test is true if the specified part of the [SMTP] (or
25294
 
+   equivalent) envelope matches the specified key.  This specification
25295
 
+   defines the interpretation of the (case insensitive) "from" and "to"
25296
 
+   envelope-parts.  Additional envelope-parts may be defined by other
25297
 
+   extensions; implementations SHOULD consider unknown envelope parts an
25298
 
+   error.
25299
 
+
25300
 
+   If one of the envelope-part strings is (case insensitive) "from",
25301
 
+   then matching occurs against the FROM address used in the SMTP MAIL
25302
 
+   command.  The null reverse-path is matched against as the empty
25303
 
+   string, regardless of the ADDRESS-PART argument specified.
25304
 
+
25305
 
+   If one of the envelope-part strings is (case insensitive) "to", then
25306
 
+   matching occurs against the TO address used in the SMTP RCPT command
25307
 
+   that resulted in this message getting delivered to this user.  Note
25308
 
+   that only the most recent TO is available, and only the one relevant
25309
 
+   to this user.
25310
 
+
25311
 
+   The envelope-part is a string list and may contain more than one
25312
 
+   parameter, in which case all of the strings specified in the key-list
25313
 
+   are matched against all parts given in the envelope-part list.
25314
 
+
25315
 
+
25316
 
+
25317
 
+Guenther & Showalter        Standards Track                    [Page 27]
25318
 
+
25319
 
+RFC 5228           Sieve: An Email Filtering Language       January 2008
25320
 
+
25321
 
+
25322
 
+   Like address and header, this test returns true if any combination of
25323
 
+   the envelope-part list and key-list arguments match and returns false
25324
 
+   otherwise.
25325
 
+
25326
 
+   All tests against envelopes MUST drop source routes.
25327
 
+
25328
 
+   If the SMTP transaction involved several RCPT commands, only the data
25329
 
+   from the RCPT command that caused delivery to this user is available
25330
 
+   in the "to" part of the envelope.
25331
 
+
25332
 
+   If a protocol other than SMTP is used for message transport,
25333
 
+   implementations are expected to adapt this command appropriately.
25334
 
+
25335
 
+   The envelope command is optional.  Implementations SHOULD support it,
25336
 
+   but the necessary information may not be available in all cases.  The
25337
 
+   capability string for use with the require command is "envelope".
25338
 
+
25339
 
+   Example:  require "envelope";
25340
 
+             if envelope :all :is "from" "tim@example.com" {
25341
 
+                discard;
25342
 
+             }
25343
 
+
25344
 
+5.5.  Test exists
25345
 
+
25346
 
+   Usage:   exists <header-names: string-list>
25347
 
+
25348
 
+   The "exists" test is true if the headers listed in the header-names
25349
 
+   argument exist within the message.  All of the headers must exist or
25350
 
+   the test is false.
25351
 
+
25352
 
+   The following example throws out mail that doesn't have a From header
25353
 
+   and a Date header.
25354
 
+
25355
 
+   Example:  if not exists ["From","Date"] {
25356
 
+                discard;
25357
 
+             }
25358
 
+
25359
 
+5.6.  Test false
25360
 
+
25361
 
+   Usage:   false
25362
 
+
25363
 
+   The "false" test always evaluates to false.
25364
 
+
25365
 
+
25366
 
+
25367
 
+
25368
 
+
25369
 
+
25370
 
+
25371
 
+
25372
 
+
25373
 
+Guenther & Showalter        Standards Track                    [Page 28]
25374
 
+
25375
 
+RFC 5228           Sieve: An Email Filtering Language       January 2008
25376
 
+
25377
 
+
25378
 
+5.7.  Test header
25379
 
+
25380
 
+   Usage:   header [COMPARATOR] [MATCH-TYPE]
25381
 
+            <header-names: string-list> <key-list: string-list>
25382
 
+
25383
 
+   The "header" test evaluates to true if the value of any of the named
25384
 
+   headers, ignoring leading and trailing whitespace, matches any key.
25385
 
+   The type of match is specified by the optional match argument, which
25386
 
+   defaults to ":is" if not specified, as specified in section 2.6.
25387
 
+
25388
 
+   Like address and envelope, this test returns true if any combination
25389
 
+   of the header-names list and key-list arguments match and returns
25390
 
+   false otherwise.
25391
 
+
25392
 
+   If a header listed in the header-names argument exists, it contains
25393
 
+   the empty key ("").  However, if the named header is not present, it
25394
 
+   does not match any key, including the empty key.  So if a message
25395
 
+   contained the header
25396
 
+
25397
 
+           X-Caffeine: C8H10N4O2
25398
 
+
25399
 
+   these tests on that header evaluate as follows:
25400
 
+
25401
 
+           header :is ["X-Caffeine"] [""]         => false
25402
 
+           header :contains ["X-Caffeine"] [""]   => true
25403
 
+
25404
 
+   Testing whether a given header is either absent or doesn't contain
25405
 
+   any non-whitespace characters can be done using a negated "header"
25406
 
+   test:
25407
 
+
25408
 
+           not header :matches "Cc" "?*"
25409
 
+
25410
 
+5.8.  Test not
25411
 
+
25412
 
+   Usage:   not <test1: test>
25413
 
+
25414
 
+   The "not" test takes some other test as an argument, and yields the
25415
 
+   opposite result.  "not false" evaluates to "true" and "not true"
25416
 
+   evaluates to "false".
25417
 
+
25418
 
+5.9.  Test size
25419
 
+
25420
 
+   Usage:   size <":over" / ":under"> <limit: number>
25421
 
+
25422
 
+   The "size" test deals with the size of a message.  It takes either a
25423
 
+   tagged argument of ":over" or ":under", followed by a number
25424
 
+   representing the size of the message.
25425
 
+
25426
 
+
25427
 
+
25428
 
+
25429
 
+Guenther & Showalter        Standards Track                    [Page 29]
25430
 
+
25431
 
+RFC 5228           Sieve: An Email Filtering Language       January 2008
25432
 
+
25433
 
+
25434
 
+   If the argument is ":over", and the size of the message is greater
25435
 
+   than the number provided, the test is true; otherwise, it is false.
25436
 
+
25437
 
+   If the argument is ":under", and the size of the message is less than
25438
 
+   the number provided, the test is true; otherwise, it is false.
25439
 
+
25440
 
+   Exactly one of ":over" or ":under" must be specified, and anything
25441
 
+   else is an error.
25442
 
+
25443
 
+   The size of a message is defined to be the number of octets in the
25444
 
+   [IMAIL] representation of the message.
25445
 
+
25446
 
+   Note that for a message that is exactly 4,000 octets, the message is
25447
 
+   neither ":over" nor ":under" 4000 octets.
25448
 
+
25449
 
+5.10.  Test true
25450
 
+
25451
 
+   Usage:   true
25452
 
+
25453
 
+   The "true" test always evaluates to true.
25454
 
+
25455
 
+6.  Extensibility
25456
 
+
25457
 
+   New control commands, actions, and tests can be added to the
25458
 
+   language.  Sites must make these features known to their users; this
25459
 
+   document does not define a way to discover the list of extensions
25460
 
+   supported by the server.
25461
 
+
25462
 
+   Any extensions to this language MUST define a capability string that
25463
 
+   uniquely identifies that extension.  Capability string are case-
25464
 
+   sensitive; for example, "foo" and "FOO" are different capabilities.
25465
 
+   If a new version of an extension changes the functionality of a
25466
 
+   previously defined extension, it MUST use a different name.
25467
 
+   Extensions may register a set of related capabilities by registering
25468
 
+   just a unique prefix for them.  The "comparator-" prefix is an
25469
 
+   example of this.  The prefix MUST end with a "-" and MUST NOT overlap
25470
 
+   any existing registrations.
25471
 
+
25472
 
+   In a situation where there is a script submission protocol and an
25473
 
+   extension advertisement mechanism aware of the details of this
25474
 
+   language, scripts submitted can be checked against the mail server to
25475
 
+   prevent use of an extension that the server does not support.
25476
 
+
25477
 
+   Extensions MUST state how they interact with constraints defined in
25478
 
+   section 2.10, e.g., whether they cancel the implicit keep, and which
25479
 
+   actions they are compatible and incompatible with.  Extensions MUST
25480
 
+   NOT change the behavior of the "require" control command or alter the
25481
 
+   interpretation of the argument to the "require" control.
25482
 
+
25483
 
+
25484
 
+
25485
 
+Guenther & Showalter        Standards Track                    [Page 30]
25486
 
+
25487
 
+RFC 5228           Sieve: An Email Filtering Language       January 2008
25488
 
+
25489
 
+
25490
 
+   Extensions that can submit new email messages or otherwise generate
25491
 
+   new protocol requests MUST consider loop suppression, at least to
25492
 
+   document any security considerations.
25493
 
+
25494
 
+6.1.  Capability String
25495
 
+
25496
 
+   Capability strings are typically short strings describing what
25497
 
+   capabilities are supported by the server.
25498
 
+
25499
 
+   Capability strings beginning with "vnd." represent vendor-defined
25500
 
+   extensions.  Such extensions are not defined by Internet standards or
25501
 
+   RFCs, but are still registered with IANA in order to prevent
25502
 
+   conflicts.  Extensions starting with "vnd." SHOULD be followed by the
25503
 
+   name of the vendor and product, such as "vnd.acme.rocket-sled".
25504
 
+
25505
 
+   The following capability strings are defined by this document:
25506
 
+
25507
 
+   encoded-character The string "encoded-character" indicates that the
25508
 
+               implementation supports the interpretation of
25509
 
+               "${hex:...}" and "${unicode:...}" in strings.
25510
 
+
25511
 
+   envelope    The string "envelope" indicates that the implementation
25512
 
+               supports the "envelope" command.
25513
 
+
25514
 
+   fileinto    The string "fileinto" indicates that the implementation
25515
 
+               supports the "fileinto" command.
25516
 
+
25517
 
+   comparator- The string "comparator-elbonia" is provided if the
25518
 
+               implementation supports the "elbonia" comparator.
25519
 
+               Therefore, all implementations have at least the
25520
 
+               "comparator-i;octet" and "comparator-i;ascii-casemap"
25521
 
+               capabilities.  However, these comparators may be used
25522
 
+               without being declared with require.
25523
 
+
25524
 
+6.2.  IANA Considerations
25525
 
+
25526
 
+   In order to provide a standard set of extensions, a registry is
25527
 
+   maintained by IANA.  This registry contains both vendor-controlled
25528
 
+   capability names (beginning with "vnd.") and IETF-controlled
25529
 
+   capability names.  Vendor-controlled capability names may be
25530
 
+   registered on a first-come, first-served basis, by applying to IANA
25531
 
+   with the form in the following section.  Registration of capability
25532
 
+   prefixes that do not begin with "vnd." REQUIRES a standards track or
25533
 
+   IESG-approved experimental RFC.
25534
 
+
25535
 
+   Extensions designed for interoperable use SHOULD use IETF-controlled
25536
 
+   capability names.
25537
 
+
25538
 
+
25539
 
+
25540
 
+
25541
 
+Guenther & Showalter        Standards Track                    [Page 31]
25542
 
+
25543
 
+RFC 5228           Sieve: An Email Filtering Language       January 2008
25544
 
+
25545
 
+
25546
 
+6.2.1.  Template for Capability Registrations
25547
 
+
25548
 
+   The following template is to be used for registering new Sieve
25549
 
+   extensions with IANA.
25550
 
+
25551
 
+   To: iana@iana.org
25552
 
+   Subject: Registration of new Sieve extension
25553
 
+
25554
 
+   Capability name: [the string for use in the 'require' statement]
25555
 
+   Description:     [a brief description of what the extension adds
25556
 
+                     or changes]
25557
 
+   RFC number:      [for extensions published as RFCs]
25558
 
+   Contact address: [email and/or physical address to contact for
25559
 
+                     additional information]
25560
 
+
25561
 
+6.2.2.  Handling of Existing Capability Registrations
25562
 
+
25563
 
+   In order to bring the existing capability registrations in line with
25564
 
+   the new template, IANA has modified each as follows:
25565
 
+
25566
 
+   1. The "capability name" and "capability arguments" fields have been
25567
 
+      eliminated
25568
 
+   2. The "capability keyword" field have been renamed to "Capability
25569
 
+      name"
25570
 
+   3. An empty "Description" field has been added
25571
 
+   4. The "Standards Track/IESG-approved experimental RFC number" field
25572
 
+      has been renamed to "RFC number"
25573
 
+   5. The "Person and email address to contact for further information"
25574
 
+      field should be renamed to "Contact address"
25575
 
+
25576
 
+6.2.3.  Initial Capability Registrations
25577
 
+
25578
 
+   This RFC updates the following entries in the IANA registry for Sieve
25579
 
+   extensions.
25580
 
+
25581
 
+   Capability name: encoded-character
25582
 
+   Description:     changes the interpretation of strings to allow
25583
 
+                    arbitrary octets and Unicode characters to be
25584
 
+                    represented using US-ASCII
25585
 
+   RFC number:      RFC 5228 (Sieve base spec)
25586
 
+   Contact address: The Sieve discussion list <ietf-mta-filters@imc.org>
25587
 
+
25588
 
+   Capability name: fileinto
25589
 
+   Description:     adds the 'fileinto' action for delivering to a
25590
 
+                    mailbox other than the default
25591
 
+   RFC number:      RFC 5228 (Sieve base spec)
25592
 
+   Contact address: The Sieve discussion list <ietf-mta-filters@imc.org>
25593
 
+
25594
 
+
25595
 
+
25596
 
+
25597
 
+Guenther & Showalter        Standards Track                    [Page 32]
25598
 
+
25599
 
+RFC 5228           Sieve: An Email Filtering Language       January 2008
25600
 
+
25601
 
+
25602
 
+   Capability name: envelope
25603
 
+   Description:     adds the 'envelope' test for testing the message
25604
 
+                    transport sender and recipient address
25605
 
+   RFC number:      RFC 5228 (Sieve base spec)
25606
 
+   Contact address: The Sieve discussion list <ietf-mta-filters@imc.org>
25607
 
+
25608
 
+   Capability name: comparator-* (anything starting with "comparator-")
25609
 
+   Description:     adds the indicated comparator for use with the
25610
 
+                    :comparator argument
25611
 
+   RFC number:      RFC 5228 (Sieve base spec) and [COLLATION]
25612
 
+   Contact address: The Sieve discussion list <ietf-mta-filters@imc.org>
25613
 
+
25614
 
+6.3.  Capability Transport
25615
 
+
25616
 
+   A method of advertising which capabilities an implementation supports
25617
 
+   is difficult due to the wide range of possible implementations.  Such
25618
 
+   a mechanism, however, should have the property that the
25619
 
+   implementation can advertise the complete set of extensions that it
25620
 
+   supports.
25621
 
+
25622
 
+7.  Transmission
25623
 
+
25624
 
+   The [MIME] type for a Sieve script is "application/sieve".
25625
 
+
25626
 
+   The registration of this type for RFC 2048 requirements is updated as
25627
 
+   follows:
25628
 
+
25629
 
+    Subject: Registration of MIME media type application/sieve
25630
 
+
25631
 
+    MIME media type name: application
25632
 
+    MIME subtype name: sieve
25633
 
+    Required parameters: none
25634
 
+    Optional parameters: none
25635
 
+    Encoding considerations: Most Sieve scripts will be textual,
25636
 
+       written in UTF-8.  When non-7bit characters are used,
25637
 
+       quoted-printable is appropriate for transport systems
25638
 
+       that require 7bit encoding.
25639
 
+    Security considerations: Discussed in section 10 of this RFC.
25640
 
+    Interoperability considerations: Discussed in section 2.10.5
25641
 
+       of this RFC.
25642
 
+    Published specification: this RFC.
25643
 
+    Applications that use this media type: sieve-enabled mail
25644
 
+      servers and clients
25645
 
+    Additional information:
25646
 
+      Magic number(s):
25647
 
+      File extension(s): .siv .sieve
25648
 
+      Macintosh File Type Code(s):
25649
 
+
25650
 
+
25651
 
+
25652
 
+
25653
 
+Guenther & Showalter        Standards Track                    [Page 33]
25654
 
+
25655
 
+RFC 5228           Sieve: An Email Filtering Language       January 2008
25656
 
+
25657
 
+
25658
 
+    Person & email address to contact for further information:
25659
 
+       See the discussion list at ietf-mta-filters@imc.org.
25660
 
+    Intended usage:
25661
 
+       COMMON
25662
 
+    Author/Change controller:
25663
 
+       The SIEVE WG, delegated by the IESG.
25664
 
+
25665
 
+8.  Parsing
25666
 
+
25667
 
+   The Sieve grammar is separated into tokens and a separate grammar as
25668
 
+   most programming languages are.  Additional rules are supplied here
25669
 
+   for common arguments to various language facilities.
25670
 
+
25671
 
+8.1.  Lexical Tokens
25672
 
+
25673
 
+   Sieve scripts are encoded in UTF-8.  The following assumes a valid
25674
 
+   UTF-8 encoding; special characters in Sieve scripts are all US-ASCII.
25675
 
+
25676
 
+   The following are tokens in Sieve:
25677
 
+
25678
 
+           - identifiers
25679
 
+           - tags
25680
 
+           - numbers
25681
 
+           - quoted strings
25682
 
+           - multi-line strings
25683
 
+           - other separators
25684
 
+
25685
 
+   Identifiers, tags, and numbers are case-insensitive, while quoted
25686
 
+   strings and multi-line strings are case-sensitive.
25687
 
+
25688
 
+   Blanks, horizontal tabs, CRLFs, and comments ("whitespace") are
25689
 
+   ignored except as they separate tokens.  Some whitespace is required
25690
 
+   to separate otherwise adjacent tokens and in specific places in the
25691
 
+   multi-line strings.  CR and LF can only appear in CRLF pairs.
25692
 
+
25693
 
+   The other separators are single individual characters and are
25694
 
+   mentioned explicitly in the grammar.
25695
 
+
25696
 
+   The lexical structure of sieve is defined in the following grammar
25697
 
+   (as described in [ABNF]):
25698
 
+
25699
 
+   bracket-comment    = "/*" *not-star 1*STAR
25700
 
+                        *(not-star-slash *not-star 1*STAR) "/"
25701
 
+                          ; No */ allowed inside a comment.
25702
 
+                          ; (No * is allowed unless it is the last
25703
 
+                          ; character, or unless it is followed by a
25704
 
+                          ; character that isn't a slash.)
25705
 
+
25706
 
+
25707
 
+
25708
 
+
25709
 
+Guenther & Showalter        Standards Track                    [Page 34]
25710
 
+
25711
 
+RFC 5228           Sieve: An Email Filtering Language       January 2008
25712
 
+
25713
 
+
25714
 
+   comment            = bracket-comment / hash-comment
25715
 
+
25716
 
+   hash-comment       = "#" *octet-not-crlf CRLF
25717
 
+
25718
 
+   identifier         = (ALPHA / "_") *(ALPHA / DIGIT / "_")
25719
 
+
25720
 
+   multi-line         = "text:" *(SP / HTAB) (hash-comment / CRLF)
25721
 
+                        *(multiline-literal / multiline-dotstart)
25722
 
+                        "." CRLF
25723
 
+
25724
 
+   multiline-literal  = [ octet-not-period *octet-not-crlf ] CRLF
25725
 
+
25726
 
+   multiline-dotstart = "." 1*octet-not-crlf CRLF
25727
 
+                          ; A line containing only "." ends the
25728
 
+                          ; multi-line.  Remove a leading '.' if
25729
 
+                          ; followed by another '.'.
25730
 
+
25731
 
+   not-star           = CRLF / %x01-09 / %x0B-0C / %x0E-29 / %x2B-FF
25732
 
+                          ; either a CRLF pair, OR a single octet
25733
 
+                          ; other than NUL, CR, LF, or star
25734
 
+
25735
 
+   not-star-slash     = CRLF / %x01-09 / %x0B-0C / %x0E-29 / %x2B-2E /
25736
 
+                        %x30-FF
25737
 
+                          ; either a CRLF pair, OR a single octet
25738
 
+                          ; other than NUL, CR, LF, star, or slash
25739
 
+
25740
 
+   number             = 1*DIGIT [ QUANTIFIER ]
25741
 
+
25742
 
+   octet-not-crlf     = %x01-09 / %x0B-0C / %x0E-FF
25743
 
+                          ; a single octet other than NUL, CR, or LF
25744
 
+
25745
 
+   octet-not-period   = %x01-09 / %x0B-0C / %x0E-2D / %x2F-FF
25746
 
+                          ; a single octet other than NUL,
25747
 
+                          ; CR, LF, or period
25748
 
+
25749
 
+   octet-not-qspecial = %x01-09 / %x0B-0C / %x0E-21 / %x23-5B / %x5D-FF
25750
 
+                          ; a single octet other than NUL,
25751
 
+                          ; CR, LF, double-quote, or backslash
25752
 
+
25753
 
+   QUANTIFIER         = "K" / "M" / "G"
25754
 
+
25755
 
+   quoted-other       = "\" octet-not-qspecial
25756
 
+                          ; represents just the octet-no-qspecial
25757
 
+                          ; character.  SHOULD NOT be used
25758
 
+
25759
 
+   quoted-safe        = CRLF / octet-not-qspecial
25760
 
+                          ; either a CRLF pair, OR a single octet other
25761
 
+                          ; than NUL, CR, LF, double-quote, or backslash
25762
 
+
25763
 
+
25764
 
+
25765
 
+Guenther & Showalter        Standards Track                    [Page 35]
25766
 
+
25767
 
+RFC 5228           Sieve: An Email Filtering Language       January 2008
25768
 
+
25769
 
+
25770
 
+   quoted-special     = "\" (DQUOTE / "\")
25771
 
+                          ; represents just a double-quote or backslash
25772
 
+
25773
 
+   quoted-string      = DQUOTE quoted-text DQUOTE
25774
 
+
25775
 
+   quoted-text        = *(quoted-safe / quoted-special / quoted-other)
25776
 
+
25777
 
+   STAR               = "*"
25778
 
+
25779
 
+   tag                = ":" identifier
25780
 
+
25781
 
+   white-space        = 1*(SP / CRLF / HTAB) / comment
25782
 
+
25783
 
+8.2.  Grammar
25784
 
+
25785
 
+   The following is the grammar of Sieve after it has been lexically
25786
 
+   interpreted.  No whitespace or comments appear below.  The start
25787
 
+   symbol is "start".
25788
 
+
25789
 
+   argument     = string-list / number / tag
25790
 
+
25791
 
+   arguments    = *argument [ test / test-list ]
25792
 
+
25793
 
+   block        = "{" commands "}"
25794
 
+
25795
 
+   command      = identifier arguments (";" / block)
25796
 
+
25797
 
+   commands     = *command
25798
 
+
25799
 
+   start        = commands
25800
 
+
25801
 
+   string       = quoted-string / multi-line
25802
 
+
25803
 
+   string-list  = "[" string *("," string) "]" / string
25804
 
+                    ; if there is only a single string, the brackets
25805
 
+                    ; are optional
25806
 
+
25807
 
+   test         = identifier arguments
25808
 
+
25809
 
+   test-list    = "(" test *("," test) ")"
25810
 
+
25811
 
+8.3.  Statement Elements
25812
 
+
25813
 
+   These elements are collected from the "Syntax" sections elsewhere in
25814
 
+   this document, and are provided here in [ABNF] syntax so that they
25815
 
+   can be modified by extensions.
25816
 
+
25817
 
+   ADDRESS-PART = ":localpart" / ":domain" / ":all"
25818
 
+
25819
 
+
25820
 
+
25821
 
+Guenther & Showalter        Standards Track                    [Page 36]
25822
 
+
25823
 
+RFC 5228           Sieve: An Email Filtering Language       January 2008
25824
 
+
25825
 
+
25826
 
+   COMPARATOR   = ":comparator" string
25827
 
+
25828
 
+   MATCH-TYPE   = ":is" / ":contains" / ":matches"
25829
 
+
25830
 
+9.  Extended Example
25831
 
+
25832
 
+   The following is an extended example of a Sieve script.  Note that it
25833
 
+   does not make use of the implicit keep.
25834
 
+
25835
 
+    #
25836
 
+    # Example Sieve Filter
25837
 
+    # Declare any optional features or extension used by the script
25838
 
+    #
25839
 
+    require ["fileinto"];
25840
 
+
25841
 
+    #
25842
 
+    # Handle messages from known mailing lists
25843
 
+    # Move messages from IETF filter discussion list to filter mailbox
25844
 
+    #
25845
 
+    if header :is "Sender" "owner-ietf-mta-filters@imc.org"
25846
 
+            {
25847
 
+            fileinto "filter";  # move to "filter" mailbox
25848
 
+            }
25849
 
+    #
25850
 
+    # Keep all messages to or from people in my company
25851
 
+    #
25852
 
+    elsif address :DOMAIN :is ["From", "To"] "example.com"
25853
 
+            {
25854
 
+            keep;               # keep in "In" mailbox
25855
 
+            }
25856
 
+
25857
 
+    #
25858
 
+    # Try and catch unsolicited email.  If a message is not to me,
25859
 
+    # or it contains a subject known to be spam, file it away.
25860
 
+    #
25861
 
+    elsif anyof (NOT address :all :contains
25862
 
+                   ["To", "Cc", "Bcc"] "me@example.com",
25863
 
+                 header :matches "subject"
25864
 
+                   ["*make*money*fast*", "*university*dipl*mas*"])
25865
 
+            {
25866
 
+            fileinto "spam";   # move to "spam" mailbox
25867
 
+            }
25868
 
+    else
25869
 
+            {
25870
 
+            # Move all other (non-company) mail to "personal"
25871
 
+            # mailbox.
25872
 
+            fileinto "personal";
25873
 
+            }
25874
 
+
25875
 
+
25876
 
+
25877
 
+Guenther & Showalter        Standards Track                    [Page 37]
25878
 
+
25879
 
+RFC 5228           Sieve: An Email Filtering Language       January 2008
25880
 
+
25881
 
+
25882
 
+10.  Security Considerations
25883
 
+
25884
 
+   Users must get their mail.  It is imperative that whatever
25885
 
+   implementations use to store the user-defined filtering scripts
25886
 
+   protect them from unauthorized modification, to preserve the
25887
 
+   integrity of the mail system.  An attacker who can modify a script
25888
 
+   can cause mail to be discarded, rejected, or forwarded to an
25889
 
+   unauthorized recipient.  In addition, it's possible that Sieve
25890
 
+   scripts might expose private information, such as mailbox names, or
25891
 
+   email addresses of favored (or disfavored) correspondents.  Because
25892
 
+   of that, scripts SHOULD also be protected from unauthorized
25893
 
+   retrieval.
25894
 
+
25895
 
+   Several commands, such as "discard", "redirect", and "fileinto",
25896
 
+   allow for actions to be taken that are potentially very dangerous.
25897
 
+
25898
 
+   Use of the "redirect" command to generate notifications may easily
25899
 
+   overwhelm the target address, especially if it was not designed to
25900
 
+   handle large messages.
25901
 
+
25902
 
+   Allowing a single script to redirect to multiple destinations can be
25903
 
+   used as a means of amplifying the number of messages in an attack.
25904
 
+   Moreover, if loop detection is not properly implemented, it may be
25905
 
+   possible to set up exponentially growing message loops.  Accordingly,
25906
 
+   Sieve implementations:
25907
 
+
25908
 
+   (1) MUST implement facilities to detect and break message loops.  See
25909
 
+       section 6.2 of [SMTP] for additional information on basic loop
25910
 
+       detection strategies.
25911
 
+
25912
 
+   (2) MUST provide the means for administrators to limit the ability of
25913
 
+       users to abuse redirect.  In particular, it MUST be possible to
25914
 
+       limit the number of redirects a script can perform.
25915
 
+       Additionally, if no use cases exist for using redirect to
25916
 
+       multiple destinations, this limit SHOULD be set to 1.  Additional
25917
 
+       limits, such as the ability to restrict redirect to local users,
25918
 
+       MAY also be implemented.
25919
 
+
25920
 
+   (3) MUST provide facilities to log use of redirect in order to
25921
 
+       facilitate tracking down abuse.
25922
 
+
25923
 
+   (4) MAY use script analysis to determine whether or not a given
25924
 
+       script can be executed safely.  While the Sieve language is
25925
 
+       sufficiently complex that full analysis of all possible scripts
25926
 
+       is computationally infeasible, the majority of real-world scripts
25927
 
+       are amenable to analysis.  For example, an implementation might
25928
 
+
25929
 
+
25930
 
+
25931
 
+
25932
 
+
25933
 
+Guenther & Showalter        Standards Track                    [Page 38]
25934
 
+
25935
 
+RFC 5228           Sieve: An Email Filtering Language       January 2008
25936
 
+
25937
 
+
25938
 
+       allow scripts that it has determined are safe to run unhindered,
25939
 
+       block scripts that are potentially problematic, and subject
25940
 
+       unclassifiable scripts to additional auditing and logging.
25941
 
+
25942
 
+   Allowing redirects at all may not be appropriate in situations where
25943
 
+   email accounts are freely available and/or not trackable to a human
25944
 
+   who can be held accountable for creating message bombs or other
25945
 
+   abuse.
25946
 
+
25947
 
+   As with any filter on a message stream, if the Sieve implementation
25948
 
+   and the mail agents 'behind' Sieve in the message stream differ in
25949
 
+   their interpretation of the messages, it may be possible for an
25950
 
+   attacker to subvert the filter.  Of particular note are differences
25951
 
+   in the interpretation of malformed messages (e.g., missing or extra
25952
 
+   syntax characters) or those that exhibit corner cases (e.g., NUL
25953
 
+   octets encoded via [MIME3]).
25954
 
+
25955
 
+11.  Acknowledgments
25956
 
+
25957
 
+   This document has been revised in part based on comments and
25958
 
+   discussions that took place on and off the SIEVE mailing list.
25959
 
+   Thanks to Sharon Chisholm, Cyrus Daboo, Ned Freed, Arnt Gulbrandsen,
25960
 
+   Michael Haardt, Kjetil Torgrim Homme, Barry Leiba, Mark E. Mallett,
25961
 
+   Alexey Melnikov, Eric Rescorla, Rob Siemborski, and Nigel Swinson for
25962
 
+   reviews and suggestions.
25963
 
+
25964
 
+12.  Normative References
25965
 
+
25966
 
+   [ABNF]      Crocker, D., Ed., and P. Overell, "Augmented BNF for
25967
 
+               Syntax Specifications: ABNF", RFC 4234, October 2005.
25968
 
+
25969
 
+   [COLLATION] Newman, C., Duerst, M., and A. Gulbrandsen, "Internet
25970
 
+               Application Protocol Collation Registry", RFC 4790, March
25971
 
+               2007.
25972
 
+
25973
 
+   [IMAIL]     Resnick, P., Ed., "Internet Message Format", RFC 2822,
25974
 
+               April 2001.
25975
 
+
25976
 
+   [KEYWORDS]  Bradner, S., "Key words for use in RFCs to Indicate
25977
 
+               Requirement Levels", BCP 14, RFC 2119, March 1997.
25978
 
+
25979
 
+   [MIME]      Freed, N. and N. Borenstein, "Multipurpose Internet Mail
25980
 
+               Extensions (MIME) Part One: Format of Internet Message
25981
 
+               Bodies", RFC 2045, November 1996.
25982
 
+
25983
 
+   [MIME3]     Moore, K., "MIME (Multipurpose Internet Mail Extensions)
25984
 
+               Part Three: Message Header Extensions for Non-ASCII
25985
 
+               Text", RFC 2047, November 1996.
25986
 
+
25987
 
+
25988
 
+
25989
 
+Guenther & Showalter        Standards Track                    [Page 39]
25990
 
+
25991
 
+RFC 5228           Sieve: An Email Filtering Language       January 2008
25992
 
+
25993
 
+
25994
 
+   [SMTP]      Klensin, J., Ed., "Simple Mail Transfer Protocol", RFC
25995
 
+               2821, April 2001.
25996
 
+
25997
 
+   [UTF-8]     Yergeau, F., "UTF-8, a transformation format of ISO
25998
 
+               10646", STD 63, RFC 3629, November 2003.
25999
 
+
26000
 
+13.  Informative References
26001
 
+
26002
 
+   [BINARY-SI] "Standard IEC 60027-2: Letter symbols to be used in
26003
 
+               electrical technology - Part 2: Telecommunications and
26004
 
+               electronics", January 1999.
26005
 
+
26006
 
+   [DSN]       Moore, K. and G. Vaudreuil, "An Extensible Message Format
26007
 
+               for Delivery Status Notifications", RFC 3464, January
26008
 
+               2003.
26009
 
+
26010
 
+   [FLAMES]    Borenstein, N, and C. Thyberg, "Power, Ease of Use, and
26011
 
+               Cooperative Work in a Practical Multimedia Message
26012
 
+               System", Int. J.  of Man-Machine Studies, April, 1991.
26013
 
+               Reprinted in Computer-Supported Cooperative Work and
26014
 
+               Groupware, Saul Greenberg, editor, Harcourt Brace
26015
 
+               Jovanovich, 1991.  Reprinted in Readings in Groupware and
26016
 
+               Computer-Supported Cooperative Work, Ronald Baecker,
26017
 
+               editor, Morgan Kaufmann, 1993.
26018
 
+
26019
 
+   [IMAP]      Crispin, M., "Internet Message Access Protocol - version
26020
 
+               4rev1", RFC 3501, March 2003.
26021
 
+
26022
 
+   [MDN]       Hansen, T., Ed., and G. Vaudreuil, Ed., "Message
26023
 
+               Disposition Notification", RFC 3798, May 2004.
26024
 
+
26025
 
+   [RFC3028]   Showalter, T., "Sieve: A Mail Filtering Language", RFC
26026
 
+               3028, January 2001.
26027
 
+
26028
 
+
26029
 
+
26030
 
+
26031
 
+
26032
 
+
26033
 
+
26034
 
+
26035
 
+
26036
 
+
26037
 
+
26038
 
+
26039
 
+
26040
 
+
26041
 
+
26042
 
+
26043
 
+
26044
 
+
26045
 
+Guenther & Showalter        Standards Track                    [Page 40]
26046
 
+
26047
 
+RFC 5228           Sieve: An Email Filtering Language       January 2008
26048
 
+
26049
 
+
26050
 
+14.  Changes from RFC 3028
26051
 
+
26052
 
+   This following list is a summary of the changes that have been made
26053
 
+   in the Sieve language base specification from [RFC3028].
26054
 
+
26055
 
+    1. Removed ban on tests having side-effects
26056
 
+    2. Removed reject extension (will be specified in a separate RFC)
26057
 
+    3. Clarified description of comparators to match [COLLATION], the
26058
 
+       new base specification for them
26059
 
+    4. Require stripping of leading and trailing whitespace in "header"
26060
 
+       test
26061
 
+    5. Clarified or tightened handling of many minor items, including:
26062
 
+       - invalid [MIME3] encoding
26063
 
+       - invalid addresses in headers
26064
 
+       - invalid header field names in tests
26065
 
+       - 'undefined' comparator result
26066
 
+       - unknown envelope parts
26067
 
+       - null return-path in "envelope" test
26068
 
+    6. Capability strings are case-sensitive
26069
 
+    7. Clarified that fileinto should reencode non-ASCII mailbox
26070
 
+       names to match the mailstore's conventions
26071
 
+    8. Errors in the ABNF were corrected
26072
 
+    9. The references were updated and split into normative and
26073
 
+       informative
26074
 
+   10. Added encoded-character capability and deprecated (but did not
26075
 
+       remove) use of arbitrary binary octets in Sieve scripts.
26076
 
+   11. Updated IANA registration template, and added IANA
26077
 
+       considerations to permit capability prefix registrations.
26078
 
+   12. Added .sieve as a valid extension for Sieve scripts.
26079
 
+
26080
 
+Editors' Addresses
26081
 
+
26082
 
+   Philip Guenther
26083
 
+   Sendmail, Inc.
26084
 
+   6425 Christie St. Ste 400
26085
 
+   Emeryville, CA 94608
26086
 
+   EMail: guenther@sendmail.com
26087
 
+
26088
 
+   Tim Showalter
26089
 
+   EMail: tjs@psaux.com
26090
 
+
26091
 
+
26092
 
+
26093
 
+
26094
 
+
26095
 
+
26096
 
+
26097
 
+
26098
 
+
26099
 
+
26100
 
+
26101
 
+Guenther & Showalter        Standards Track                    [Page 41]
26102
 
+
26103
 
+RFC 5228           Sieve: An Email Filtering Language       January 2008
26104
 
+
26105
 
+
26106
 
+Full Copyright Statement
26107
 
+
26108
 
+   Copyright (C) The IETF Trust (2008).
26109
 
+
26110
 
+   This document is subject to the rights, licenses and restrictions
26111
 
+   contained in BCP 78, and except as set forth therein, the authors
26112
 
+   retain all their rights.
26113
 
+
26114
 
+   This document and the information contained herein are provided on an
26115
 
+   "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS
26116
 
+   OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY, THE IETF TRUST AND
26117
 
+   THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS
26118
 
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF
26119
 
+   THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
26120
 
+   WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
26121
 
+
26122
 
+Intellectual Property
26123
 
+
26124
 
+   The IETF takes no position regarding the validity or scope of any
26125
 
+   Intellectual Property Rights or other rights that might be claimed to
26126
 
+   pertain to the implementation or use of the technology described in
26127
 
+   this document or the extent to which any license under such rights
26128
 
+   might or might not be available; nor does it represent that it has
26129
 
+   made any independent effort to identify any such rights.  Information
26130
 
+   on the procedures with respect to rights in RFC documents can be
26131
 
+   found in BCP 78 and BCP 79.
26132
 
+
26133
 
+   Copies of IPR disclosures made to the IETF Secretariat and any
26134
 
+   assurances of licenses to be made available, or the result of an
26135
 
+   attempt made to obtain a general license or permission for the use of
26136
 
+   such proprietary rights by implementers or users of this
26137
 
+   specification can be obtained from the IETF on-line IPR repository at
26138
 
+   http://www.ietf.org/ipr.
26139
 
+
26140
 
+   The IETF invites any interested party to bring to its attention any
26141
 
+   copyrights, patents or patent applications, or other proprietary
26142
 
+   rights that may cover technology that may be required to implement
26143
 
+   this standard.  Please address the information to the IETF at
26144
 
+   ietf-ipr@ietf.org.
26145
 
+
26146
 
+
26147
 
+
26148
 
+
26149
 
+
26150
 
+
26151
 
+
26152
 
+
26153
 
+
26154
 
+
26155
 
+
26156
 
+
26157
 
+Guenther & Showalter        Standards Track                    [Page 42]
26158
 
+
26159
 
diff -urN dovecot-1.2.4/dovecot-libsieve/doc/rfc/subaddress.rfc5233.txt dovecot-1.2.4.debian/dovecot-libsieve/doc/rfc/subaddress.rfc5233.txt
26160
 
--- dovecot-1.2.4/dovecot-libsieve/doc/rfc/subaddress.rfc5233.txt       1970-01-01 01:00:00.000000000 +0100
26161
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/doc/rfc/subaddress.rfc5233.txt        2008-08-25 10:25:08.000000000 +0200
26162
 
@@ -0,0 +1,395 @@
26163
 
+
26164
 
+
26165
 
+
26166
 
+
26167
 
+
26168
 
+
26169
 
+Network Working Group                                       K. Murchison
26170
 
+Request for Comments: 5233                    Carnegie Mellon University
26171
 
+Obsoletes: 3598                                             January 2008
26172
 
+Category: Standards Track
26173
 
+
26174
 
+
26175
 
+              Sieve Email Filtering: Subaddress Extension
26176
 
+
26177
 
+Status of This Memo
26178
 
+
26179
 
+   This document specifies an Internet standards track protocol for the
26180
 
+   Internet community, and requests discussion and suggestions for
26181
 
+   improvements.  Please refer to the current edition of the "Internet
26182
 
+   Official Protocol Standards" (STD 1) for the standardization state
26183
 
+   and status of this protocol.  Distribution of this memo is unlimited.
26184
 
+
26185
 
+Abstract
26186
 
+
26187
 
+   On email systems that allow for 'subaddressing' or 'detailed
26188
 
+   addressing' (e.g., "ken+sieve@example.org"), it is sometimes
26189
 
+   desirable to make comparisons against these sub-parts of addresses.
26190
 
+   This document defines an extension to the Sieve Email Filtering
26191
 
+   Language that allows users to compare against the user and detail
26192
 
+   sub-parts of an address.
26193
 
+
26194
 
+Table of Contents
26195
 
+
26196
 
+   1. Introduction ....................................................2
26197
 
+   2. Conventions Used in This Document ...............................2
26198
 
+   3. Capability Identifier ...........................................2
26199
 
+   4. Subaddress Comparisons ..........................................2
26200
 
+   5. IANA Considerations .............................................5
26201
 
+   6. Security Considerations .........................................5
26202
 
+   7. Normative References ............................................5
26203
 
+   Appendix A. Acknowledgments ........................................6
26204
 
+   Appendix B. Changes since RFC 3598 .................................6
26205
 
+
26206
 
+
26207
 
+
26208
 
+
26209
 
+
26210
 
+
26211
 
+
26212
 
+
26213
 
+
26214
 
+
26215
 
+
26216
 
+
26217
 
+
26218
 
+
26219
 
+
26220
 
+Murchison                   Standards Track                     [Page 1]
26221
 
+
26222
 
+RFC 5233              Sieve: Subaddress Extension           January 2008
26223
 
+
26224
 
+
26225
 
+1.  Introduction
26226
 
+
26227
 
+   Subaddressing is the practice of augmenting the local-part of an
26228
 
+   [RFC2822] address with some 'detail' information in order to give
26229
 
+   some extra meaning to that address.  One common way of encoding
26230
 
+   'detail' information into the local-part is to add a 'separator
26231
 
+   character sequence', such as "+", to form a boundary between the
26232
 
+   'user' (original local-part) and 'detail' sub-parts of the address,
26233
 
+   much like the "@" character forms the boundary between the local-part
26234
 
+   and domain.
26235
 
+
26236
 
+   Typical uses of subaddressing might be:
26237
 
+
26238
 
+   o  A message addressed to "ken+sieve@example.org" is delivered into a
26239
 
+      mailbox called "sieve" belonging to the user "ken".
26240
 
+
26241
 
+   o  A message addressed to "5551212#123@example.com" is delivered to
26242
 
+      the voice mailbox number "123" at phone number "5551212".
26243
 
+
26244
 
+   This document describes an extension to the Sieve language defined by
26245
 
+   [RFC5228] for comparing against the 'user' and 'detail' sub-parts of
26246
 
+   an address.
26247
 
+
26248
 
+2.  Conventions Used in This Document
26249
 
+
26250
 
+   The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
26251
 
+   "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
26252
 
+   document are to be interpreted as described in [RFC2119].
26253
 
+
26254
 
+3.  Capability Identifier
26255
 
+
26256
 
+   The capability string associated with the extension defined in this
26257
 
+   document is "subaddress".
26258
 
+
26259
 
+4.  Subaddress Comparisons
26260
 
+
26261
 
+   Test commands that act exclusively on addresses may take the optional
26262
 
+   tagged arguments ":user" and ":detail" to specify what sub-part of
26263
 
+   the local-part of the address will be acted upon.
26264
 
+
26265
 
+      NOTE: In most cases, the envelope "to" address is the preferred
26266
 
+      address to examine for subaddress information when the desire is
26267
 
+      to sort messages based on how they were addressed so as to get to
26268
 
+      a specific recipient.  The envelope address is, after all, the
26269
 
+      reason a given message is being processed by a given sieve script
26270
 
+      for a given user.  This is particularly true when mailing lists,
26271
 
+
26272
 
+
26273
 
+
26274
 
+
26275
 
+
26276
 
+Murchison                   Standards Track                     [Page 2]
26277
 
+
26278
 
+RFC 5233              Sieve: Subaddress Extension           January 2008
26279
 
+
26280
 
+
26281
 
+      aliases, and 'virtual domains' are involved since the envelope may
26282
 
+      be the only source of detail information for the specific
26283
 
+      recipient.
26284
 
+
26285
 
+      NOTE: Because the encoding of detailed addresses are site and/or
26286
 
+      implementation specific, using the subaddress extension on foreign
26287
 
+      addresses (such as the envelope "from" address or originator
26288
 
+      header fields) may lead to inconsistent or incorrect results.
26289
 
+
26290
 
+   The ":user" argument specifies the user sub-part of the local-part of
26291
 
+   an address.  If the address is not encoded to contain a detail sub-
26292
 
+   part, then ":user" specifies the entire left side of the address
26293
 
+   (equivalent to ":localpart").
26294
 
+
26295
 
+   The ":detail" argument specifies the detail sub-part of the local-
26296
 
+   part of an address.  If the address is not encoded to contain a
26297
 
+   detail sub-part, then the address fails to match any of the specified
26298
 
+   keys.  If a zero-length string is encoded as the detail sub-part,
26299
 
+   then ":detail" resolves to the empty value ("").
26300
 
+
26301
 
+      NOTE: If the encoding method used for detailed addresses utilizes
26302
 
+      a separator character sequence, and the separator character
26303
 
+      sequence occurs more than once in the local-part, then the logic
26304
 
+      used to split the address is implementation-defined and is usually
26305
 
+      dependent on the format used by the encompassing mail system.
26306
 
+
26307
 
+   Implementations MUST make sure that the encoding method used for
26308
 
+   detailed addresses matches that which is used and/or allowed by the
26309
 
+   encompassing mail system, otherwise unexpected results might occur.
26310
 
+   Note that the mechanisms used to define and/or query the encoding
26311
 
+   method used by the mail system are outside the scope of this
26312
 
+   document.
26313
 
+
26314
 
+   The ":user" and ":detail" address parts are subject to the same rules
26315
 
+   and restrictions as the standard address parts defined in [RFC5228],
26316
 
+   Section 2.7.4.
26317
 
+
26318
 
+   For convenience, the "ADDRESS-PART" syntax element defined in
26319
 
+   [RFC5228], Section 2.7.4, is augmented here as follows:
26320
 
+
26321
 
+         ADDRESS-PART  =/  ":user" / ":detail"
26322
 
+
26323
 
+   A diagram showing the ADDRESS-PARTs of an email address where the
26324
 
+   detail information follows a separator character sequence of "+" is
26325
 
+   shown below:
26326
 
+
26327
 
+
26328
 
+
26329
 
+
26330
 
+
26331
 
+
26332
 
+Murchison                   Standards Track                     [Page 3]
26333
 
+
26334
 
+RFC 5233              Sieve: Subaddress Extension           January 2008
26335
 
+
26336
 
+
26337
 
+          :user "+" :detail  "@" :domain
26338
 
+         \-----------------/
26339
 
+             :local-part
26340
 
+
26341
 
+   A diagram showing the ADDRESS-PARTs of a email address where the
26342
 
+   detail information precedes a separator character sequence of "--" is
26343
 
+   shown below:
26344
 
+
26345
 
+          :detail "--" :user  "@" :domain
26346
 
+         \------------------/
26347
 
+             :local-part
26348
 
+
26349
 
+   Example (where the detail information follows "+"):
26350
 
+
26351
 
+      require ["envelope", "subaddress", "fileinto"];
26352
 
+
26353
 
+      # In this example the same user account receives mail for both
26354
 
+      # "ken@example.com" and "postmaster@example.com"
26355
 
+
26356
 
+      # File all messages to postmaster into a single mailbox,
26357
 
+      # ignoring the :detail part.
26358
 
+      if envelope :user "to" "postmaster" {
26359
 
+          fileinto "inbox.postmaster";
26360
 
+          stop;
26361
 
+      }
26362
 
+
26363
 
+      # File mailing list messages (subscribed as "ken+mta-filters").
26364
 
+      if envelope :detail "to" "mta-filters" {
26365
 
+          fileinto "inbox.ietf-mta-filters";
26366
 
+      }
26367
 
+
26368
 
+      # Redirect all mail sent to "ken+foo".
26369
 
+      if envelope :detail "to" "foo" {
26370
 
+          redirect "ken@example.net";
26371
 
+      }
26372
 
+
26373
 
+
26374
 
+
26375
 
+
26376
 
+
26377
 
+
26378
 
+
26379
 
+
26380
 
+
26381
 
+
26382
 
+
26383
 
+
26384
 
+
26385
 
+
26386
 
+
26387
 
+
26388
 
+Murchison                   Standards Track                     [Page 4]
26389
 
+
26390
 
+RFC 5233              Sieve: Subaddress Extension           January 2008
26391
 
+
26392
 
+
26393
 
+5.  IANA Considerations
26394
 
+
26395
 
+   The following template specifies the IANA registration of the
26396
 
+   subaddress Sieve extension specified in this document.  This
26397
 
+   registration replaces that from RFC 3598:
26398
 
+
26399
 
+   To: iana@iana.org
26400
 
+   Subject: Registration of new Sieve extension
26401
 
+
26402
 
+   Capability name: subaddress
26403
 
+   Description:     Adds the ':user' and ':detail' address parts
26404
 
+                    for use with the address and envelope tests
26405
 
+   RFC number:      RFC 5233
26406
 
+   Contact address: The Sieve discussion list <ietf-mta-filters@imc.org>
26407
 
+
26408
 
+   This information has been added to the list of Sieve extensions given
26409
 
+   on http://www.iana.org/assignments/sieve-extensions.
26410
 
+
26411
 
+6.  Security Considerations
26412
 
+
26413
 
+   Security considerations are discussed in [RFC5228].  It is believed
26414
 
+   that this extension does not introduce any additional security
26415
 
+   concerns.
26416
 
+
26417
 
+7.  Normative References
26418
 
+
26419
 
+   [RFC2119]  Bradner, S., "Key words for use in RFCs to Indicate
26420
 
+              Requirement Levels", BCP 14, RFC 2119, March 1997.
26421
 
+
26422
 
+   [RFC2822]  Resnick, P., "Internet Message Format", RFC 2822, April
26423
 
+              2001.
26424
 
+
26425
 
+   [RFC5228]  Guenther, P., Ed., and T. Showalter, Ed., "Sieve: An Email
26426
 
+              Filtering Language", RFC 5228, January 2008.
26427
 
+
26428
 
+
26429
 
+
26430
 
+
26431
 
+
26432
 
+
26433
 
+
26434
 
+
26435
 
+
26436
 
+
26437
 
+
26438
 
+
26439
 
+
26440
 
+
26441
 
+
26442
 
+
26443
 
+
26444
 
+Murchison                   Standards Track                     [Page 5]
26445
 
+
26446
 
+RFC 5233              Sieve: Subaddress Extension           January 2008
26447
 
+
26448
 
+
26449
 
+Appendix A.  Acknowledgments
26450
 
+
26451
 
+   Thanks to Tim Showalter, Alexey Melnikov, Michael Salmon, Randall
26452
 
+   Gellens, Philip Guenther, Jutta Degener, Michael Haardt, Ned Freed,
26453
 
+   Mark Mallett, and Barry Leiba for their help with this document.
26454
 
+
26455
 
+Appendix B.  Changes since RFC 3598
26456
 
+
26457
 
+   o  Discussion of how the user and detail information is encoded now
26458
 
+      uses generic language.
26459
 
+
26460
 
+   o  Added note detailing that this extension is most useful when used
26461
 
+      on the envelope "to" address.
26462
 
+
26463
 
+   o  Added note detailing that this extension isn't very useful on
26464
 
+      foreign addresses (envelope "from" or originator header fields).
26465
 
+
26466
 
+   o  Fixed envelope test example to only use "to" address.
26467
 
+
26468
 
+   o  Replaced ":user" example with one that doesn't produce unexpected
26469
 
+      behavior.
26470
 
+
26471
 
+   o  Refer to the zero-length string ("") as "empty" instead of "null"
26472
 
+      (per RFC 5228).
26473
 
+
26474
 
+   o  Use only RFC 2606 domains in examples.
26475
 
+
26476
 
+   o  Miscellaneous editorial changes.
26477
 
+
26478
 
+Author's Address
26479
 
+
26480
 
+   Kenneth Murchison
26481
 
+   Carnegie Mellon University
26482
 
+   5000 Forbes Avenue
26483
 
+   Cyert Hall 285
26484
 
+   Pittsburgh, PA  15213
26485
 
+   USA
26486
 
+
26487
 
+   Phone: +1 412 268 2638
26488
 
+   EMail: murch@andrew.cmu.edu
26489
 
+
26490
 
+
26491
 
+
26492
 
+
26493
 
+
26494
 
+
26495
 
+
26496
 
+
26497
 
+
26498
 
+
26499
 
+
26500
 
+Murchison                   Standards Track                     [Page 6]
26501
 
+
26502
 
+RFC 5233              Sieve: Subaddress Extension           January 2008
26503
 
+
26504
 
+
26505
 
+Full Copyright Statement
26506
 
+
26507
 
+   Copyright (C) The IETF Trust (2008).
26508
 
+
26509
 
+   This document is subject to the rights, licenses and restrictions
26510
 
+   contained in BCP 78, and except as set forth therein, the authors
26511
 
+   retain all their rights.
26512
 
+
26513
 
+   This document and the information contained herein are provided on an
26514
 
+   "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS
26515
 
+   OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY, THE IETF TRUST AND
26516
 
+   THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS
26517
 
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF
26518
 
+   THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
26519
 
+   WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
26520
 
+
26521
 
+Intellectual Property
26522
 
+
26523
 
+   The IETF takes no position regarding the validity or scope of any
26524
 
+   Intellectual Property Rights or other rights that might be claimed to
26525
 
+   pertain to the implementation or use of the technology described in
26526
 
+   this document or the extent to which any license under such rights
26527
 
+   might or might not be available; nor does it represent that it has
26528
 
+   made any independent effort to identify any such rights.  Information
26529
 
+   on the procedures with respect to rights in RFC documents can be
26530
 
+   found in BCP 78 and BCP 79.
26531
 
+
26532
 
+   Copies of IPR disclosures made to the IETF Secretariat and any
26533
 
+   assurances of licenses to be made available, or the result of an
26534
 
+   attempt made to obtain a general license or permission for the use of
26535
 
+   such proprietary rights by implementers or users of this
26536
 
+   specification can be obtained from the IETF on-line IPR repository at
26537
 
+   http://www.ietf.org/ipr.
26538
 
+
26539
 
+   The IETF invites any interested party to bring to its attention any
26540
 
+   copyrights, patents or patent applications, or other proprietary
26541
 
+   rights that may cover technology that may be required to implement
26542
 
+   this standard.  Please address the information to the IETF at
26543
 
+   ietf-ipr@ietf.org.
26544
 
+
26545
 
+
26546
 
+
26547
 
+
26548
 
+
26549
 
+
26550
 
+
26551
 
+
26552
 
+
26553
 
+
26554
 
+
26555
 
+
26556
 
+Murchison                   Standards Track                     [Page 7]
26557
 
+
26558
 
diff -urN dovecot-1.2.4/dovecot-libsieve/doc/rfc/uri.rfc3986.txt dovecot-1.2.4.debian/dovecot-libsieve/doc/rfc/uri.rfc3986.txt
26559
 
--- dovecot-1.2.4/dovecot-libsieve/doc/rfc/uri.rfc3986.txt      1970-01-01 01:00:00.000000000 +0100
26560
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/doc/rfc/uri.rfc3986.txt       2008-11-28 22:33:49.000000000 +0100
26561
 
@@ -0,0 +1,3419 @@
26562
 
+
26563
 
+
26564
 
+
26565
 
+
26566
 
+
26567
 
+
26568
 
+Network Working Group                                     T. Berners-Lee
26569
 
+Request for Comments: 3986                                       W3C/MIT
26570
 
+STD: 66                                                      R. Fielding
26571
 
+Updates: 1738                                               Day Software
26572
 
+Obsoletes: 2732, 2396, 1808                                  L. Masinter
26573
 
+Category: Standards Track                                  Adobe Systems
26574
 
+                                                            January 2005
26575
 
+
26576
 
+
26577
 
+           Uniform Resource Identifier (URI): Generic Syntax
26578
 
+
26579
 
+Status of This Memo
26580
 
+
26581
 
+   This document specifies an Internet standards track protocol for the
26582
 
+   Internet community, and requests discussion and suggestions for
26583
 
+   improvements.  Please refer to the current edition of the "Internet
26584
 
+   Official Protocol Standards" (STD 1) for the standardization state
26585
 
+   and status of this protocol.  Distribution of this memo is unlimited.
26586
 
+
26587
 
+Copyright Notice
26588
 
+
26589
 
+   Copyright (C) The Internet Society (2005).
26590
 
+
26591
 
+Abstract
26592
 
+
26593
 
+   A Uniform Resource Identifier (URI) is a compact sequence of
26594
 
+   characters that identifies an abstract or physical resource.  This
26595
 
+   specification defines the generic URI syntax and a process for
26596
 
+   resolving URI references that might be in relative form, along with
26597
 
+   guidelines and security considerations for the use of URIs on the
26598
 
+   Internet.  The URI syntax defines a grammar that is a superset of all
26599
 
+   valid URIs, allowing an implementation to parse the common components
26600
 
+   of a URI reference without knowing the scheme-specific requirements
26601
 
+   of every possible identifier.  This specification does not define a
26602
 
+   generative grammar for URIs; that task is performed by the individual
26603
 
+   specifications of each URI scheme.
26604
 
+
26605
 
+
26606
 
+
26607
 
+
26608
 
+
26609
 
+
26610
 
+
26611
 
+
26612
 
+
26613
 
+
26614
 
+
26615
 
+
26616
 
+
26617
 
+
26618
 
+
26619
 
+Berners-Lee, et al.         Standards Track                     [Page 1]
26620
 
+
26621
 
+RFC 3986                   URI Generic Syntax               January 2005
26622
 
+
26623
 
+
26624
 
+Table of Contents
26625
 
+
26626
 
+   1.  Introduction . . . . . . . . . . . . . . . . . . . . . . . . .  4
26627
 
+       1.1.  Overview of URIs . . . . . . . . . . . . . . . . . . . .  4
26628
 
+             1.1.1.  Generic Syntax . . . . . . . . . . . . . . . . .  6
26629
 
+             1.1.2.  Examples . . . . . . . . . . . . . . . . . . . .  7
26630
 
+             1.1.3.  URI, URL, and URN  . . . . . . . . . . . . . . .  7
26631
 
+       1.2.  Design Considerations  . . . . . . . . . . . . . . . . .  8
26632
 
+             1.2.1.  Transcription  . . . . . . . . . . . . . . . . .  8
26633
 
+             1.2.2.  Separating Identification from Interaction . . .  9
26634
 
+             1.2.3.  Hierarchical Identifiers . . . . . . . . . . . . 10
26635
 
+       1.3.  Syntax Notation  . . . . . . . . . . . . . . . . . . . . 11
26636
 
+   2.  Characters . . . . . . . . . . . . . . . . . . . . . . . . . . 11
26637
 
+       2.1.  Percent-Encoding . . . . . . . . . . . . . . . . . . . . 12
26638
 
+       2.2.  Reserved Characters  . . . . . . . . . . . . . . . . . . 12
26639
 
+       2.3.  Unreserved Characters  . . . . . . . . . . . . . . . . . 13
26640
 
+       2.4.  When to Encode or Decode . . . . . . . . . . . . . . . . 14
26641
 
+       2.5.  Identifying Data . . . . . . . . . . . . . . . . . . . . 14
26642
 
+   3.  Syntax Components  . . . . . . . . . . . . . . . . . . . . . . 16
26643
 
+       3.1.  Scheme . . . . . . . . . . . . . . . . . . . . . . . . . 17
26644
 
+       3.2.  Authority  . . . . . . . . . . . . . . . . . . . . . . . 17
26645
 
+             3.2.1.  User Information . . . . . . . . . . . . . . . . 18
26646
 
+             3.2.2.  Host . . . . . . . . . . . . . . . . . . . . . . 18
26647
 
+             3.2.3.  Port . . . . . . . . . . . . . . . . . . . . . . 22
26648
 
+       3.3.  Path . . . . . . . . . . . . . . . . . . . . . . . . . . 22
26649
 
+       3.4.  Query  . . . . . . . . . . . . . . . . . . . . . . . . . 23
26650
 
+       3.5.  Fragment . . . . . . . . . . . . . . . . . . . . . . . . 24
26651
 
+   4.  Usage  . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
26652
 
+       4.1.  URI Reference  . . . . . . . . . . . . . . . . . . . . . 25
26653
 
+       4.2.  Relative Reference . . . . . . . . . . . . . . . . . . . 26
26654
 
+       4.3.  Absolute URI . . . . . . . . . . . . . . . . . . . . . . 27
26655
 
+       4.4.  Same-Document Reference  . . . . . . . . . . . . . . . . 27
26656
 
+       4.5.  Suffix Reference . . . . . . . . . . . . . . . . . . . . 27
26657
 
+   5.  Reference Resolution . . . . . . . . . . . . . . . . . . . . . 28
26658
 
+       5.1.  Establishing a Base URI  . . . . . . . . . . . . . . . . 28
26659
 
+             5.1.1.  Base URI Embedded in Content . . . . . . . . . . 29
26660
 
+             5.1.2.  Base URI from the Encapsulating Entity . . . . . 29
26661
 
+             5.1.3.  Base URI from the Retrieval URI  . . . . . . . . 30
26662
 
+             5.1.4.  Default Base URI . . . . . . . . . . . . . . . . 30
26663
 
+       5.2.  Relative Resolution  . . . . . . . . . . . . . . . . . . 30
26664
 
+             5.2.1.  Pre-parse the Base URI . . . . . . . . . . . . . 31
26665
 
+             5.2.2.  Transform References . . . . . . . . . . . . . . 31
26666
 
+             5.2.3.  Merge Paths  . . . . . . . . . . . . . . . . . . 32
26667
 
+             5.2.4.  Remove Dot Segments  . . . . . . . . . . . . . . 33
26668
 
+       5.3.  Component Recomposition  . . . . . . . . . . . . . . . . 35
26669
 
+       5.4.  Reference Resolution Examples  . . . . . . . . . . . . . 35
26670
 
+             5.4.1.  Normal Examples  . . . . . . . . . . . . . . . . 36
26671
 
+             5.4.2.  Abnormal Examples  . . . . . . . . . . . . . . . 36
26672
 
+
26673
 
+
26674
 
+
26675
 
+Berners-Lee, et al.         Standards Track                     [Page 2]
26676
 
+
26677
 
+RFC 3986                   URI Generic Syntax               January 2005
26678
 
+
26679
 
+
26680
 
+   6.  Normalization and Comparison . . . . . . . . . . . . . . . . . 38
26681
 
+       6.1.  Equivalence  . . . . . . . . . . . . . . . . . . . . . . 38
26682
 
+       6.2.  Comparison Ladder  . . . . . . . . . . . . . . . . . . . 39
26683
 
+             6.2.1.  Simple String Comparison . . . . . . . . . . . . 39
26684
 
+             6.2.2.  Syntax-Based Normalization . . . . . . . . . . . 40
26685
 
+             6.2.3.  Scheme-Based Normalization . . . . . . . . . . . 41
26686
 
+             6.2.4.  Protocol-Based Normalization . . . . . . . . . . 42
26687
 
+   7.  Security Considerations  . . . . . . . . . . . . . . . . . . . 43
26688
 
+       7.1.  Reliability and Consistency  . . . . . . . . . . . . . . 43
26689
 
+       7.2.  Malicious Construction . . . . . . . . . . . . . . . . . 43
26690
 
+       7.3.  Back-End Transcoding . . . . . . . . . . . . . . . . . . 44
26691
 
+       7.4.  Rare IP Address Formats  . . . . . . . . . . . . . . . . 45
26692
 
+       7.5.  Sensitive Information  . . . . . . . . . . . . . . . . . 45
26693
 
+       7.6.  Semantic Attacks . . . . . . . . . . . . . . . . . . . . 45
26694
 
+   8.  IANA Considerations  . . . . . . . . . . . . . . . . . . . . . 46
26695
 
+   9.  Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . 46
26696
 
+   10. References . . . . . . . . . . . . . . . . . . . . . . . . . . 46
26697
 
+       10.1. Normative References . . . . . . . . . . . . . . . . . . 46
26698
 
+       10.2. Informative References . . . . . . . . . . . . . . . . . 47
26699
 
+   A.  Collected ABNF for URI . . . . . . . . . . . . . . . . . . . . 49
26700
 
+   B.  Parsing a URI Reference with a Regular Expression  . . . . . . 50
26701
 
+   C.  Delimiting a URI in Context  . . . . . . . . . . . . . . . . . 51
26702
 
+   D.  Changes from RFC 2396  . . . . . . . . . . . . . . . . . . . . 53
26703
 
+       D.1.  Additions  . . . . . . . . . . . . . . . . . . . . . . . 53
26704
 
+       D.2.  Modifications  . . . . . . . . . . . . . . . . . . . . . 53
26705
 
+   Index  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
26706
 
+   Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . . 60
26707
 
+   Full Copyright Statement . . . . . . . . . . . . . . . . . . . . . 61
26708
 
+
26709
 
+
26710
 
+
26711
 
+
26712
 
+
26713
 
+
26714
 
+
26715
 
+
26716
 
+
26717
 
+
26718
 
+
26719
 
+
26720
 
+
26721
 
+
26722
 
+
26723
 
+
26724
 
+
26725
 
+
26726
 
+
26727
 
+
26728
 
+
26729
 
+
26730
 
+
26731
 
+Berners-Lee, et al.         Standards Track                     [Page 3]
26732
 
+
26733
 
+RFC 3986                   URI Generic Syntax               January 2005
26734
 
+
26735
 
+
26736
 
+1.  Introduction
26737
 
+
26738
 
+   A Uniform Resource Identifier (URI) provides a simple and extensible
26739
 
+   means for identifying a resource.  This specification of URI syntax
26740
 
+   and semantics is derived from concepts introduced by the World Wide
26741
 
+   Web global information initiative, whose use of these identifiers
26742
 
+   dates from 1990 and is described in "Universal Resource Identifiers
26743
 
+   in WWW" [RFC1630].  The syntax is designed to meet the
26744
 
+   recommendations laid out in "Functional Recommendations for Internet
26745
 
+   Resource Locators" [RFC1736] and "Functional Requirements for Uniform
26746
 
+   Resource Names" [RFC1737].
26747
 
+
26748
 
+   This document obsoletes [RFC2396], which merged "Uniform Resource
26749
 
+   Locators" [RFC1738] and "Relative Uniform Resource Locators"
26750
 
+   [RFC1808] in order to define a single, generic syntax for all URIs.
26751
 
+   It obsoletes [RFC2732], which introduced syntax for an IPv6 address.
26752
 
+   It excludes portions of RFC 1738 that defined the specific syntax of
26753
 
+   individual URI schemes; those portions will be updated as separate
26754
 
+   documents.  The process for registration of new URI schemes is
26755
 
+   defined separately by [BCP35].  Advice for designers of new URI
26756
 
+   schemes can be found in [RFC2718].  All significant changes from RFC
26757
 
+   2396 are noted in Appendix D.
26758
 
+
26759
 
+   This specification uses the terms "character" and "coded character
26760
 
+   set" in accordance with the definitions provided in [BCP19], and
26761
 
+   "character encoding" in place of what [BCP19] refers to as a
26762
 
+   "charset".
26763
 
+
26764
 
+1.1.  Overview of URIs
26765
 
+
26766
 
+   URIs are characterized as follows:
26767
 
+
26768
 
+   Uniform
26769
 
+
26770
 
+      Uniformity provides several benefits.  It allows different types
26771
 
+      of resource identifiers to be used in the same context, even when
26772
 
+      the mechanisms used to access those resources may differ.  It
26773
 
+      allows uniform semantic interpretation of common syntactic
26774
 
+      conventions across different types of resource identifiers.  It
26775
 
+      allows introduction of new types of resource identifiers without
26776
 
+      interfering with the way that existing identifiers are used.  It
26777
 
+      allows the identifiers to be reused in many different contexts,
26778
 
+      thus permitting new applications or protocols to leverage a pre-
26779
 
+      existing, large, and widely used set of resource identifiers.
26780
 
+
26781
 
+
26782
 
+
26783
 
+
26784
 
+
26785
 
+
26786
 
+
26787
 
+Berners-Lee, et al.         Standards Track                     [Page 4]
26788
 
+
26789
 
+RFC 3986                   URI Generic Syntax               January 2005
26790
 
+
26791
 
+
26792
 
+   Resource
26793
 
+
26794
 
+      This specification does not limit the scope of what might be a
26795
 
+      resource; rather, the term "resource" is used in a general sense
26796
 
+      for whatever might be identified by a URI.  Familiar examples
26797
 
+      include an electronic document, an image, a source of information
26798
 
+      with a consistent purpose (e.g., "today's weather report for Los
26799
 
+      Angeles"), a service (e.g., an HTTP-to-SMS gateway), and a
26800
 
+      collection of other resources.  A resource is not necessarily
26801
 
+      accessible via the Internet; e.g., human beings, corporations, and
26802
 
+      bound books in a library can also be resources.  Likewise,
26803
 
+      abstract concepts can be resources, such as the operators and
26804
 
+      operands of a mathematical equation, the types of a relationship
26805
 
+      (e.g., "parent" or "employee"), or numeric values (e.g., zero,
26806
 
+      one, and infinity).
26807
 
+
26808
 
+   Identifier
26809
 
+
26810
 
+      An identifier embodies the information required to distinguish
26811
 
+      what is being identified from all other things within its scope of
26812
 
+      identification.  Our use of the terms "identify" and "identifying"
26813
 
+      refer to this purpose of distinguishing one resource from all
26814
 
+      other resources, regardless of how that purpose is accomplished
26815
 
+      (e.g., by name, address, or context).  These terms should not be
26816
 
+      mistaken as an assumption that an identifier defines or embodies
26817
 
+      the identity of what is referenced, though that may be the case
26818
 
+      for some identifiers.  Nor should it be assumed that a system
26819
 
+      using URIs will access the resource identified: in many cases,
26820
 
+      URIs are used to denote resources without any intention that they
26821
 
+      be accessed.  Likewise, the "one" resource identified might not be
26822
 
+      singular in nature (e.g., a resource might be a named set or a
26823
 
+      mapping that varies over time).
26824
 
+
26825
 
+   A URI is an identifier consisting of a sequence of characters
26826
 
+   matching the syntax rule named <URI> in Section 3.  It enables
26827
 
+   uniform identification of resources via a separately defined
26828
 
+   extensible set of naming schemes (Section 3.1).  How that
26829
 
+   identification is accomplished, assigned, or enabled is delegated to
26830
 
+   each scheme specification.
26831
 
+
26832
 
+   This specification does not place any limits on the nature of a
26833
 
+   resource, the reasons why an application might seek to refer to a
26834
 
+   resource, or the kinds of systems that might use URIs for the sake of
26835
 
+   identifying resources.  This specification does not require that a
26836
 
+   URI persists in identifying the same resource over time, though that
26837
 
+   is a common goal of all URI schemes.  Nevertheless, nothing in this
26838
 
+
26839
 
+
26840
 
+
26841
 
+
26842
 
+
26843
 
+Berners-Lee, et al.         Standards Track                     [Page 5]
26844
 
+
26845
 
+RFC 3986                   URI Generic Syntax               January 2005
26846
 
+
26847
 
+
26848
 
+   specification prevents an application from limiting itself to
26849
 
+   particular types of resources, or to a subset of URIs that maintains
26850
 
+   characteristics desired by that application.
26851
 
+
26852
 
+   URIs have a global scope and are interpreted consistently regardless
26853
 
+   of context, though the result of that interpretation may be in
26854
 
+   relation to the end-user's context.  For example, "http://localhost/"
26855
 
+   has the same interpretation for every user of that reference, even
26856
 
+   though the network interface corresponding to "localhost" may be
26857
 
+   different for each end-user: interpretation is independent of access.
26858
 
+   However, an action made on the basis of that reference will take
26859
 
+   place in relation to the end-user's context, which implies that an
26860
 
+   action intended to refer to a globally unique thing must use a URI
26861
 
+   that distinguishes that resource from all other things.  URIs that
26862
 
+   identify in relation to the end-user's local context should only be
26863
 
+   used when the context itself is a defining aspect of the resource,
26864
 
+   such as when an on-line help manual refers to a file on the end-
26865
 
+   user's file system (e.g., "file:///etc/hosts").
26866
 
+
26867
 
+1.1.1.  Generic Syntax
26868
 
+
26869
 
+   Each URI begins with a scheme name, as defined in Section 3.1, that
26870
 
+   refers to a specification for assigning identifiers within that
26871
 
+   scheme.  As such, the URI syntax is a federated and extensible naming
26872
 
+   system wherein each scheme's specification may further restrict the
26873
 
+   syntax and semantics of identifiers using that scheme.
26874
 
+
26875
 
+   This specification defines those elements of the URI syntax that are
26876
 
+   required of all URI schemes or are common to many URI schemes.  It
26877
 
+   thus defines the syntax and semantics needed to implement a scheme-
26878
 
+   independent parsing mechanism for URI references, by which the
26879
 
+   scheme-dependent handling of a URI can be postponed until the
26880
 
+   scheme-dependent semantics are needed.  Likewise, protocols and data
26881
 
+   formats that make use of URI references can refer to this
26882
 
+   specification as a definition for the range of syntax allowed for all
26883
 
+   URIs, including those schemes that have yet to be defined.  This
26884
 
+   decouples the evolution of identification schemes from the evolution
26885
 
+   of protocols, data formats, and implementations that make use of
26886
 
+   URIs.
26887
 
+
26888
 
+   A parser of the generic URI syntax can parse any URI reference into
26889
 
+   its major components.  Once the scheme is determined, further
26890
 
+   scheme-specific parsing can be performed on the components.  In other
26891
 
+   words, the URI generic syntax is a superset of the syntax of all URI
26892
 
+   schemes.
26893
 
+
26894
 
+
26895
 
+
26896
 
+
26897
 
+
26898
 
+
26899
 
+Berners-Lee, et al.         Standards Track                     [Page 6]
26900
 
+
26901
 
+RFC 3986                   URI Generic Syntax               January 2005
26902
 
+
26903
 
+
26904
 
+1.1.2.  Examples
26905
 
+
26906
 
+   The following example URIs illustrate several URI schemes and
26907
 
+   variations in their common syntax components:
26908
 
+
26909
 
+      ftp://ftp.is.co.za/rfc/rfc1808.txt
26910
 
+
26911
 
+      http://www.ietf.org/rfc/rfc2396.txt
26912
 
+
26913
 
+      ldap://[2001:db8::7]/c=GB?objectClass?one
26914
 
+
26915
 
+      mailto:John.Doe@example.com
26916
 
+
26917
 
+      news:comp.infosystems.www.servers.unix
26918
 
+
26919
 
+      tel:+1-816-555-1212
26920
 
+
26921
 
+      telnet://192.0.2.16:80/
26922
 
+
26923
 
+      urn:oasis:names:specification:docbook:dtd:xml:4.1.2
26924
 
+
26925
 
+
26926
 
+1.1.3.  URI, URL, and URN
26927
 
+
26928
 
+   A URI can be further classified as a locator, a name, or both.  The
26929
 
+   term "Uniform Resource Locator" (URL) refers to the subset of URIs
26930
 
+   that, in addition to identifying a resource, provide a means of
26931
 
+   locating the resource by describing its primary access mechanism
26932
 
+   (e.g., its network "location").  The term "Uniform Resource Name"
26933
 
+   (URN) has been used historically to refer to both URIs under the
26934
 
+   "urn" scheme [RFC2141], which are required to remain globally unique
26935
 
+   and persistent even when the resource ceases to exist or becomes
26936
 
+   unavailable, and to any other URI with the properties of a name.
26937
 
+
26938
 
+   An individual scheme does not have to be classified as being just one
26939
 
+   of "name" or "locator".  Instances of URIs from any given scheme may
26940
 
+   have the characteristics of names or locators or both, often
26941
 
+   depending on the persistence and care in the assignment of
26942
 
+   identifiers by the naming authority, rather than on any quality of
26943
 
+   the scheme.  Future specifications and related documentation should
26944
 
+   use the general term "URI" rather than the more restrictive terms
26945
 
+   "URL" and "URN" [RFC3305].
26946
 
+
26947
 
+
26948
 
+
26949
 
+
26950
 
+
26951
 
+
26952
 
+
26953
 
+
26954
 
+
26955
 
+Berners-Lee, et al.         Standards Track                     [Page 7]
26956
 
+
26957
 
+RFC 3986                   URI Generic Syntax               January 2005
26958
 
+
26959
 
+
26960
 
+1.2.  Design Considerations
26961
 
+
26962
 
+1.2.1.  Transcription
26963
 
+
26964
 
+   The URI syntax has been designed with global transcription as one of
26965
 
+   its main considerations.  A URI is a sequence of characters from a
26966
 
+   very limited set: the letters of the basic Latin alphabet, digits,
26967
 
+   and a few special characters.  A URI may be represented in a variety
26968
 
+   of ways; e.g., ink on paper, pixels on a screen, or a sequence of
26969
 
+   character encoding octets.  The interpretation of a URI depends only
26970
 
+   on the characters used and not on how those characters are
26971
 
+   represented in a network protocol.
26972
 
+
26973
 
+   The goal of transcription can be described by a simple scenario.
26974
 
+   Imagine two colleagues, Sam and Kim, sitting in a pub at an
26975
 
+   international conference and exchanging research ideas.  Sam asks Kim
26976
 
+   for a location to get more information, so Kim writes the URI for the
26977
 
+   research site on a napkin.  Upon returning home, Sam takes out the
26978
 
+   napkin and types the URI into a computer, which then retrieves the
26979
 
+   information to which Kim referred.
26980
 
+
26981
 
+   There are several design considerations revealed by the scenario:
26982
 
+
26983
 
+   o  A URI is a sequence of characters that is not always represented
26984
 
+      as a sequence of octets.
26985
 
+
26986
 
+   o  A URI might be transcribed from a non-network source and thus
26987
 
+      should consist of characters that are most likely able to be
26988
 
+      entered into a computer, within the constraints imposed by
26989
 
+      keyboards (and related input devices) across languages and
26990
 
+      locales.
26991
 
+
26992
 
+   o  A URI often has to be remembered by people, and it is easier for
26993
 
+      people to remember a URI when it consists of meaningful or
26994
 
+      familiar components.
26995
 
+
26996
 
+   These design considerations are not always in alignment.  For
26997
 
+   example, it is often the case that the most meaningful name for a URI
26998
 
+   component would require characters that cannot be typed into some
26999
 
+   systems.  The ability to transcribe a resource identifier from one
27000
 
+   medium to another has been considered more important than having a
27001
 
+   URI consist of the most meaningful of components.
27002
 
+
27003
 
+   In local or regional contexts and with improving technology, users
27004
 
+   might benefit from being able to use a wider range of characters;
27005
 
+   such use is not defined by this specification.  Percent-encoded
27006
 
+   octets (Section 2.1) may be used within a URI to represent characters
27007
 
+   outside the range of the US-ASCII coded character set if this
27008
 
+
27009
 
+
27010
 
+
27011
 
+Berners-Lee, et al.         Standards Track                     [Page 8]
27012
 
+
27013
 
+RFC 3986                   URI Generic Syntax               January 2005
27014
 
+
27015
 
+
27016
 
+   representation is allowed by the scheme or by the protocol element in
27017
 
+   which the URI is referenced.  Such a definition should specify the
27018
 
+   character encoding used to map those characters to octets prior to
27019
 
+   being percent-encoded for the URI.
27020
 
+
27021
 
+1.2.2.  Separating Identification from Interaction
27022
 
+
27023
 
+   A common misunderstanding of URIs is that they are only used to refer
27024
 
+   to accessible resources.  The URI itself only provides
27025
 
+   identification; access to the resource is neither guaranteed nor
27026
 
+   implied by the presence of a URI.  Instead, any operation associated
27027
 
+   with a URI reference is defined by the protocol element, data format
27028
 
+   attribute, or natural language text in which it appears.
27029
 
+
27030
 
+   Given a URI, a system may attempt to perform a variety of operations
27031
 
+   on the resource, as might be characterized by words such as "access",
27032
 
+   "update", "replace", or "find attributes".  Such operations are
27033
 
+   defined by the protocols that make use of URIs, not by this
27034
 
+   specification.  However, we do use a few general terms for describing
27035
 
+   common operations on URIs.  URI "resolution" is the process of
27036
 
+   determining an access mechanism and the appropriate parameters
27037
 
+   necessary to dereference a URI; this resolution may require several
27038
 
+   iterations.  To use that access mechanism to perform an action on the
27039
 
+   URI's resource is to "dereference" the URI.
27040
 
+
27041
 
+   When URIs are used within information retrieval systems to identify
27042
 
+   sources of information, the most common form of URI dereference is
27043
 
+   "retrieval": making use of a URI in order to retrieve a
27044
 
+   representation of its associated resource.  A "representation" is a
27045
 
+   sequence of octets, along with representation metadata describing
27046
 
+   those octets, that constitutes a record of the state of the resource
27047
 
+   at the time when the representation is generated.  Retrieval is
27048
 
+   achieved by a process that might include using the URI as a cache key
27049
 
+   to check for a locally cached representation, resolution of the URI
27050
 
+   to determine an appropriate access mechanism (if any), and
27051
 
+   dereference of the URI for the sake of applying a retrieval
27052
 
+   operation.  Depending on the protocols used to perform the retrieval,
27053
 
+   additional information might be supplied about the resource (resource
27054
 
+   metadata) and its relation to other resources.
27055
 
+
27056
 
+   URI references in information retrieval systems are designed to be
27057
 
+   late-binding: the result of an access is generally determined when it
27058
 
+   is accessed and may vary over time or due to other aspects of the
27059
 
+   interaction.  These references are created in order to be used in the
27060
 
+   future: what is being identified is not some specific result that was
27061
 
+   obtained in the past, but rather some characteristic that is expected
27062
 
+   to be true for future results.  In such cases, the resource referred
27063
 
+   to by the URI is actually a sameness of characteristics as observed
27064
 
+
27065
 
+
27066
 
+
27067
 
+Berners-Lee, et al.         Standards Track                     [Page 9]
27068
 
+
27069
 
+RFC 3986                   URI Generic Syntax               January 2005
27070
 
+
27071
 
+
27072
 
+   over time, perhaps elucidated by additional comments or assertions
27073
 
+   made by the resource provider.
27074
 
+
27075
 
+   Although many URI schemes are named after protocols, this does not
27076
 
+   imply that use of these URIs will result in access to the resource
27077
 
+   via the named protocol.  URIs are often used simply for the sake of
27078
 
+   identification.  Even when a URI is used to retrieve a representation
27079
 
+   of a resource, that access might be through gateways, proxies,
27080
 
+   caches, and name resolution services that are independent of the
27081
 
+   protocol associated with the scheme name.  The resolution of some
27082
 
+   URIs may require the use of more than one protocol (e.g., both DNS
27083
 
+   and HTTP are typically used to access an "http" URI's origin server
27084
 
+   when a representation isn't found in a local cache).
27085
 
+
27086
 
+1.2.3.  Hierarchical Identifiers
27087
 
+
27088
 
+   The URI syntax is organized hierarchically, with components listed in
27089
 
+   order of decreasing significance from left to right.  For some URI
27090
 
+   schemes, the visible hierarchy is limited to the scheme itself:
27091
 
+   everything after the scheme component delimiter (":") is considered
27092
 
+   opaque to URI processing.  Other URI schemes make the hierarchy
27093
 
+   explicit and visible to generic parsing algorithms.
27094
 
+
27095
 
+   The generic syntax uses the slash ("/"), question mark ("?"), and
27096
 
+   number sign ("#") characters to delimit components that are
27097
 
+   significant to the generic parser's hierarchical interpretation of an
27098
 
+   identifier.  In addition to aiding the readability of such
27099
 
+   identifiers through the consistent use of familiar syntax, this
27100
 
+   uniform representation of hierarchy across naming schemes allows
27101
 
+   scheme-independent references to be made relative to that hierarchy.
27102
 
+
27103
 
+   It is often the case that a group or "tree" of documents has been
27104
 
+   constructed to serve a common purpose, wherein the vast majority of
27105
 
+   URI references in these documents point to resources within the tree
27106
 
+   rather than outside it.  Similarly, documents located at a particular
27107
 
+   site are much more likely to refer to other resources at that site
27108
 
+   than to resources at remote sites.  Relative referencing of URIs
27109
 
+   allows document trees to be partially independent of their location
27110
 
+   and access scheme.  For instance, it is possible for a single set of
27111
 
+   hypertext documents to be simultaneously accessible and traversable
27112
 
+   via each of the "file", "http", and "ftp" schemes if the documents
27113
 
+   refer to each other with relative references.  Furthermore, such
27114
 
+   document trees can be moved, as a whole, without changing any of the
27115
 
+   relative references.
27116
 
+
27117
 
+   A relative reference (Section 4.2) refers to a resource by describing
27118
 
+   the difference within a hierarchical name space between the reference
27119
 
+   context and the target URI.  The reference resolution algorithm,
27120
 
+
27121
 
+
27122
 
+
27123
 
+Berners-Lee, et al.         Standards Track                    [Page 10]
27124
 
+
27125
 
+RFC 3986                   URI Generic Syntax               January 2005
27126
 
+
27127
 
+
27128
 
+   presented in Section 5, defines how such a reference is transformed
27129
 
+   to the target URI.  As relative references can only be used within
27130
 
+   the context of a hierarchical URI, designers of new URI schemes
27131
 
+   should use a syntax consistent with the generic syntax's hierarchical
27132
 
+   components unless there are compelling reasons to forbid relative
27133
 
+   referencing within that scheme.
27134
 
+
27135
 
+      NOTE: Previous specifications used the terms "partial URI" and
27136
 
+      "relative URI" to denote a relative reference to a URI.  As some
27137
 
+      readers misunderstood those terms to mean that relative URIs are a
27138
 
+      subset of URIs rather than a method of referencing URIs, this
27139
 
+      specification simply refers to them as relative references.
27140
 
+
27141
 
+   All URI references are parsed by generic syntax parsers when used.
27142
 
+   However, because hierarchical processing has no effect on an absolute
27143
 
+   URI used in a reference unless it contains one or more dot-segments
27144
 
+   (complete path segments of "." or "..", as described in Section 3.3),
27145
 
+   URI scheme specifications can define opaque identifiers by
27146
 
+   disallowing use of slash characters, question mark characters, and
27147
 
+   the URIs "scheme:." and "scheme:..".
27148
 
+
27149
 
+1.3.  Syntax Notation
27150
 
+
27151
 
+   This specification uses the Augmented Backus-Naur Form (ABNF)
27152
 
+   notation of [RFC2234], including the following core ABNF syntax rules
27153
 
+   defined by that specification: ALPHA (letters), CR (carriage return),
27154
 
+   DIGIT (decimal digits), DQUOTE (double quote), HEXDIG (hexadecimal
27155
 
+   digits), LF (line feed), and SP (space).  The complete URI syntax is
27156
 
+   collected in Appendix A.
27157
 
+
27158
 
+2.  Characters
27159
 
+
27160
 
+   The URI syntax provides a method of encoding data, presumably for the
27161
 
+   sake of identifying a resource, as a sequence of characters.  The URI
27162
 
+   characters are, in turn, frequently encoded as octets for transport
27163
 
+   or presentation.  This specification does not mandate any particular
27164
 
+   character encoding for mapping between URI characters and the octets
27165
 
+   used to store or transmit those characters.  When a URI appears in a
27166
 
+   protocol element, the character encoding is defined by that protocol;
27167
 
+   without such a definition, a URI is assumed to be in the same
27168
 
+   character encoding as the surrounding text.
27169
 
+
27170
 
+   The ABNF notation defines its terminal values to be non-negative
27171
 
+   integers (codepoints) based on the US-ASCII coded character set
27172
 
+   [ASCII].  Because a URI is a sequence of characters, we must invert
27173
 
+   that relation in order to understand the URI syntax.  Therefore, the
27174
 
+
27175
 
+
27176
 
+
27177
 
+
27178
 
+
27179
 
+Berners-Lee, et al.         Standards Track                    [Page 11]
27180
 
+
27181
 
+RFC 3986                   URI Generic Syntax               January 2005
27182
 
+
27183
 
+
27184
 
+   integer values used by the ABNF must be mapped back to their
27185
 
+   corresponding characters via US-ASCII in order to complete the syntax
27186
 
+   rules.
27187
 
+
27188
 
+   A URI is composed from a limited set of characters consisting of
27189
 
+   digits, letters, and a few graphic symbols.  A reserved subset of
27190
 
+   those characters may be used to delimit syntax components within a
27191
 
+   URI while the remaining characters, including both the unreserved set
27192
 
+   and those reserved characters not acting as delimiters, define each
27193
 
+   component's identifying data.
27194
 
+
27195
 
+2.1.  Percent-Encoding
27196
 
+
27197
 
+   A percent-encoding mechanism is used to represent a data octet in a
27198
 
+   component when that octet's corresponding character is outside the
27199
 
+   allowed set or is being used as a delimiter of, or within, the
27200
 
+   component.  A percent-encoded octet is encoded as a character
27201
 
+   triplet, consisting of the percent character "%" followed by the two
27202
 
+   hexadecimal digits representing that octet's numeric value.  For
27203
 
+   example, "%20" is the percent-encoding for the binary octet
27204
 
+   "00100000" (ABNF: %x20), which in US-ASCII corresponds to the space
27205
 
+   character (SP).  Section 2.4 describes when percent-encoding and
27206
 
+   decoding is applied.
27207
 
+
27208
 
+      pct-encoded = "%" HEXDIG HEXDIG
27209
 
+
27210
 
+   The uppercase hexadecimal digits 'A' through 'F' are equivalent to
27211
 
+   the lowercase digits 'a' through 'f', respectively.  If two URIs
27212
 
+   differ only in the case of hexadecimal digits used in percent-encoded
27213
 
+   octets, they are equivalent.  For consistency, URI producers and
27214
 
+   normalizers should use uppercase hexadecimal digits for all percent-
27215
 
+   encodings.
27216
 
+
27217
 
+2.2.  Reserved Characters
27218
 
+
27219
 
+   URIs include components and subcomponents that are delimited by
27220
 
+   characters in the "reserved" set.  These characters are called
27221
 
+   "reserved" because they may (or may not) be defined as delimiters by
27222
 
+   the generic syntax, by each scheme-specific syntax, or by the
27223
 
+   implementation-specific syntax of a URI's dereferencing algorithm.
27224
 
+   If data for a URI component would conflict with a reserved
27225
 
+   character's purpose as a delimiter, then the conflicting data must be
27226
 
+   percent-encoded before the URI is formed.
27227
 
+
27228
 
+
27229
 
+
27230
 
+
27231
 
+
27232
 
+
27233
 
+
27234
 
+
27235
 
+Berners-Lee, et al.         Standards Track                    [Page 12]
27236
 
+
27237
 
+RFC 3986                   URI Generic Syntax               January 2005
27238
 
+
27239
 
+
27240
 
+      reserved    = gen-delims / sub-delims
27241
 
+
27242
 
+      gen-delims  = ":" / "/" / "?" / "#" / "[" / "]" / "@"
27243
 
+
27244
 
+      sub-delims  = "!" / "$" / "&" / "'" / "(" / ")"
27245
 
+                  / "*" / "+" / "," / ";" / "="
27246
 
+
27247
 
+   The purpose of reserved characters is to provide a set of delimiting
27248
 
+   characters that are distinguishable from other data within a URI.
27249
 
+   URIs that differ in the replacement of a reserved character with its
27250
 
+   corresponding percent-encoded octet are not equivalent.  Percent-
27251
 
+   encoding a reserved character, or decoding a percent-encoded octet
27252
 
+   that corresponds to a reserved character, will change how the URI is
27253
 
+   interpreted by most applications.  Thus, characters in the reserved
27254
 
+   set are protected from normalization and are therefore safe to be
27255
 
+   used by scheme-specific and producer-specific algorithms for
27256
 
+   delimiting data subcomponents within a URI.
27257
 
+
27258
 
+   A subset of the reserved characters (gen-delims) is used as
27259
 
+   delimiters of the generic URI components described in Section 3.  A
27260
 
+   component's ABNF syntax rule will not use the reserved or gen-delims
27261
 
+   rule names directly; instead, each syntax rule lists the characters
27262
 
+   allowed within that component (i.e., not delimiting it), and any of
27263
 
+   those characters that are also in the reserved set are "reserved" for
27264
 
+   use as subcomponent delimiters within the component.  Only the most
27265
 
+   common subcomponents are defined by this specification; other
27266
 
+   subcomponents may be defined by a URI scheme's specification, or by
27267
 
+   the implementation-specific syntax of a URI's dereferencing
27268
 
+   algorithm, provided that such subcomponents are delimited by
27269
 
+   characters in the reserved set allowed within that component.
27270
 
+
27271
 
+   URI producing applications should percent-encode data octets that
27272
 
+   correspond to characters in the reserved set unless these characters
27273
 
+   are specifically allowed by the URI scheme to represent data in that
27274
 
+   component.  If a reserved character is found in a URI component and
27275
 
+   no delimiting role is known for that character, then it must be
27276
 
+   interpreted as representing the data octet corresponding to that
27277
 
+   character's encoding in US-ASCII.
27278
 
+
27279
 
+2.3.  Unreserved Characters
27280
 
+
27281
 
+   Characters that are allowed in a URI but do not have a reserved
27282
 
+   purpose are called unreserved.  These include uppercase and lowercase
27283
 
+   letters, decimal digits, hyphen, period, underscore, and tilde.
27284
 
+
27285
 
+      unreserved  = ALPHA / DIGIT / "-" / "." / "_" / "~"
27286
 
+
27287
 
+
27288
 
+
27289
 
+
27290
 
+
27291
 
+Berners-Lee, et al.         Standards Track                    [Page 13]
27292
 
+
27293
 
+RFC 3986                   URI Generic Syntax               January 2005
27294
 
+
27295
 
+
27296
 
+   URIs that differ in the replacement of an unreserved character with
27297
 
+   its corresponding percent-encoded US-ASCII octet are equivalent: they
27298
 
+   identify the same resource.  However, URI comparison implementations
27299
 
+   do not always perform normalization prior to comparison (see Section
27300
 
+   6).  For consistency, percent-encoded octets in the ranges of ALPHA
27301
 
+   (%41-%5A and %61-%7A), DIGIT (%30-%39), hyphen (%2D), period (%2E),
27302
 
+   underscore (%5F), or tilde (%7E) should not be created by URI
27303
 
+   producers and, when found in a URI, should be decoded to their
27304
 
+   corresponding unreserved characters by URI normalizers.
27305
 
+
27306
 
+2.4.  When to Encode or Decode
27307
 
+
27308
 
+   Under normal circumstances, the only time when octets within a URI
27309
 
+   are percent-encoded is during the process of producing the URI from
27310
 
+   its component parts.  This is when an implementation determines which
27311
 
+   of the reserved characters are to be used as subcomponent delimiters
27312
 
+   and which can be safely used as data.  Once produced, a URI is always
27313
 
+   in its percent-encoded form.
27314
 
+
27315
 
+   When a URI is dereferenced, the components and subcomponents
27316
 
+   significant to the scheme-specific dereferencing process (if any)
27317
 
+   must be parsed and separated before the percent-encoded octets within
27318
 
+   those components can be safely decoded, as otherwise the data may be
27319
 
+   mistaken for component delimiters.  The only exception is for
27320
 
+   percent-encoded octets corresponding to characters in the unreserved
27321
 
+   set, which can be decoded at any time.  For example, the octet
27322
 
+   corresponding to the tilde ("~") character is often encoded as "%7E"
27323
 
+   by older URI processing implementations; the "%7E" can be replaced by
27324
 
+   "~" without changing its interpretation.
27325
 
+
27326
 
+   Because the percent ("%") character serves as the indicator for
27327
 
+   percent-encoded octets, it must be percent-encoded as "%25" for that
27328
 
+   octet to be used as data within a URI.  Implementations must not
27329
 
+   percent-encode or decode the same string more than once, as decoding
27330
 
+   an already decoded string might lead to misinterpreting a percent
27331
 
+   data octet as the beginning of a percent-encoding, or vice versa in
27332
 
+   the case of percent-encoding an already percent-encoded string.
27333
 
+
27334
 
+2.5.  Identifying Data
27335
 
+
27336
 
+   URI characters provide identifying data for each of the URI
27337
 
+   components, serving as an external interface for identification
27338
 
+   between systems.  Although the presence and nature of the URI
27339
 
+   production interface is hidden from clients that use its URIs (and is
27340
 
+   thus beyond the scope of the interoperability requirements defined by
27341
 
+   this specification), it is a frequent source of confusion and errors
27342
 
+   in the interpretation of URI character issues.  Implementers have to
27343
 
+   be aware that there are multiple character encodings involved in the
27344
 
+
27345
 
+
27346
 
+
27347
 
+Berners-Lee, et al.         Standards Track                    [Page 14]
27348
 
+
27349
 
+RFC 3986                   URI Generic Syntax               January 2005
27350
 
+
27351
 
+
27352
 
+   production and transmission of URIs: local name and data encoding,
27353
 
+   public interface encoding, URI character encoding, data format
27354
 
+   encoding, and protocol encoding.
27355
 
+
27356
 
+   Local names, such as file system names, are stored with a local
27357
 
+   character encoding.  URI producing applications (e.g., origin
27358
 
+   servers) will typically use the local encoding as the basis for
27359
 
+   producing meaningful names.  The URI producer will transform the
27360
 
+   local encoding to one that is suitable for a public interface and
27361
 
+   then transform the public interface encoding into the restricted set
27362
 
+   of URI characters (reserved, unreserved, and percent-encodings).
27363
 
+   Those characters are, in turn, encoded as octets to be used as a
27364
 
+   reference within a data format (e.g., a document charset), and such
27365
 
+   data formats are often subsequently encoded for transmission over
27366
 
+   Internet protocols.
27367
 
+
27368
 
+   For most systems, an unreserved character appearing within a URI
27369
 
+   component is interpreted as representing the data octet corresponding
27370
 
+   to that character's encoding in US-ASCII.  Consumers of URIs assume
27371
 
+   that the letter "X" corresponds to the octet "01011000", and even
27372
 
+   when that assumption is incorrect, there is no harm in making it.  A
27373
 
+   system that internally provides identifiers in the form of a
27374
 
+   different character encoding, such as EBCDIC, will generally perform
27375
 
+   character translation of textual identifiers to UTF-8 [STD63] (or
27376
 
+   some other superset of the US-ASCII character encoding) at an
27377
 
+   internal interface, thereby providing more meaningful identifiers
27378
 
+   than those resulting from simply percent-encoding the original
27379
 
+   octets.
27380
 
+
27381
 
+   For example, consider an information service that provides data,
27382
 
+   stored locally using an EBCDIC-based file system, to clients on the
27383
 
+   Internet through an HTTP server.  When an author creates a file with
27384
 
+   the name "Laguna Beach" on that file system, the "http" URI
27385
 
+   corresponding to that resource is expected to contain the meaningful
27386
 
+   string "Laguna%20Beach".  If, however, that server produces URIs by
27387
 
+   using an overly simplistic raw octet mapping, then the result would
27388
 
+   be a URI containing "%D3%81%87%A4%95%81@%C2%85%81%83%88".  An
27389
 
+   internal transcoding interface fixes this problem by transcoding the
27390
 
+   local name to a superset of US-ASCII prior to producing the URI.
27391
 
+   Naturally, proper interpretation of an incoming URI on such an
27392
 
+   interface requires that percent-encoded octets be decoded (e.g.,
27393
 
+   "%20" to SP) before the reverse transcoding is applied to obtain the
27394
 
+   local name.
27395
 
+
27396
 
+   In some cases, the internal interface between a URI component and the
27397
 
+   identifying data that it has been crafted to represent is much less
27398
 
+   direct than a character encoding translation.  For example, portions
27399
 
+   of a URI might reflect a query on non-ASCII data, or numeric
27400
 
+
27401
 
+
27402
 
+
27403
 
+Berners-Lee, et al.         Standards Track                    [Page 15]
27404
 
+
27405
 
+RFC 3986                   URI Generic Syntax               January 2005
27406
 
+
27407
 
+
27408
 
+   coordinates on a map.  Likewise, a URI scheme may define components
27409
 
+   with additional encoding requirements that are applied prior to
27410
 
+   forming the component and producing the URI.
27411
 
+
27412
 
+   When a new URI scheme defines a component that represents textual
27413
 
+   data consisting of characters from the Universal Character Set [UCS],
27414
 
+   the data should first be encoded as octets according to the UTF-8
27415
 
+   character encoding [STD63]; then only those octets that do not
27416
 
+   correspond to characters in the unreserved set should be percent-
27417
 
+   encoded.  For example, the character A would be represented as "A",
27418
 
+   the character LATIN CAPITAL LETTER A WITH GRAVE would be represented
27419
 
+   as "%C3%80", and the character KATAKANA LETTER A would be represented
27420
 
+   as "%E3%82%A2".
27421
 
+
27422
 
+3.  Syntax Components
27423
 
+
27424
 
+   The generic URI syntax consists of a hierarchical sequence of
27425
 
+   components referred to as the scheme, authority, path, query, and
27426
 
+   fragment.
27427
 
+
27428
 
+      URI         = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
27429
 
+
27430
 
+      hier-part   = "//" authority path-abempty
27431
 
+                  / path-absolute
27432
 
+                  / path-rootless
27433
 
+                  / path-empty
27434
 
+
27435
 
+   The scheme and path components are required, though the path may be
27436
 
+   empty (no characters).  When authority is present, the path must
27437
 
+   either be empty or begin with a slash ("/") character.  When
27438
 
+   authority is not present, the path cannot begin with two slash
27439
 
+   characters ("//").  These restrictions result in five different ABNF
27440
 
+   rules for a path (Section 3.3), only one of which will match any
27441
 
+   given URI reference.
27442
 
+
27443
 
+   The following are two example URIs and their component parts:
27444
 
+
27445
 
+         foo://example.com:8042/over/there?name=ferret#nose
27446
 
+         \_/   \______________/\_________/ \_________/ \__/
27447
 
+          |           |            |            |        |
27448
 
+       scheme     authority       path        query   fragment
27449
 
+          |   _____________________|__
27450
 
+         / \ /                        \
27451
 
+         urn:example:animal:ferret:nose
27452
 
+
27453
 
+
27454
 
+
27455
 
+
27456
 
+
27457
 
+
27458
 
+
27459
 
+Berners-Lee, et al.         Standards Track                    [Page 16]
27460
 
+
27461
 
+RFC 3986                   URI Generic Syntax               January 2005
27462
 
+
27463
 
+
27464
 
+3.1.  Scheme
27465
 
+
27466
 
+   Each URI begins with a scheme name that refers to a specification for
27467
 
+   assigning identifiers within that scheme.  As such, the URI syntax is
27468
 
+   a federated and extensible naming system wherein each scheme's
27469
 
+   specification may further restrict the syntax and semantics of
27470
 
+   identifiers using that scheme.
27471
 
+
27472
 
+   Scheme names consist of a sequence of characters beginning with a
27473
 
+   letter and followed by any combination of letters, digits, plus
27474
 
+   ("+"), period ("."), or hyphen ("-").  Although schemes are case-
27475
 
+   insensitive, the canonical form is lowercase and documents that
27476
 
+   specify schemes must do so with lowercase letters.  An implementation
27477
 
+   should accept uppercase letters as equivalent to lowercase in scheme
27478
 
+   names (e.g., allow "HTTP" as well as "http") for the sake of
27479
 
+   robustness but should only produce lowercase scheme names for
27480
 
+   consistency.
27481
 
+
27482
 
+      scheme      = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
27483
 
+
27484
 
+   Individual schemes are not specified by this document.  The process
27485
 
+   for registration of new URI schemes is defined separately by [BCP35].
27486
 
+   The scheme registry maintains the mapping between scheme names and
27487
 
+   their specifications.  Advice for designers of new URI schemes can be
27488
 
+   found in [RFC2718].  URI scheme specifications must define their own
27489
 
+   syntax so that all strings matching their scheme-specific syntax will
27490
 
+   also match the <absolute-URI> grammar, as described in Section 4.3.
27491
 
+
27492
 
+   When presented with a URI that violates one or more scheme-specific
27493
 
+   restrictions, the scheme-specific resolution process should flag the
27494
 
+   reference as an error rather than ignore the unused parts; doing so
27495
 
+   reduces the number of equivalent URIs and helps detect abuses of the
27496
 
+   generic syntax, which might indicate that the URI has been
27497
 
+   constructed to mislead the user (Section 7.6).
27498
 
+
27499
 
+3.2.  Authority
27500
 
+
27501
 
+   Many URI schemes include a hierarchical element for a naming
27502
 
+   authority so that governance of the name space defined by the
27503
 
+   remainder of the URI is delegated to that authority (which may, in
27504
 
+   turn, delegate it further).  The generic syntax provides a common
27505
 
+   means for distinguishing an authority based on a registered name or
27506
 
+   server address, along with optional port and user information.
27507
 
+
27508
 
+   The authority component is preceded by a double slash ("//") and is
27509
 
+   terminated by the next slash ("/"), question mark ("?"), or number
27510
 
+   sign ("#") character, or by the end of the URI.
27511
 
+
27512
 
+
27513
 
+
27514
 
+
27515
 
+Berners-Lee, et al.         Standards Track                    [Page 17]
27516
 
+
27517
 
+RFC 3986                   URI Generic Syntax               January 2005
27518
 
+
27519
 
+
27520
 
+      authority   = [ userinfo "@" ] host [ ":" port ]
27521
 
+
27522
 
+   URI producers and normalizers should omit the ":" delimiter that
27523
 
+   separates host from port if the port component is empty.  Some
27524
 
+   schemes do not allow the userinfo and/or port subcomponents.
27525
 
+
27526
 
+   If a URI contains an authority component, then the path component
27527
 
+   must either be empty or begin with a slash ("/") character.  Non-
27528
 
+   validating parsers (those that merely separate a URI reference into
27529
 
+   its major components) will often ignore the subcomponent structure of
27530
 
+   authority, treating it as an opaque string from the double-slash to
27531
 
+   the first terminating delimiter, until such time as the URI is
27532
 
+   dereferenced.
27533
 
+
27534
 
+3.2.1.  User Information
27535
 
+
27536
 
+   The userinfo subcomponent may consist of a user name and, optionally,
27537
 
+   scheme-specific information about how to gain authorization to access
27538
 
+   the resource.  The user information, if present, is followed by a
27539
 
+   commercial at-sign ("@") that delimits it from the host.
27540
 
+
27541
 
+      userinfo    = *( unreserved / pct-encoded / sub-delims / ":" )
27542
 
+
27543
 
+   Use of the format "user:password" in the userinfo field is
27544
 
+   deprecated.  Applications should not render as clear text any data
27545
 
+   after the first colon (":") character found within a userinfo
27546
 
+   subcomponent unless the data after the colon is the empty string
27547
 
+   (indicating no password).  Applications may choose to ignore or
27548
 
+   reject such data when it is received as part of a reference and
27549
 
+   should reject the storage of such data in unencrypted form.  The
27550
 
+   passing of authentication information in clear text has proven to be
27551
 
+   a security risk in almost every case where it has been used.
27552
 
+
27553
 
+   Applications that render a URI for the sake of user feedback, such as
27554
 
+   in graphical hypertext browsing, should render userinfo in a way that
27555
 
+   is distinguished from the rest of a URI, when feasible.  Such
27556
 
+   rendering will assist the user in cases where the userinfo has been
27557
 
+   misleadingly crafted to look like a trusted domain name
27558
 
+   (Section 7.6).
27559
 
+
27560
 
+3.2.2.  Host
27561
 
+
27562
 
+   The host subcomponent of authority is identified by an IP literal
27563
 
+   encapsulated within square brackets, an IPv4 address in dotted-
27564
 
+   decimal form, or a registered name.  The host subcomponent is case-
27565
 
+   insensitive.  The presence of a host subcomponent within a URI does
27566
 
+   not imply that the scheme requires access to the given host on the
27567
 
+   Internet.  In many cases, the host syntax is used only for the sake
27568
 
+
27569
 
+
27570
 
+
27571
 
+Berners-Lee, et al.         Standards Track                    [Page 18]
27572
 
+
27573
 
+RFC 3986                   URI Generic Syntax               January 2005
27574
 
+
27575
 
+
27576
 
+   of reusing the existing registration process created and deployed for
27577
 
+   DNS, thus obtaining a globally unique name without the cost of
27578
 
+   deploying another registry.  However, such use comes with its own
27579
 
+   costs: domain name ownership may change over time for reasons not
27580
 
+   anticipated by the URI producer.  In other cases, the data within the
27581
 
+   host component identifies a registered name that has nothing to do
27582
 
+   with an Internet host.  We use the name "host" for the ABNF rule
27583
 
+   because that is its most common purpose, not its only purpose.
27584
 
+
27585
 
+      host        = IP-literal / IPv4address / reg-name
27586
 
+
27587
 
+   The syntax rule for host is ambiguous because it does not completely
27588
 
+   distinguish between an IPv4address and a reg-name.  In order to
27589
 
+   disambiguate the syntax, we apply the "first-match-wins" algorithm:
27590
 
+   If host matches the rule for IPv4address, then it should be
27591
 
+   considered an IPv4 address literal and not a reg-name.  Although host
27592
 
+   is case-insensitive, producers and normalizers should use lowercase
27593
 
+   for registered names and hexadecimal addresses for the sake of
27594
 
+   uniformity, while only using uppercase letters for percent-encodings.
27595
 
+
27596
 
+   A host identified by an Internet Protocol literal address, version 6
27597
 
+   [RFC3513] or later, is distinguished by enclosing the IP literal
27598
 
+   within square brackets ("[" and "]").  This is the only place where
27599
 
+   square bracket characters are allowed in the URI syntax.  In
27600
 
+   anticipation of future, as-yet-undefined IP literal address formats,
27601
 
+   an implementation may use an optional version flag to indicate such a
27602
 
+   format explicitly rather than rely on heuristic determination.
27603
 
+
27604
 
+      IP-literal = "[" ( IPv6address / IPvFuture  ) "]"
27605
 
+
27606
 
+      IPvFuture  = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )
27607
 
+
27608
 
+   The version flag does not indicate the IP version; rather, it
27609
 
+   indicates future versions of the literal format.  As such,
27610
 
+   implementations must not provide the version flag for the existing
27611
 
+   IPv4 and IPv6 literal address forms described below.  If a URI
27612
 
+   containing an IP-literal that starts with "v" (case-insensitive),
27613
 
+   indicating that the version flag is present, is dereferenced by an
27614
 
+   application that does not know the meaning of that version flag, then
27615
 
+   the application should return an appropriate error for "address
27616
 
+   mechanism not supported".
27617
 
+
27618
 
+   A host identified by an IPv6 literal address is represented inside
27619
 
+   the square brackets without a preceding version flag.  The ABNF
27620
 
+   provided here is a translation of the text definition of an IPv6
27621
 
+   literal address provided in [RFC3513].  This syntax does not support
27622
 
+   IPv6 scoped addressing zone identifiers.
27623
 
+
27624
 
+
27625
 
+
27626
 
+
27627
 
+Berners-Lee, et al.         Standards Track                    [Page 19]
27628
 
+
27629
 
+RFC 3986                   URI Generic Syntax               January 2005
27630
 
+
27631
 
+
27632
 
+   A 128-bit IPv6 address is divided into eight 16-bit pieces.  Each
27633
 
+   piece is represented numerically in case-insensitive hexadecimal,
27634
 
+   using one to four hexadecimal digits (leading zeroes are permitted).
27635
 
+   The eight encoded pieces are given most-significant first, separated
27636
 
+   by colon characters.  Optionally, the least-significant two pieces
27637
 
+   may instead be represented in IPv4 address textual format.  A
27638
 
+   sequence of one or more consecutive zero-valued 16-bit pieces within
27639
 
+   the address may be elided, omitting all their digits and leaving
27640
 
+   exactly two consecutive colons in their place to mark the elision.
27641
 
+
27642
 
+      IPv6address =                            6( h16 ":" ) ls32
27643
 
+                  /                       "::" 5( h16 ":" ) ls32
27644
 
+                  / [               h16 ] "::" 4( h16 ":" ) ls32
27645
 
+                  / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32
27646
 
+                  / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32
27647
 
+                  / [ *3( h16 ":" ) h16 ] "::"    h16 ":"   ls32
27648
 
+                  / [ *4( h16 ":" ) h16 ] "::"              ls32
27649
 
+                  / [ *5( h16 ":" ) h16 ] "::"              h16
27650
 
+                  / [ *6( h16 ":" ) h16 ] "::"
27651
 
+
27652
 
+      ls32        = ( h16 ":" h16 ) / IPv4address
27653
 
+                  ; least-significant 32 bits of address
27654
 
+
27655
 
+      h16         = 1*4HEXDIG
27656
 
+                  ; 16 bits of address represented in hexadecimal
27657
 
+
27658
 
+   A host identified by an IPv4 literal address is represented in
27659
 
+   dotted-decimal notation (a sequence of four decimal numbers in the
27660
 
+   range 0 to 255, separated by "."), as described in [RFC1123] by
27661
 
+   reference to [RFC0952].  Note that other forms of dotted notation may
27662
 
+   be interpreted on some platforms, as described in Section 7.4, but
27663
 
+   only the dotted-decimal form of four octets is allowed by this
27664
 
+   grammar.
27665
 
+
27666
 
+      IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet
27667
 
+
27668
 
+      dec-octet   = DIGIT                 ; 0-9
27669
 
+                  / %x31-39 DIGIT         ; 10-99
27670
 
+                  / "1" 2DIGIT            ; 100-199
27671
 
+                  / "2" %x30-34 DIGIT     ; 200-249
27672
 
+                  / "25" %x30-35          ; 250-255
27673
 
+
27674
 
+   A host identified by a registered name is a sequence of characters
27675
 
+   usually intended for lookup within a locally defined host or service
27676
 
+   name registry, though the URI's scheme-specific semantics may require
27677
 
+   that a specific registry (or fixed name table) be used instead.  The
27678
 
+   most common name registry mechanism is the Domain Name System (DNS).
27679
 
+   A registered name intended for lookup in the DNS uses the syntax
27680
 
+
27681
 
+
27682
 
+
27683
 
+Berners-Lee, et al.         Standards Track                    [Page 20]
27684
 
+
27685
 
+RFC 3986                   URI Generic Syntax               January 2005
27686
 
+
27687
 
+
27688
 
+   defined in Section 3.5 of [RFC1034] and Section 2.1 of [RFC1123].
27689
 
+   Such a name consists of a sequence of domain labels separated by ".",
27690
 
+   each domain label starting and ending with an alphanumeric character
27691
 
+   and possibly also containing "-" characters.  The rightmost domain
27692
 
+   label of a fully qualified domain name in DNS may be followed by a
27693
 
+   single "." and should be if it is necessary to distinguish between
27694
 
+   the complete domain name and some local domain.
27695
 
+
27696
 
+      reg-name    = *( unreserved / pct-encoded / sub-delims )
27697
 
+
27698
 
+   If the URI scheme defines a default for host, then that default
27699
 
+   applies when the host subcomponent is undefined or when the
27700
 
+   registered name is empty (zero length).  For example, the "file" URI
27701
 
+   scheme is defined so that no authority, an empty host, and
27702
 
+   "localhost" all mean the end-user's machine, whereas the "http"
27703
 
+   scheme considers a missing authority or empty host invalid.
27704
 
+
27705
 
+   This specification does not mandate a particular registered name
27706
 
+   lookup technology and therefore does not restrict the syntax of reg-
27707
 
+   name beyond what is necessary for interoperability.  Instead, it
27708
 
+   delegates the issue of registered name syntax conformance to the
27709
 
+   operating system of each application performing URI resolution, and
27710
 
+   that operating system decides what it will allow for the purpose of
27711
 
+   host identification.  A URI resolution implementation might use DNS,
27712
 
+   host tables, yellow pages, NetInfo, WINS, or any other system for
27713
 
+   lookup of registered names.  However, a globally scoped naming
27714
 
+   system, such as DNS fully qualified domain names, is necessary for
27715
 
+   URIs intended to have global scope.  URI producers should use names
27716
 
+   that conform to the DNS syntax, even when use of DNS is not
27717
 
+   immediately apparent, and should limit these names to no more than
27718
 
+   255 characters in length.
27719
 
+
27720
 
+   The reg-name syntax allows percent-encoded octets in order to
27721
 
+   represent non-ASCII registered names in a uniform way that is
27722
 
+   independent of the underlying name resolution technology.  Non-ASCII
27723
 
+   characters must first be encoded according to UTF-8 [STD63], and then
27724
 
+   each octet of the corresponding UTF-8 sequence must be percent-
27725
 
+   encoded to be represented as URI characters.  URI producing
27726
 
+   applications must not use percent-encoding in host unless it is used
27727
 
+   to represent a UTF-8 character sequence.  When a non-ASCII registered
27728
 
+   name represents an internationalized domain name intended for
27729
 
+   resolution via the DNS, the name must be transformed to the IDNA
27730
 
+   encoding [RFC3490] prior to name lookup.  URI producers should
27731
 
+   provide these registered names in the IDNA encoding, rather than a
27732
 
+   percent-encoding, if they wish to maximize interoperability with
27733
 
+   legacy URI resolvers.
27734
 
+
27735
 
+
27736
 
+
27737
 
+
27738
 
+
27739
 
+Berners-Lee, et al.         Standards Track                    [Page 21]
27740
 
+
27741
 
+RFC 3986                   URI Generic Syntax               January 2005
27742
 
+
27743
 
+
27744
 
+3.2.3.  Port
27745
 
+
27746
 
+   The port subcomponent of authority is designated by an optional port
27747
 
+   number in decimal following the host and delimited from it by a
27748
 
+   single colon (":") character.
27749
 
+
27750
 
+      port        = *DIGIT
27751
 
+
27752
 
+   A scheme may define a default port.  For example, the "http" scheme
27753
 
+   defines a default port of "80", corresponding to its reserved TCP
27754
 
+   port number.  The type of port designated by the port number (e.g.,
27755
 
+   TCP, UDP, SCTP) is defined by the URI scheme.  URI producers and
27756
 
+   normalizers should omit the port component and its ":" delimiter if
27757
 
+   port is empty or if its value would be the same as that of the
27758
 
+   scheme's default.
27759
 
+
27760
 
+3.3.  Path
27761
 
+
27762
 
+   The path component contains data, usually organized in hierarchical
27763
 
+   form, that, along with data in the non-hierarchical query component
27764
 
+   (Section 3.4), serves to identify a resource within the scope of the
27765
 
+   URI's scheme and naming authority (if any).  The path is terminated
27766
 
+   by the first question mark ("?") or number sign ("#") character, or
27767
 
+   by the end of the URI.
27768
 
+
27769
 
+   If a URI contains an authority component, then the path component
27770
 
+   must either be empty or begin with a slash ("/") character.  If a URI
27771
 
+   does not contain an authority component, then the path cannot begin
27772
 
+   with two slash characters ("//").  In addition, a URI reference
27773
 
+   (Section 4.1) may be a relative-path reference, in which case the
27774
 
+   first path segment cannot contain a colon (":") character.  The ABNF
27775
 
+   requires five separate rules to disambiguate these cases, only one of
27776
 
+   which will match the path substring within a given URI reference.  We
27777
 
+   use the generic term "path component" to describe the URI substring
27778
 
+   matched by the parser to one of these rules.
27779
 
+
27780
 
+      path          = path-abempty    ; begins with "/" or is empty
27781
 
+                    / path-absolute   ; begins with "/" but not "//"
27782
 
+                    / path-noscheme   ; begins with a non-colon segment
27783
 
+                    / path-rootless   ; begins with a segment
27784
 
+                    / path-empty      ; zero characters
27785
 
+
27786
 
+      path-abempty  = *( "/" segment )
27787
 
+      path-absolute = "/" [ segment-nz *( "/" segment ) ]
27788
 
+      path-noscheme = segment-nz-nc *( "/" segment )
27789
 
+      path-rootless = segment-nz *( "/" segment )
27790
 
+      path-empty    = 0<pchar>
27791
 
+
27792
 
+
27793
 
+
27794
 
+
27795
 
+Berners-Lee, et al.         Standards Track                    [Page 22]
27796
 
+
27797
 
+RFC 3986                   URI Generic Syntax               January 2005
27798
 
+
27799
 
+
27800
 
+      segment       = *pchar
27801
 
+      segment-nz    = 1*pchar
27802
 
+      segment-nz-nc = 1*( unreserved / pct-encoded / sub-delims / "@" )
27803
 
+                    ; non-zero-length segment without any colon ":"
27804
 
+
27805
 
+      pchar         = unreserved / pct-encoded / sub-delims / ":" / "@"
27806
 
+
27807
 
+   A path consists of a sequence of path segments separated by a slash
27808
 
+   ("/") character.  A path is always defined for a URI, though the
27809
 
+   defined path may be empty (zero length).  Use of the slash character
27810
 
+   to indicate hierarchy is only required when a URI will be used as the
27811
 
+   context for relative references.  For example, the URI
27812
 
+   <mailto:fred@example.com> has a path of "fred@example.com", whereas
27813
 
+   the URI <foo://info.example.com?fred> has an empty path.
27814
 
+
27815
 
+   The path segments "." and "..", also known as dot-segments, are
27816
 
+   defined for relative reference within the path name hierarchy.  They
27817
 
+   are intended for use at the beginning of a relative-path reference
27818
 
+   (Section 4.2) to indicate relative position within the hierarchical
27819
 
+   tree of names.  This is similar to their role within some operating
27820
 
+   systems' file directory structures to indicate the current directory
27821
 
+   and parent directory, respectively.  However, unlike in a file
27822
 
+   system, these dot-segments are only interpreted within the URI path
27823
 
+   hierarchy and are removed as part of the resolution process (Section
27824
 
+   5.2).
27825
 
+
27826
 
+   Aside from dot-segments in hierarchical paths, a path segment is
27827
 
+   considered opaque by the generic syntax.  URI producing applications
27828
 
+   often use the reserved characters allowed in a segment to delimit
27829
 
+   scheme-specific or dereference-handler-specific subcomponents.  For
27830
 
+   example, the semicolon (";") and equals ("=") reserved characters are
27831
 
+   often used to delimit parameters and parameter values applicable to
27832
 
+   that segment.  The comma (",") reserved character is often used for
27833
 
+   similar purposes.  For example, one URI producer might use a segment
27834
 
+   such as "name;v=1.1" to indicate a reference to version 1.1 of
27835
 
+   "name", whereas another might use a segment such as "name,1.1" to
27836
 
+   indicate the same.  Parameter types may be defined by scheme-specific
27837
 
+   semantics, but in most cases the syntax of a parameter is specific to
27838
 
+   the implementation of the URI's dereferencing algorithm.
27839
 
+
27840
 
+3.4.  Query
27841
 
+
27842
 
+   The query component contains non-hierarchical data that, along with
27843
 
+   data in the path component (Section 3.3), serves to identify a
27844
 
+   resource within the scope of the URI's scheme and naming authority
27845
 
+   (if any).  The query component is indicated by the first question
27846
 
+   mark ("?") character and terminated by a number sign ("#") character
27847
 
+   or by the end of the URI.
27848
 
+
27849
 
+
27850
 
+
27851
 
+Berners-Lee, et al.         Standards Track                    [Page 23]
27852
 
+
27853
 
+RFC 3986                   URI Generic Syntax               January 2005
27854
 
+
27855
 
+
27856
 
+      query       = *( pchar / "/" / "?" )
27857
 
+
27858
 
+   The characters slash ("/") and question mark ("?") may represent data
27859
 
+   within the query component.  Beware that some older, erroneous
27860
 
+   implementations may not handle such data correctly when it is used as
27861
 
+   the base URI for relative references (Section 5.1), apparently
27862
 
+   because they fail to distinguish query data from path data when
27863
 
+   looking for hierarchical separators.  However, as query components
27864
 
+   are often used to carry identifying information in the form of
27865
 
+   "key=value" pairs and one frequently used value is a reference to
27866
 
+   another URI, it is sometimes better for usability to avoid percent-
27867
 
+   encoding those characters.
27868
 
+
27869
 
+3.5.  Fragment
27870
 
+
27871
 
+   The fragment identifier component of a URI allows indirect
27872
 
+   identification of a secondary resource by reference to a primary
27873
 
+   resource and additional identifying information.  The identified
27874
 
+   secondary resource may be some portion or subset of the primary
27875
 
+   resource, some view on representations of the primary resource, or
27876
 
+   some other resource defined or described by those representations.  A
27877
 
+   fragment identifier component is indicated by the presence of a
27878
 
+   number sign ("#") character and terminated by the end of the URI.
27879
 
+
27880
 
+      fragment    = *( pchar / "/" / "?" )
27881
 
+
27882
 
+   The semantics of a fragment identifier are defined by the set of
27883
 
+   representations that might result from a retrieval action on the
27884
 
+   primary resource.  The fragment's format and resolution is therefore
27885
 
+   dependent on the media type [RFC2046] of a potentially retrieved
27886
 
+   representation, even though such a retrieval is only performed if the
27887
 
+   URI is dereferenced.  If no such representation exists, then the
27888
 
+   semantics of the fragment are considered unknown and are effectively
27889
 
+   unconstrained.  Fragment identifier semantics are independent of the
27890
 
+   URI scheme and thus cannot be redefined by scheme specifications.
27891
 
+
27892
 
+   Individual media types may define their own restrictions on or
27893
 
+   structures within the fragment identifier syntax for specifying
27894
 
+   different types of subsets, views, or external references that are
27895
 
+   identifiable as secondary resources by that media type.  If the
27896
 
+   primary resource has multiple representations, as is often the case
27897
 
+   for resources whose representation is selected based on attributes of
27898
 
+   the retrieval request (a.k.a., content negotiation), then whatever is
27899
 
+   identified by the fragment should be consistent across all of those
27900
 
+   representations.  Each representation should either define the
27901
 
+   fragment so that it corresponds to the same secondary resource,
27902
 
+   regardless of how it is represented, or should leave the fragment
27903
 
+   undefined (i.e., not found).
27904
 
+
27905
 
+
27906
 
+
27907
 
+Berners-Lee, et al.         Standards Track                    [Page 24]
27908
 
+
27909
 
+RFC 3986                   URI Generic Syntax               January 2005
27910
 
+
27911
 
+
27912
 
+   As with any URI, use of a fragment identifier component does not
27913
 
+   imply that a retrieval action will take place.  A URI with a fragment
27914
 
+   identifier may be used to refer to the secondary resource without any
27915
 
+   implication that the primary resource is accessible or will ever be
27916
 
+   accessed.
27917
 
+
27918
 
+   Fragment identifiers have a special role in information retrieval
27919
 
+   systems as the primary form of client-side indirect referencing,
27920
 
+   allowing an author to specifically identify aspects of an existing
27921
 
+   resource that are only indirectly provided by the resource owner.  As
27922
 
+   such, the fragment identifier is not used in the scheme-specific
27923
 
+   processing of a URI; instead, the fragment identifier is separated
27924
 
+   from the rest of the URI prior to a dereference, and thus the
27925
 
+   identifying information within the fragment itself is dereferenced
27926
 
+   solely by the user agent, regardless of the URI scheme.  Although
27927
 
+   this separate handling is often perceived to be a loss of
27928
 
+   information, particularly for accurate redirection of references as
27929
 
+   resources move over time, it also serves to prevent information
27930
 
+   providers from denying reference authors the right to refer to
27931
 
+   information within a resource selectively.  Indirect referencing also
27932
 
+   provides additional flexibility and extensibility to systems that use
27933
 
+   URIs, as new media types are easier to define and deploy than new
27934
 
+   schemes of identification.
27935
 
+
27936
 
+   The characters slash ("/") and question mark ("?") are allowed to
27937
 
+   represent data within the fragment identifier.  Beware that some
27938
 
+   older, erroneous implementations may not handle this data correctly
27939
 
+   when it is used as the base URI for relative references (Section
27940
 
+   5.1).
27941
 
+
27942
 
+4.  Usage
27943
 
+
27944
 
+   When applications make reference to a URI, they do not always use the
27945
 
+   full form of reference defined by the "URI" syntax rule.  To save
27946
 
+   space and take advantage of hierarchical locality, many Internet
27947
 
+   protocol elements and media type formats allow an abbreviation of a
27948
 
+   URI, whereas others restrict the syntax to a particular form of URI.
27949
 
+   We define the most common forms of reference syntax in this
27950
 
+   specification because they impact and depend upon the design of the
27951
 
+   generic syntax, requiring a uniform parsing algorithm in order to be
27952
 
+   interpreted consistently.
27953
 
+
27954
 
+4.1.  URI Reference
27955
 
+
27956
 
+   URI-reference is used to denote the most common usage of a resource
27957
 
+   identifier.
27958
 
+
27959
 
+      URI-reference = URI / relative-ref
27960
 
+
27961
 
+
27962
 
+
27963
 
+Berners-Lee, et al.         Standards Track                    [Page 25]
27964
 
+
27965
 
+RFC 3986                   URI Generic Syntax               January 2005
27966
 
+
27967
 
+
27968
 
+   A URI-reference is either a URI or a relative reference.  If the
27969
 
+   URI-reference's prefix does not match the syntax of a scheme followed
27970
 
+   by its colon separator, then the URI-reference is a relative
27971
 
+   reference.
27972
 
+
27973
 
+   A URI-reference is typically parsed first into the five URI
27974
 
+   components, in order to determine what components are present and
27975
 
+   whether the reference is relative.  Then, each component is parsed
27976
 
+   for its subparts and their validation.  The ABNF of URI-reference,
27977
 
+   along with the "first-match-wins" disambiguation rule, is sufficient
27978
 
+   to define a validating parser for the generic syntax.  Readers
27979
 
+   familiar with regular expressions should see Appendix B for an
27980
 
+   example of a non-validating URI-reference parser that will take any
27981
 
+   given string and extract the URI components.
27982
 
+
27983
 
+4.2.  Relative Reference
27984
 
+
27985
 
+   A relative reference takes advantage of the hierarchical syntax
27986
 
+   (Section 1.2.3) to express a URI reference relative to the name space
27987
 
+   of another hierarchical URI.
27988
 
+
27989
 
+      relative-ref  = relative-part [ "?" query ] [ "#" fragment ]
27990
 
+
27991
 
+      relative-part = "//" authority path-abempty
27992
 
+                    / path-absolute
27993
 
+                    / path-noscheme
27994
 
+                    / path-empty
27995
 
+
27996
 
+   The URI referred to by a relative reference, also known as the target
27997
 
+   URI, is obtained by applying the reference resolution algorithm of
27998
 
+   Section 5.
27999
 
+
28000
 
+   A relative reference that begins with two slash characters is termed
28001
 
+   a network-path reference; such references are rarely used.  A
28002
 
+   relative reference that begins with a single slash character is
28003
 
+   termed an absolute-path reference.  A relative reference that does
28004
 
+   not begin with a slash character is termed a relative-path reference.
28005
 
+
28006
 
+   A path segment that contains a colon character (e.g., "this:that")
28007
 
+   cannot be used as the first segment of a relative-path reference, as
28008
 
+   it would be mistaken for a scheme name.  Such a segment must be
28009
 
+   preceded by a dot-segment (e.g., "./this:that") to make a relative-
28010
 
+   path reference.
28011
 
+
28012
 
+
28013
 
+
28014
 
+
28015
 
+
28016
 
+
28017
 
+
28018
 
+
28019
 
+Berners-Lee, et al.         Standards Track                    [Page 26]
28020
 
+
28021
 
+RFC 3986                   URI Generic Syntax               January 2005
28022
 
+
28023
 
+
28024
 
+4.3.  Absolute URI
28025
 
+
28026
 
+   Some protocol elements allow only the absolute form of a URI without
28027
 
+   a fragment identifier.  For example, defining a base URI for later
28028
 
+   use by relative references calls for an absolute-URI syntax rule that
28029
 
+   does not allow a fragment.
28030
 
+
28031
 
+      absolute-URI  = scheme ":" hier-part [ "?" query ]
28032
 
+
28033
 
+   URI scheme specifications must define their own syntax so that all
28034
 
+   strings matching their scheme-specific syntax will also match the
28035
 
+   <absolute-URI> grammar.  Scheme specifications will not define
28036
 
+   fragment identifier syntax or usage, regardless of its applicability
28037
 
+   to resources identifiable via that scheme, as fragment identification
28038
 
+   is orthogonal to scheme definition.  However, scheme specifications
28039
 
+   are encouraged to include a wide range of examples, including
28040
 
+   examples that show use of the scheme's URIs with fragment identifiers
28041
 
+   when such usage is appropriate.
28042
 
+
28043
 
+4.4.  Same-Document Reference
28044
 
+
28045
 
+   When a URI reference refers to a URI that is, aside from its fragment
28046
 
+   component (if any), identical to the base URI (Section 5.1), that
28047
 
+   reference is called a "same-document" reference.  The most frequent
28048
 
+   examples of same-document references are relative references that are
28049
 
+   empty or include only the number sign ("#") separator followed by a
28050
 
+   fragment identifier.
28051
 
+
28052
 
+   When a same-document reference is dereferenced for a retrieval
28053
 
+   action, the target of that reference is defined to be within the same
28054
 
+   entity (representation, document, or message) as the reference;
28055
 
+   therefore, a dereference should not result in a new retrieval action.
28056
 
+
28057
 
+   Normalization of the base and target URIs prior to their comparison,
28058
 
+   as described in Sections 6.2.2 and 6.2.3, is allowed but rarely
28059
 
+   performed in practice.  Normalization may increase the set of same-
28060
 
+   document references, which may be of benefit to some caching
28061
 
+   applications.  As such, reference authors should not assume that a
28062
 
+   slightly different, though equivalent, reference URI will (or will
28063
 
+   not) be interpreted as a same-document reference by any given
28064
 
+   application.
28065
 
+
28066
 
+4.5.  Suffix Reference
28067
 
+
28068
 
+   The URI syntax is designed for unambiguous reference to resources and
28069
 
+   extensibility via the URI scheme.  However, as URI identification and
28070
 
+   usage have become commonplace, traditional media (television, radio,
28071
 
+   newspapers, billboards, etc.) have increasingly used a suffix of the
28072
 
+
28073
 
+
28074
 
+
28075
 
+Berners-Lee, et al.         Standards Track                    [Page 27]
28076
 
+
28077
 
+RFC 3986                   URI Generic Syntax               January 2005
28078
 
+
28079
 
+
28080
 
+   URI as a reference, consisting of only the authority and path
28081
 
+   portions of the URI, such as
28082
 
+
28083
 
+      www.w3.org/Addressing/
28084
 
+
28085
 
+   or simply a DNS registered name on its own.  Such references are
28086
 
+   primarily intended for human interpretation rather than for machines,
28087
 
+   with the assumption that context-based heuristics are sufficient to
28088
 
+   complete the URI (e.g., most registered names beginning with "www"
28089
 
+   are likely to have a URI prefix of "http://").  Although there is no
28090
 
+   standard set of heuristics for disambiguating a URI suffix, many
28091
 
+   client implementations allow them to be entered by the user and
28092
 
+   heuristically resolved.
28093
 
+
28094
 
+   Although this practice of using suffix references is common, it
28095
 
+   should be avoided whenever possible and should never be used in
28096
 
+   situations where long-term references are expected.  The heuristics
28097
 
+   noted above will change over time, particularly when a new URI scheme
28098
 
+   becomes popular, and are often incorrect when used out of context.
28099
 
+   Furthermore, they can lead to security issues along the lines of
28100
 
+   those described in [RFC1535].
28101
 
+
28102
 
+   As a URI suffix has the same syntax as a relative-path reference, a
28103
 
+   suffix reference cannot be used in contexts where a relative
28104
 
+   reference is expected.  As a result, suffix references are limited to
28105
 
+   places where there is no defined base URI, such as dialog boxes and
28106
 
+   off-line advertisements.
28107
 
+
28108
 
+5.  Reference Resolution
28109
 
+
28110
 
+   This section defines the process of resolving a URI reference within
28111
 
+   a context that allows relative references so that the result is a
28112
 
+   string matching the <URI> syntax rule of Section 3.
28113
 
+
28114
 
+5.1.  Establishing a Base URI
28115
 
+
28116
 
+   The term "relative" implies that a "base URI" exists against which
28117
 
+   the relative reference is applied.  Aside from fragment-only
28118
 
+   references (Section 4.4), relative references are only usable when a
28119
 
+   base URI is known.  A base URI must be established by the parser
28120
 
+   prior to parsing URI references that might be relative.  A base URI
28121
 
+   must conform to the <absolute-URI> syntax rule (Section 4.3).  If the
28122
 
+   base URI is obtained from a URI reference, then that reference must
28123
 
+   be converted to absolute form and stripped of any fragment component
28124
 
+   prior to its use as a base URI.
28125
 
+
28126
 
+
28127
 
+
28128
 
+
28129
 
+
28130
 
+
28131
 
+Berners-Lee, et al.         Standards Track                    [Page 28]
28132
 
+
28133
 
+RFC 3986                   URI Generic Syntax               January 2005
28134
 
+
28135
 
+
28136
 
+   The base URI of a reference can be established in one of four ways,
28137
 
+   discussed below in order of precedence.  The order of precedence can
28138
 
+   be thought of in terms of layers, where the innermost defined base
28139
 
+   URI has the highest precedence.  This can be visualized graphically
28140
 
+   as follows:
28141
 
+
28142
 
+         .----------------------------------------------------------.
28143
 
+         |  .----------------------------------------------------.  |
28144
 
+         |  |  .----------------------------------------------.  |  |
28145
 
+         |  |  |  .----------------------------------------.  |  |  |
28146
 
+         |  |  |  |  .----------------------------------.  |  |  |  |
28147
 
+         |  |  |  |  |       <relative-reference>       |  |  |  |  |
28148
 
+         |  |  |  |  `----------------------------------'  |  |  |  |
28149
 
+         |  |  |  | (5.1.1) Base URI embedded in content   |  |  |  |
28150
 
+         |  |  |  `----------------------------------------'  |  |  |
28151
 
+         |  |  | (5.1.2) Base URI of the encapsulating entity |  |  |
28152
 
+         |  |  |         (message, representation, or none)   |  |  |
28153
 
+         |  |  `----------------------------------------------'  |  |
28154
 
+         |  | (5.1.3) URI used to retrieve the entity            |  |
28155
 
+         |  `----------------------------------------------------'  |
28156
 
+         | (5.1.4) Default Base URI (application-dependent)         |
28157
 
+         `----------------------------------------------------------'
28158
 
+
28159
 
+5.1.1.  Base URI Embedded in Content
28160
 
+
28161
 
+   Within certain media types, a base URI for relative references can be
28162
 
+   embedded within the content itself so that it can be readily obtained
28163
 
+   by a parser.  This can be useful for descriptive documents, such as
28164
 
+   tables of contents, which may be transmitted to others through
28165
 
+   protocols other than their usual retrieval context (e.g., email or
28166
 
+   USENET news).
28167
 
+
28168
 
+   It is beyond the scope of this specification to specify how, for each
28169
 
+   media type, a base URI can be embedded.  The appropriate syntax, when
28170
 
+   available, is described by the data format specification associated
28171
 
+   with each media type.
28172
 
+
28173
 
+5.1.2.  Base URI from the Encapsulating Entity
28174
 
+
28175
 
+   If no base URI is embedded, the base URI is defined by the
28176
 
+   representation's retrieval context.  For a document that is enclosed
28177
 
+   within another entity, such as a message or archive, the retrieval
28178
 
+   context is that entity.  Thus, the default base URI of a
28179
 
+   representation is the base URI of the entity in which the
28180
 
+   representation is encapsulated.
28181
 
+
28182
 
+
28183
 
+
28184
 
+
28185
 
+
28186
 
+
28187
 
+Berners-Lee, et al.         Standards Track                    [Page 29]
28188
 
+
28189
 
+RFC 3986                   URI Generic Syntax               January 2005
28190
 
+
28191
 
+
28192
 
+   A mechanism for embedding a base URI within MIME container types
28193
 
+   (e.g., the message and multipart types) is defined by MHTML
28194
 
+   [RFC2557].  Protocols that do not use the MIME message header syntax,
28195
 
+   but that do allow some form of tagged metadata to be included within
28196
 
+   messages, may define their own syntax for defining a base URI as part
28197
 
+   of a message.
28198
 
+
28199
 
+5.1.3.  Base URI from the Retrieval URI
28200
 
+
28201
 
+   If no base URI is embedded and the representation is not encapsulated
28202
 
+   within some other entity, then, if a URI was used to retrieve the
28203
 
+   representation, that URI shall be considered the base URI.  Note that
28204
 
+   if the retrieval was the result of a redirected request, the last URI
28205
 
+   used (i.e., the URI that resulted in the actual retrieval of the
28206
 
+   representation) is the base URI.
28207
 
+
28208
 
+5.1.4.  Default Base URI
28209
 
+
28210
 
+   If none of the conditions described above apply, then the base URI is
28211
 
+   defined by the context of the application.  As this definition is
28212
 
+   necessarily application-dependent, failing to define a base URI by
28213
 
+   using one of the other methods may result in the same content being
28214
 
+   interpreted differently by different types of applications.
28215
 
+
28216
 
+   A sender of a representation containing relative references is
28217
 
+   responsible for ensuring that a base URI for those references can be
28218
 
+   established.  Aside from fragment-only references, relative
28219
 
+   references can only be used reliably in situations where the base URI
28220
 
+   is well defined.
28221
 
+
28222
 
+5.2.  Relative Resolution
28223
 
+
28224
 
+   This section describes an algorithm for converting a URI reference
28225
 
+   that might be relative to a given base URI into the parsed components
28226
 
+   of the reference's target.  The components can then be recomposed, as
28227
 
+   described in Section 5.3, to form the target URI.  This algorithm
28228
 
+   provides definitive results that can be used to test the output of
28229
 
+   other implementations.  Applications may implement relative reference
28230
 
+   resolution by using some other algorithm, provided that the results
28231
 
+   match what would be given by this one.
28232
 
+
28233
 
+
28234
 
+
28235
 
+
28236
 
+
28237
 
+
28238
 
+
28239
 
+
28240
 
+
28241
 
+
28242
 
+
28243
 
+Berners-Lee, et al.         Standards Track                    [Page 30]
28244
 
+
28245
 
+RFC 3986                   URI Generic Syntax               January 2005
28246
 
+
28247
 
+
28248
 
+5.2.1.  Pre-parse the Base URI
28249
 
+
28250
 
+   The base URI (Base) is established according to the procedure of
28251
 
+   Section 5.1 and parsed into the five main components described in
28252
 
+   Section 3.  Note that only the scheme component is required to be
28253
 
+   present in a base URI; the other components may be empty or
28254
 
+   undefined.  A component is undefined if its associated delimiter does
28255
 
+   not appear in the URI reference; the path component is never
28256
 
+   undefined, though it may be empty.
28257
 
+
28258
 
+   Normalization of the base URI, as described in Sections 6.2.2 and
28259
 
+   6.2.3, is optional.  A URI reference must be transformed to its
28260
 
+   target URI before it can be normalized.
28261
 
+
28262
 
+5.2.2.  Transform References
28263
 
+
28264
 
+   For each URI reference (R), the following pseudocode describes an
28265
 
+   algorithm for transforming R into its target URI (T):
28266
 
+
28267
 
+      -- The URI reference is parsed into the five URI components
28268
 
+      --
28269
 
+      (R.scheme, R.authority, R.path, R.query, R.fragment) = parse(R);
28270
 
+
28271
 
+      -- A non-strict parser may ignore a scheme in the reference
28272
 
+      -- if it is identical to the base URI's scheme.
28273
 
+      --
28274
 
+      if ((not strict) and (R.scheme == Base.scheme)) then
28275
 
+         undefine(R.scheme);
28276
 
+      endif;
28277
 
+
28278
 
+
28279
 
+
28280
 
+
28281
 
+
28282
 
+
28283
 
+
28284
 
+
28285
 
+
28286
 
+
28287
 
+
28288
 
+
28289
 
+
28290
 
+
28291
 
+
28292
 
+
28293
 
+
28294
 
+
28295
 
+
28296
 
+
28297
 
+
28298
 
+
28299
 
+Berners-Lee, et al.         Standards Track                    [Page 31]
28300
 
+
28301
 
+RFC 3986                   URI Generic Syntax               January 2005
28302
 
+
28303
 
+
28304
 
+      if defined(R.scheme) then
28305
 
+         T.scheme    = R.scheme;
28306
 
+         T.authority = R.authority;
28307
 
+         T.path      = remove_dot_segments(R.path);
28308
 
+         T.query     = R.query;
28309
 
+      else
28310
 
+         if defined(R.authority) then
28311
 
+            T.authority = R.authority;
28312
 
+            T.path      = remove_dot_segments(R.path);
28313
 
+            T.query     = R.query;
28314
 
+         else
28315
 
+            if (R.path == "") then
28316
 
+               T.path = Base.path;
28317
 
+               if defined(R.query) then
28318
 
+                  T.query = R.query;
28319
 
+               else
28320
 
+                  T.query = Base.query;
28321
 
+               endif;
28322
 
+            else
28323
 
+               if (R.path starts-with "/") then
28324
 
+                  T.path = remove_dot_segments(R.path);
28325
 
+               else
28326
 
+                  T.path = merge(Base.path, R.path);
28327
 
+                  T.path = remove_dot_segments(T.path);
28328
 
+               endif;
28329
 
+               T.query = R.query;
28330
 
+            endif;
28331
 
+            T.authority = Base.authority;
28332
 
+         endif;
28333
 
+         T.scheme = Base.scheme;
28334
 
+      endif;
28335
 
+
28336
 
+      T.fragment = R.fragment;
28337
 
+
28338
 
+5.2.3.  Merge Paths
28339
 
+
28340
 
+   The pseudocode above refers to a "merge" routine for merging a
28341
 
+   relative-path reference with the path of the base URI.  This is
28342
 
+   accomplished as follows:
28343
 
+
28344
 
+   o  If the base URI has a defined authority component and an empty
28345
 
+      path, then return a string consisting of "/" concatenated with the
28346
 
+      reference's path; otherwise,
28347
 
+
28348
 
+
28349
 
+
28350
 
+
28351
 
+
28352
 
+
28353
 
+
28354
 
+
28355
 
+Berners-Lee, et al.         Standards Track                    [Page 32]
28356
 
+
28357
 
+RFC 3986                   URI Generic Syntax               January 2005
28358
 
+
28359
 
+
28360
 
+   o  return a string consisting of the reference's path component
28361
 
+      appended to all but the last segment of the base URI's path (i.e.,
28362
 
+      excluding any characters after the right-most "/" in the base URI
28363
 
+      path, or excluding the entire base URI path if it does not contain
28364
 
+      any "/" characters).
28365
 
+
28366
 
+5.2.4.  Remove Dot Segments
28367
 
+
28368
 
+   The pseudocode also refers to a "remove_dot_segments" routine for
28369
 
+   interpreting and removing the special "." and ".." complete path
28370
 
+   segments from a referenced path.  This is done after the path is
28371
 
+   extracted from a reference, whether or not the path was relative, in
28372
 
+   order to remove any invalid or extraneous dot-segments prior to
28373
 
+   forming the target URI.  Although there are many ways to accomplish
28374
 
+   this removal process, we describe a simple method using two string
28375
 
+   buffers.
28376
 
+
28377
 
+   1.  The input buffer is initialized with the now-appended path
28378
 
+       components and the output buffer is initialized to the empty
28379
 
+       string.
28380
 
+
28381
 
+   2.  While the input buffer is not empty, loop as follows:
28382
 
+
28383
 
+       A.  If the input buffer begins with a prefix of "../" or "./",
28384
 
+           then remove that prefix from the input buffer; otherwise,
28385
 
+
28386
 
+       B.  if the input buffer begins with a prefix of "/./" or "/.",
28387
 
+           where "." is a complete path segment, then replace that
28388
 
+           prefix with "/" in the input buffer; otherwise,
28389
 
+
28390
 
+       C.  if the input buffer begins with a prefix of "/../" or "/..",
28391
 
+           where ".." is a complete path segment, then replace that
28392
 
+           prefix with "/" in the input buffer and remove the last
28393
 
+           segment and its preceding "/" (if any) from the output
28394
 
+           buffer; otherwise,
28395
 
+
28396
 
+       D.  if the input buffer consists only of "." or "..", then remove
28397
 
+           that from the input buffer; otherwise,
28398
 
+
28399
 
+       E.  move the first path segment in the input buffer to the end of
28400
 
+           the output buffer, including the initial "/" character (if
28401
 
+           any) and any subsequent characters up to, but not including,
28402
 
+           the next "/" character or the end of the input buffer.
28403
 
+
28404
 
+   3.  Finally, the output buffer is returned as the result of
28405
 
+       remove_dot_segments.
28406
 
+
28407
 
+
28408
 
+
28409
 
+
28410
 
+
28411
 
+Berners-Lee, et al.         Standards Track                    [Page 33]
28412
 
+
28413
 
+RFC 3986                   URI Generic Syntax               January 2005
28414
 
+
28415
 
+
28416
 
+   Note that dot-segments are intended for use in URI references to
28417
 
+   express an identifier relative to the hierarchy of names in the base
28418
 
+   URI.  The remove_dot_segments algorithm respects that hierarchy by
28419
 
+   removing extra dot-segments rather than treat them as an error or
28420
 
+   leaving them to be misinterpreted by dereference implementations.
28421
 
+
28422
 
+   The following illustrates how the above steps are applied for two
28423
 
+   examples of merged paths, showing the state of the two buffers after
28424
 
+   each step.
28425
 
+
28426
 
+      STEP   OUTPUT BUFFER         INPUT BUFFER
28427
 
+
28428
 
+       1 :                         /a/b/c/./../../g
28429
 
+       2E:   /a                    /b/c/./../../g
28430
 
+       2E:   /a/b                  /c/./../../g
28431
 
+       2E:   /a/b/c                /./../../g
28432
 
+       2B:   /a/b/c                /../../g
28433
 
+       2C:   /a/b                  /../g
28434
 
+       2C:   /a                    /g
28435
 
+       2E:   /a/g
28436
 
+
28437
 
+      STEP   OUTPUT BUFFER         INPUT BUFFER
28438
 
+
28439
 
+       1 :                         mid/content=5/../6
28440
 
+       2E:   mid                   /content=5/../6
28441
 
+       2E:   mid/content=5         /../6
28442
 
+       2C:   mid                   /6
28443
 
+       2E:   mid/6
28444
 
+
28445
 
+   Some applications may find it more efficient to implement the
28446
 
+   remove_dot_segments algorithm by using two segment stacks rather than
28447
 
+   strings.
28448
 
+
28449
 
+      Note: Beware that some older, erroneous implementations will fail
28450
 
+      to separate a reference's query component from its path component
28451
 
+      prior to merging the base and reference paths, resulting in an
28452
 
+      interoperability failure if the query component contains the
28453
 
+      strings "/../" or "/./".
28454
 
+
28455
 
+
28456
 
+
28457
 
+
28458
 
+
28459
 
+
28460
 
+
28461
 
+
28462
 
+
28463
 
+
28464
 
+
28465
 
+
28466
 
+
28467
 
+Berners-Lee, et al.         Standards Track                    [Page 34]
28468
 
+
28469
 
+RFC 3986                   URI Generic Syntax               January 2005
28470
 
+
28471
 
+
28472
 
+5.3.  Component Recomposition
28473
 
+
28474
 
+   Parsed URI components can be recomposed to obtain the corresponding
28475
 
+   URI reference string.  Using pseudocode, this would be:
28476
 
+
28477
 
+      result = ""
28478
 
+
28479
 
+      if defined(scheme) then
28480
 
+         append scheme to result;
28481
 
+         append ":" to result;
28482
 
+      endif;
28483
 
+
28484
 
+      if defined(authority) then
28485
 
+         append "//" to result;
28486
 
+         append authority to result;
28487
 
+      endif;
28488
 
+
28489
 
+      append path to result;
28490
 
+
28491
 
+      if defined(query) then
28492
 
+         append "?" to result;
28493
 
+         append query to result;
28494
 
+      endif;
28495
 
+
28496
 
+      if defined(fragment) then
28497
 
+         append "#" to result;
28498
 
+         append fragment to result;
28499
 
+      endif;
28500
 
+
28501
 
+      return result;
28502
 
+
28503
 
+   Note that we are careful to preserve the distinction between a
28504
 
+   component that is undefined, meaning that its separator was not
28505
 
+   present in the reference, and a component that is empty, meaning that
28506
 
+   the separator was present and was immediately followed by the next
28507
 
+   component separator or the end of the reference.
28508
 
+
28509
 
+5.4.  Reference Resolution Examples
28510
 
+
28511
 
+   Within a representation with a well defined base URI of
28512
 
+
28513
 
+      http://a/b/c/d;p?q
28514
 
+
28515
 
+   a relative reference is transformed to its target URI as follows.
28516
 
+
28517
 
+
28518
 
+
28519
 
+
28520
 
+
28521
 
+
28522
 
+
28523
 
+Berners-Lee, et al.         Standards Track                    [Page 35]
28524
 
+
28525
 
+RFC 3986                   URI Generic Syntax               January 2005
28526
 
+
28527
 
+
28528
 
+5.4.1.  Normal Examples
28529
 
+
28530
 
+      "g:h"           =  "g:h"
28531
 
+      "g"             =  "http://a/b/c/g"
28532
 
+      "./g"           =  "http://a/b/c/g"
28533
 
+      "g/"            =  "http://a/b/c/g/"
28534
 
+      "/g"            =  "http://a/g"
28535
 
+      "//g"           =  "http://g"
28536
 
+      "?y"            =  "http://a/b/c/d;p?y"
28537
 
+      "g?y"           =  "http://a/b/c/g?y"
28538
 
+      "#s"            =  "http://a/b/c/d;p?q#s"
28539
 
+      "g#s"           =  "http://a/b/c/g#s"
28540
 
+      "g?y#s"         =  "http://a/b/c/g?y#s"
28541
 
+      ";x"            =  "http://a/b/c/;x"
28542
 
+      "g;x"           =  "http://a/b/c/g;x"
28543
 
+      "g;x?y#s"       =  "http://a/b/c/g;x?y#s"
28544
 
+      ""              =  "http://a/b/c/d;p?q"
28545
 
+      "."             =  "http://a/b/c/"
28546
 
+      "./"            =  "http://a/b/c/"
28547
 
+      ".."            =  "http://a/b/"
28548
 
+      "../"           =  "http://a/b/"
28549
 
+      "../g"          =  "http://a/b/g"
28550
 
+      "../.."         =  "http://a/"
28551
 
+      "../../"        =  "http://a/"
28552
 
+      "../../g"       =  "http://a/g"
28553
 
+
28554
 
+5.4.2.  Abnormal Examples
28555
 
+
28556
 
+   Although the following abnormal examples are unlikely to occur in
28557
 
+   normal practice, all URI parsers should be capable of resolving them
28558
 
+   consistently.  Each example uses the same base as that above.
28559
 
+
28560
 
+   Parsers must be careful in handling cases where there are more ".."
28561
 
+   segments in a relative-path reference than there are hierarchical
28562
 
+   levels in the base URI's path.  Note that the ".." syntax cannot be
28563
 
+   used to change the authority component of a URI.
28564
 
+
28565
 
+      "../../../g"    =  "http://a/g"
28566
 
+      "../../../../g" =  "http://a/g"
28567
 
+
28568
 
+
28569
 
+
28570
 
+
28571
 
+
28572
 
+
28573
 
+
28574
 
+
28575
 
+
28576
 
+
28577
 
+
28578
 
+
28579
 
+Berners-Lee, et al.         Standards Track                    [Page 36]
28580
 
+
28581
 
+RFC 3986                   URI Generic Syntax               January 2005
28582
 
+
28583
 
+
28584
 
+   Similarly, parsers must remove the dot-segments "." and ".." when
28585
 
+   they are complete components of a path, but not when they are only
28586
 
+   part of a segment.
28587
 
+
28588
 
+      "/./g"          =  "http://a/g"
28589
 
+      "/../g"         =  "http://a/g"
28590
 
+      "g."            =  "http://a/b/c/g."
28591
 
+      ".g"            =  "http://a/b/c/.g"
28592
 
+      "g.."           =  "http://a/b/c/g.."
28593
 
+      "..g"           =  "http://a/b/c/..g"
28594
 
+
28595
 
+   Less likely are cases where the relative reference uses unnecessary
28596
 
+   or nonsensical forms of the "." and ".." complete path segments.
28597
 
+
28598
 
+      "./../g"        =  "http://a/b/g"
28599
 
+      "./g/."         =  "http://a/b/c/g/"
28600
 
+      "g/./h"         =  "http://a/b/c/g/h"
28601
 
+      "g/../h"        =  "http://a/b/c/h"
28602
 
+      "g;x=1/./y"     =  "http://a/b/c/g;x=1/y"
28603
 
+      "g;x=1/../y"    =  "http://a/b/c/y"
28604
 
+
28605
 
+   Some applications fail to separate the reference's query and/or
28606
 
+   fragment components from the path component before merging it with
28607
 
+   the base path and removing dot-segments.  This error is rarely
28608
 
+   noticed, as typical usage of a fragment never includes the hierarchy
28609
 
+   ("/") character and the query component is not normally used within
28610
 
+   relative references.
28611
 
+
28612
 
+      "g?y/./x"       =  "http://a/b/c/g?y/./x"
28613
 
+      "g?y/../x"      =  "http://a/b/c/g?y/../x"
28614
 
+      "g#s/./x"       =  "http://a/b/c/g#s/./x"
28615
 
+      "g#s/../x"      =  "http://a/b/c/g#s/../x"
28616
 
+
28617
 
+   Some parsers allow the scheme name to be present in a relative
28618
 
+   reference if it is the same as the base URI scheme.  This is
28619
 
+   considered to be a loophole in prior specifications of partial URI
28620
 
+   [RFC1630].  Its use should be avoided but is allowed for backward
28621
 
+   compatibility.
28622
 
+
28623
 
+      "http:g"        =  "http:g"         ; for strict parsers
28624
 
+                      /  "http://a/b/c/g" ; for backward compatibility
28625
 
+
28626
 
+
28627
 
+
28628
 
+
28629
 
+
28630
 
+
28631
 
+
28632
 
+
28633
 
+
28634
 
+
28635
 
+Berners-Lee, et al.         Standards Track                    [Page 37]
28636
 
+
28637
 
+RFC 3986                   URI Generic Syntax               January 2005
28638
 
+
28639
 
+
28640
 
+6.  Normalization and Comparison
28641
 
+
28642
 
+   One of the most common operations on URIs is simple comparison:
28643
 
+   determining whether two URIs are equivalent without using the URIs to
28644
 
+   access their respective resource(s).  A comparison is performed every
28645
 
+   time a response cache is accessed, a browser checks its history to
28646
 
+   color a link, or an XML parser processes tags within a namespace.
28647
 
+   Extensive normalization prior to comparison of URIs is often used by
28648
 
+   spiders and indexing engines to prune a search space or to reduce
28649
 
+   duplication of request actions and response storage.
28650
 
+
28651
 
+   URI comparison is performed for some particular purpose.  Protocols
28652
 
+   or implementations that compare URIs for different purposes will
28653
 
+   often be subject to differing design trade-offs in regards to how
28654
 
+   much effort should be spent in reducing aliased identifiers.  This
28655
 
+   section describes various methods that may be used to compare URIs,
28656
 
+   the trade-offs between them, and the types of applications that might
28657
 
+   use them.
28658
 
+
28659
 
+6.1.  Equivalence
28660
 
+
28661
 
+   Because URIs exist to identify resources, presumably they should be
28662
 
+   considered equivalent when they identify the same resource.  However,
28663
 
+   this definition of equivalence is not of much practical use, as there
28664
 
+   is no way for an implementation to compare two resources unless it
28665
 
+   has full knowledge or control of them.  For this reason,
28666
 
+   determination of equivalence or difference of URIs is based on string
28667
 
+   comparison, perhaps augmented by reference to additional rules
28668
 
+   provided by URI scheme definitions.  We use the terms "different" and
28669
 
+   "equivalent" to describe the possible outcomes of such comparisons,
28670
 
+   but there are many application-dependent versions of equivalence.
28671
 
+
28672
 
+   Even though it is possible to determine that two URIs are equivalent,
28673
 
+   URI comparison is not sufficient to determine whether two URIs
28674
 
+   identify different resources.  For example, an owner of two different
28675
 
+   domain names could decide to serve the same resource from both,
28676
 
+   resulting in two different URIs.  Therefore, comparison methods are
28677
 
+   designed to minimize false negatives while strictly avoiding false
28678
 
+   positives.
28679
 
+
28680
 
+   In testing for equivalence, applications should not directly compare
28681
 
+   relative references; the references should be converted to their
28682
 
+   respective target URIs before comparison.  When URIs are compared to
28683
 
+   select (or avoid) a network action, such as retrieval of a
28684
 
+   representation, fragment components (if any) should be excluded from
28685
 
+   the comparison.
28686
 
+
28687
 
+
28688
 
+
28689
 
+
28690
 
+
28691
 
+Berners-Lee, et al.         Standards Track                    [Page 38]
28692
 
+
28693
 
+RFC 3986                   URI Generic Syntax               January 2005
28694
 
+
28695
 
+
28696
 
+6.2.  Comparison Ladder
28697
 
+
28698
 
+   A variety of methods are used in practice to test URI equivalence.
28699
 
+   These methods fall into a range, distinguished by the amount of
28700
 
+   processing required and the degree to which the probability of false
28701
 
+   negatives is reduced.  As noted above, false negatives cannot be
28702
 
+   eliminated.  In practice, their probability can be reduced, but this
28703
 
+   reduction requires more processing and is not cost-effective for all
28704
 
+   applications.
28705
 
+
28706
 
+   If this range of comparison practices is considered as a ladder, the
28707
 
+   following discussion will climb the ladder, starting with practices
28708
 
+   that are cheap but have a relatively higher chance of producing false
28709
 
+   negatives, and proceeding to those that have higher computational
28710
 
+   cost and lower risk of false negatives.
28711
 
+
28712
 
+6.2.1.  Simple String Comparison
28713
 
+
28714
 
+   If two URIs, when considered as character strings, are identical,
28715
 
+   then it is safe to conclude that they are equivalent.  This type of
28716
 
+   equivalence test has very low computational cost and is in wide use
28717
 
+   in a variety of applications, particularly in the domain of parsing.
28718
 
+
28719
 
+   Testing strings for equivalence requires some basic precautions.
28720
 
+   This procedure is often referred to as "bit-for-bit" or
28721
 
+   "byte-for-byte" comparison, which is potentially misleading.  Testing
28722
 
+   strings for equality is normally based on pair comparison of the
28723
 
+   characters that make up the strings, starting from the first and
28724
 
+   proceeding until both strings are exhausted and all characters are
28725
 
+   found to be equal, until a pair of characters compares unequal, or
28726
 
+   until one of the strings is exhausted before the other.
28727
 
+
28728
 
+   This character comparison requires that each pair of characters be
28729
 
+   put in comparable form.  For example, should one URI be stored in a
28730
 
+   byte array in EBCDIC encoding and the second in a Java String object
28731
 
+   (UTF-16), bit-for-bit comparisons applied naively will produce
28732
 
+   errors.  It is better to speak of equality on a character-for-
28733
 
+   character basis rather than on a byte-for-byte or bit-for-bit basis.
28734
 
+   In practical terms, character-by-character comparisons should be done
28735
 
+   codepoint-by-codepoint after conversion to a common character
28736
 
+   encoding.
28737
 
+
28738
 
+   False negatives are caused by the production and use of URI aliases.
28739
 
+   Unnecessary aliases can be reduced, regardless of the comparison
28740
 
+   method, by consistently providing URI references in an already-
28741
 
+   normalized form (i.e., a form identical to what would be produced
28742
 
+   after normalization is applied, as described below).
28743
 
+
28744
 
+
28745
 
+
28746
 
+
28747
 
+Berners-Lee, et al.         Standards Track                    [Page 39]
28748
 
+
28749
 
+RFC 3986                   URI Generic Syntax               January 2005
28750
 
+
28751
 
+
28752
 
+   Protocols and data formats often limit some URI comparisons to simple
28753
 
+   string comparison, based on the theory that people and
28754
 
+   implementations will, in their own best interest, be consistent in
28755
 
+   providing URI references, or at least consistent enough to negate any
28756
 
+   efficiency that might be obtained from further normalization.
28757
 
+
28758
 
+6.2.2.  Syntax-Based Normalization
28759
 
+
28760
 
+   Implementations may use logic based on the definitions provided by
28761
 
+   this specification to reduce the probability of false negatives.
28762
 
+   This processing is moderately higher in cost than character-for-
28763
 
+   character string comparison.  For example, an application using this
28764
 
+   approach could reasonably consider the following two URIs equivalent:
28765
 
+
28766
 
+      example://a/b/c/%7Bfoo%7D
28767
 
+      eXAMPLE://a/./b/../b/%63/%7bfoo%7d
28768
 
+
28769
 
+   Web user agents, such as browsers, typically apply this type of URI
28770
 
+   normalization when determining whether a cached response is
28771
 
+   available.  Syntax-based normalization includes such techniques as
28772
 
+   case normalization, percent-encoding normalization, and removal of
28773
 
+   dot-segments.
28774
 
+
28775
 
+6.2.2.1.  Case Normalization
28776
 
+
28777
 
+   For all URIs, the hexadecimal digits within a percent-encoding
28778
 
+   triplet (e.g., "%3a" versus "%3A") are case-insensitive and therefore
28779
 
+   should be normalized to use uppercase letters for the digits A-F.
28780
 
+
28781
 
+   When a URI uses components of the generic syntax, the component
28782
 
+   syntax equivalence rules always apply; namely, that the scheme and
28783
 
+   host are case-insensitive and therefore should be normalized to
28784
 
+   lowercase.  For example, the URI <HTTP://www.EXAMPLE.com/> is
28785
 
+   equivalent to <http://www.example.com/>.  The other generic syntax
28786
 
+   components are assumed to be case-sensitive unless specifically
28787
 
+   defined otherwise by the scheme (see Section 6.2.3).
28788
 
+
28789
 
+6.2.2.2.  Percent-Encoding Normalization
28790
 
+
28791
 
+   The percent-encoding mechanism (Section 2.1) is a frequent source of
28792
 
+   variance among otherwise identical URIs.  In addition to the case
28793
 
+   normalization issue noted above, some URI producers percent-encode
28794
 
+   octets that do not require percent-encoding, resulting in URIs that
28795
 
+   are equivalent to their non-encoded counterparts.  These URIs should
28796
 
+   be normalized by decoding any percent-encoded octet that corresponds
28797
 
+   to an unreserved character, as described in Section 2.3.
28798
 
+
28799
 
+
28800
 
+
28801
 
+
28802
 
+
28803
 
+Berners-Lee, et al.         Standards Track                    [Page 40]
28804
 
+
28805
 
+RFC 3986                   URI Generic Syntax               January 2005
28806
 
+
28807
 
+
28808
 
+6.2.2.3.  Path Segment Normalization
28809
 
+
28810
 
+   The complete path segments "." and ".." are intended only for use
28811
 
+   within relative references (Section 4.1) and are removed as part of
28812
 
+   the reference resolution process (Section 5.2).  However, some
28813
 
+   deployed implementations incorrectly assume that reference resolution
28814
 
+   is not necessary when the reference is already a URI and thus fail to
28815
 
+   remove dot-segments when they occur in non-relative paths.  URI
28816
 
+   normalizers should remove dot-segments by applying the
28817
 
+   remove_dot_segments algorithm to the path, as described in
28818
 
+   Section 5.2.4.
28819
 
+
28820
 
+6.2.3.  Scheme-Based Normalization
28821
 
+
28822
 
+   The syntax and semantics of URIs vary from scheme to scheme, as
28823
 
+   described by the defining specification for each scheme.
28824
 
+   Implementations may use scheme-specific rules, at further processing
28825
 
+   cost, to reduce the probability of false negatives.  For example,
28826
 
+   because the "http" scheme makes use of an authority component, has a
28827
 
+   default port of "80", and defines an empty path to be equivalent to
28828
 
+   "/", the following four URIs are equivalent:
28829
 
+
28830
 
+      http://example.com
28831
 
+      http://example.com/
28832
 
+      http://example.com:/
28833
 
+      http://example.com:80/
28834
 
+
28835
 
+   In general, a URI that uses the generic syntax for authority with an
28836
 
+   empty path should be normalized to a path of "/".  Likewise, an
28837
 
+   explicit ":port", for which the port is empty or the default for the
28838
 
+   scheme, is equivalent to one where the port and its ":" delimiter are
28839
 
+   elided and thus should be removed by scheme-based normalization.  For
28840
 
+   example, the second URI above is the normal form for the "http"
28841
 
+   scheme.
28842
 
+
28843
 
+   Another case where normalization varies by scheme is in the handling
28844
 
+   of an empty authority component or empty host subcomponent.  For many
28845
 
+   scheme specifications, an empty authority or host is considered an
28846
 
+   error; for others, it is considered equivalent to "localhost" or the
28847
 
+   end-user's host.  When a scheme defines a default for authority and a
28848
 
+   URI reference to that default is desired, the reference should be
28849
 
+   normalized to an empty authority for the sake of uniformity, brevity,
28850
 
+   and internationalization.  If, however, either the userinfo or port
28851
 
+   subcomponents are non-empty, then the host should be given explicitly
28852
 
+   even if it matches the default.
28853
 
+
28854
 
+   Normalization should not remove delimiters when their associated
28855
 
+   component is empty unless licensed to do so by the scheme
28856
 
+
28857
 
+
28858
 
+
28859
 
+Berners-Lee, et al.         Standards Track                    [Page 41]
28860
 
+
28861
 
+RFC 3986                   URI Generic Syntax               January 2005
28862
 
+
28863
 
+
28864
 
+   specification.  For example, the URI "http://example.com/?" cannot be
28865
 
+   assumed to be equivalent to any of the examples above.  Likewise, the
28866
 
+   presence or absence of delimiters within a userinfo subcomponent is
28867
 
+   usually significant to its interpretation.  The fragment component is
28868
 
+   not subject to any scheme-based normalization; thus, two URIs that
28869
 
+   differ only by the suffix "#" are considered different regardless of
28870
 
+   the scheme.
28871
 
+
28872
 
+   Some schemes define additional subcomponents that consist of case-
28873
 
+   insensitive data, giving an implicit license to normalizers to
28874
 
+   convert this data to a common case (e.g., all lowercase).  For
28875
 
+   example, URI schemes that define a subcomponent of path to contain an
28876
 
+   Internet hostname, such as the "mailto" URI scheme, cause that
28877
 
+   subcomponent to be case-insensitive and thus subject to case
28878
 
+   normalization (e.g., "mailto:Joe@Example.COM" is equivalent to
28879
 
+   "mailto:Joe@example.com", even though the generic syntax considers
28880
 
+   the path component to be case-sensitive).
28881
 
+
28882
 
+   Other scheme-specific normalizations are possible.
28883
 
+
28884
 
+6.2.4.  Protocol-Based Normalization
28885
 
+
28886
 
+   Substantial effort to reduce the incidence of false negatives is
28887
 
+   often cost-effective for web spiders.  Therefore, they implement even
28888
 
+   more aggressive techniques in URI comparison.  For example, if they
28889
 
+   observe that a URI such as
28890
 
+
28891
 
+      http://example.com/data
28892
 
+
28893
 
+   redirects to a URI differing only in the trailing slash
28894
 
+
28895
 
+      http://example.com/data/
28896
 
+
28897
 
+   they will likely regard the two as equivalent in the future.  This
28898
 
+   kind of technique is only appropriate when equivalence is clearly
28899
 
+   indicated by both the result of accessing the resources and the
28900
 
+   common conventions of their scheme's dereference algorithm (in this
28901
 
+   case, use of redirection by HTTP origin servers to avoid problems
28902
 
+   with relative references).
28903
 
+
28904
 
+
28905
 
+
28906
 
+
28907
 
+
28908
 
+
28909
 
+
28910
 
+
28911
 
+
28912
 
+
28913
 
+
28914
 
+
28915
 
+Berners-Lee, et al.         Standards Track                    [Page 42]
28916
 
+
28917
 
+RFC 3986                   URI Generic Syntax               January 2005
28918
 
+
28919
 
+
28920
 
+7.  Security Considerations
28921
 
+
28922
 
+   A URI does not in itself pose a security threat.  However, as URIs
28923
 
+   are often used to provide a compact set of instructions for access to
28924
 
+   network resources, care must be taken to properly interpret the data
28925
 
+   within a URI, to prevent that data from causing unintended access,
28926
 
+   and to avoid including data that should not be revealed in plain
28927
 
+   text.
28928
 
+
28929
 
+7.1.  Reliability and Consistency
28930
 
+
28931
 
+   There is no guarantee that once a URI has been used to retrieve
28932
 
+   information, the same information will be retrievable by that URI in
28933
 
+   the future.  Nor is there any guarantee that the information
28934
 
+   retrievable via that URI in the future will be observably similar to
28935
 
+   that retrieved in the past.  The URI syntax does not constrain how a
28936
 
+   given scheme or authority apportions its namespace or maintains it
28937
 
+   over time.  Such guarantees can only be obtained from the person(s)
28938
 
+   controlling that namespace and the resource in question.  A specific
28939
 
+   URI scheme may define additional semantics, such as name persistence,
28940
 
+   if those semantics are required of all naming authorities for that
28941
 
+   scheme.
28942
 
+
28943
 
+7.2.  Malicious Construction
28944
 
+
28945
 
+   It is sometimes possible to construct a URI so that an attempt to
28946
 
+   perform a seemingly harmless, idempotent operation, such as the
28947
 
+   retrieval of a representation, will in fact cause a possibly damaging
28948
 
+   remote operation.  The unsafe URI is typically constructed by
28949
 
+   specifying a port number other than that reserved for the network
28950
 
+   protocol in question.  The client unwittingly contacts a site running
28951
 
+   a different protocol service, and data within the URI contains
28952
 
+   instructions that, when interpreted according to this other protocol,
28953
 
+   cause an unexpected operation.  A frequent example of such abuse has
28954
 
+   been the use of a protocol-based scheme with a port component of
28955
 
+   "25", thereby fooling user agent software into sending an unintended
28956
 
+   or impersonating message via an SMTP server.
28957
 
+
28958
 
+   Applications should prevent dereference of a URI that specifies a TCP
28959
 
+   port number within the "well-known port" range (0 - 1023) unless the
28960
 
+   protocol being used to dereference that URI is compatible with the
28961
 
+   protocol expected on that well-known port.  Although IANA maintains a
28962
 
+   registry of well-known ports, applications should make such
28963
 
+   restrictions user-configurable to avoid preventing the deployment of
28964
 
+   new services.
28965
 
+
28966
 
+
28967
 
+
28968
 
+
28969
 
+
28970
 
+
28971
 
+Berners-Lee, et al.         Standards Track                    [Page 43]
28972
 
+
28973
 
+RFC 3986                   URI Generic Syntax               January 2005
28974
 
+
28975
 
+
28976
 
+   When a URI contains percent-encoded octets that match the delimiters
28977
 
+   for a given resolution or dereference protocol (for example, CR and
28978
 
+   LF characters for the TELNET protocol), these percent-encodings must
28979
 
+   not be decoded before transmission across that protocol.  Transfer of
28980
 
+   the percent-encoding, which might violate the protocol, is less
28981
 
+   harmful than allowing decoded octets to be interpreted as additional
28982
 
+   operations or parameters, perhaps triggering an unexpected and
28983
 
+   possibly harmful remote operation.
28984
 
+
28985
 
+7.3.  Back-End Transcoding
28986
 
+
28987
 
+   When a URI is dereferenced, the data within it is often parsed by
28988
 
+   both the user agent and one or more servers.  In HTTP, for example, a
28989
 
+   typical user agent will parse a URI into its five major components,
28990
 
+   access the authority's server, and send it the data within the
28991
 
+   authority, path, and query components.  A typical server will take
28992
 
+   that information, parse the path into segments and the query into
28993
 
+   key/value pairs, and then invoke implementation-specific handlers to
28994
 
+   respond to the request.  As a result, a common security concern for
28995
 
+   server implementations that handle a URI, either as a whole or split
28996
 
+   into separate components, is proper interpretation of the octet data
28997
 
+   represented by the characters and percent-encodings within that URI.
28998
 
+
28999
 
+   Percent-encoded octets must be decoded at some point during the
29000
 
+   dereference process.  Applications must split the URI into its
29001
 
+   components and subcomponents prior to decoding the octets, as
29002
 
+   otherwise the decoded octets might be mistaken for delimiters.
29003
 
+   Security checks of the data within a URI should be applied after
29004
 
+   decoding the octets.  Note, however, that the "%00" percent-encoding
29005
 
+   (NUL) may require special handling and should be rejected if the
29006
 
+   application is not expecting to receive raw data within a component.
29007
 
+
29008
 
+   Special care should be taken when the URI path interpretation process
29009
 
+   involves the use of a back-end file system or related system
29010
 
+   functions.  File systems typically assign an operational meaning to
29011
 
+   special characters, such as the "/", "\", ":", "[", and "]"
29012
 
+   characters, and to special device names like ".", "..", "...", "aux",
29013
 
+   "lpt", etc.  In some cases, merely testing for the existence of such
29014
 
+   a name will cause the operating system to pause or invoke unrelated
29015
 
+   system calls, leading to significant security concerns regarding
29016
 
+   denial of service and unintended data transfer.  It would be
29017
 
+   impossible for this specification to list all such significant
29018
 
+   characters and device names.  Implementers should research the
29019
 
+   reserved names and characters for the types of storage device that
29020
 
+   may be attached to their applications and restrict the use of data
29021
 
+   obtained from URI components accordingly.
29022
 
+
29023
 
+
29024
 
+
29025
 
+
29026
 
+
29027
 
+Berners-Lee, et al.         Standards Track                    [Page 44]
29028
 
+
29029
 
+RFC 3986                   URI Generic Syntax               January 2005
29030
 
+
29031
 
+
29032
 
+7.4.  Rare IP Address Formats
29033
 
+
29034
 
+   Although the URI syntax for IPv4address only allows the common
29035
 
+   dotted-decimal form of IPv4 address literal, many implementations
29036
 
+   that process URIs make use of platform-dependent system routines,
29037
 
+   such as gethostbyname() and inet_aton(), to translate the string
29038
 
+   literal to an actual IP address.  Unfortunately, such system routines
29039
 
+   often allow and process a much larger set of formats than those
29040
 
+   described in Section 3.2.2.
29041
 
+
29042
 
+   For example, many implementations allow dotted forms of three
29043
 
+   numbers, wherein the last part is interpreted as a 16-bit quantity
29044
 
+   and placed in the right-most two bytes of the network address (e.g.,
29045
 
+   a Class B network).  Likewise, a dotted form of two numbers means
29046
 
+   that the last part is interpreted as a 24-bit quantity and placed in
29047
 
+   the right-most three bytes of the network address (Class A), and a
29048
 
+   single number (without dots) is interpreted as a 32-bit quantity and
29049
 
+   stored directly in the network address.  Adding further to the
29050
 
+   confusion, some implementations allow each dotted part to be
29051
 
+   interpreted as decimal, octal, or hexadecimal, as specified in the C
29052
 
+   language (i.e., a leading 0x or 0X implies hexadecimal; a leading 0
29053
 
+   implies octal; otherwise, the number is interpreted as decimal).
29054
 
+
29055
 
+   These additional IP address formats are not allowed in the URI syntax
29056
 
+   due to differences between platform implementations.  However, they
29057
 
+   can become a security concern if an application attempts to filter
29058
 
+   access to resources based on the IP address in string literal format.
29059
 
+   If this filtering is performed, literals should be converted to
29060
 
+   numeric form and filtered based on the numeric value, and not on a
29061
 
+   prefix or suffix of the string form.
29062
 
+
29063
 
+7.5.  Sensitive Information
29064
 
+
29065
 
+   URI producers should not provide a URI that contains a username or
29066
 
+   password that is intended to be secret.  URIs are frequently
29067
 
+   displayed by browsers, stored in clear text bookmarks, and logged by
29068
 
+   user agent history and intermediary applications (proxies).  A
29069
 
+   password appearing within the userinfo component is deprecated and
29070
 
+   should be considered an error (or simply ignored) except in those
29071
 
+   rare cases where the 'password' parameter is intended to be public.
29072
 
+
29073
 
+7.6.  Semantic Attacks
29074
 
+
29075
 
+   Because the userinfo subcomponent is rarely used and appears before
29076
 
+   the host in the authority component, it can be used to construct a
29077
 
+   URI intended to mislead a human user by appearing to identify one
29078
 
+   (trusted) naming authority while actually identifying a different
29079
 
+   authority hidden behind the noise.  For example
29080
 
+
29081
 
+
29082
 
+
29083
 
+Berners-Lee, et al.         Standards Track                    [Page 45]
29084
 
+
29085
 
+RFC 3986                   URI Generic Syntax               January 2005
29086
 
+
29087
 
+
29088
 
+      ftp://cnn.example.com&story=breaking_news@10.0.0.1/top_story.htm
29089
 
+
29090
 
+   might lead a human user to assume that the host is 'cnn.example.com',
29091
 
+   whereas it is actually '10.0.0.1'.  Note that a misleading userinfo
29092
 
+   subcomponent could be much longer than the example above.
29093
 
+
29094
 
+   A misleading URI, such as that above, is an attack on the user's
29095
 
+   preconceived notions about the meaning of a URI rather than an attack
29096
 
+   on the software itself.  User agents may be able to reduce the impact
29097
 
+   of such attacks by distinguishing the various components of the URI
29098
 
+   when they are rendered, such as by using a different color or tone to
29099
 
+   render userinfo if any is present, though there is no panacea.  More
29100
 
+   information on URI-based semantic attacks can be found in [Siedzik].
29101
 
+
29102
 
+8.  IANA Considerations
29103
 
+
29104
 
+   URI scheme names, as defined by <scheme> in Section 3.1, form a
29105
 
+   registered namespace that is managed by IANA according to the
29106
 
+   procedures defined in [BCP35].  No IANA actions are required by this
29107
 
+   document.
29108
 
+
29109
 
+9.  Acknowledgements
29110
 
+
29111
 
+   This specification is derived from RFC 2396 [RFC2396], RFC 1808
29112
 
+   [RFC1808], and RFC 1738 [RFC1738]; the acknowledgements in those
29113
 
+   documents still apply.  It also incorporates the update (with
29114
 
+   corrections) for IPv6 literals in the host syntax, as defined by
29115
 
+   Robert M. Hinden, Brian E. Carpenter, and Larry Masinter in
29116
 
+   [RFC2732].  In addition, contributions by Gisle Aas, Reese Anschultz,
29117
 
+   Daniel Barclay, Tim Bray, Mike Brown, Rob Cameron, Jeremy Carroll,
29118
 
+   Dan Connolly, Adam M. Costello, John Cowan, Jason Diamond, Martin
29119
 
+   Duerst, Stefan Eissing, Clive D.W. Feather, Al Gilman, Tony Hammond,
29120
 
+   Elliotte Harold, Pat Hayes, Henry Holtzman, Ian B. Jacobs, Michael
29121
 
+   Kay, John C. Klensin, Graham Klyne, Dan Kohn, Bruce Lilly, Andrew
29122
 
+   Main, Dave McAlpin, Ira McDonald, Michael Mealling, Ray Merkert,
29123
 
+   Stephen Pollei, Julian Reschke, Tomas Rokicki, Miles Sabin, Kai
29124
 
+   Schaetzl, Mark Thomson, Ronald Tschalaer, Norm Walsh, Marc Warne,
29125
 
+   Stuart Williams, and Henry Zongaro are gratefully acknowledged.
29126
 
+
29127
 
+10.  References
29128
 
+
29129
 
+10.1.  Normative References
29130
 
+
29131
 
+   [ASCII]    American National Standards Institute, "Coded Character
29132
 
+              Set -- 7-bit American Standard Code for Information
29133
 
+              Interchange", ANSI X3.4, 1986.
29134
 
+
29135
 
+
29136
 
+
29137
 
+
29138
 
+
29139
 
+Berners-Lee, et al.         Standards Track                    [Page 46]
29140
 
+
29141
 
+RFC 3986                   URI Generic Syntax               January 2005
29142
 
+
29143
 
+
29144
 
+   [RFC2234]  Crocker, D. and P. Overell, "Augmented BNF for Syntax
29145
 
+              Specifications: ABNF", RFC 2234, November 1997.
29146
 
+
29147
 
+   [STD63]    Yergeau, F., "UTF-8, a transformation format of
29148
 
+              ISO 10646", STD 63, RFC 3629, November 2003.
29149
 
+
29150
 
+   [UCS]      International Organization for Standardization,
29151
 
+              "Information Technology - Universal Multiple-Octet Coded
29152
 
+              Character Set (UCS)", ISO/IEC 10646:2003, December 2003.
29153
 
+
29154
 
+10.2.  Informative References
29155
 
+
29156
 
+   [BCP19]    Freed, N. and J. Postel, "IANA Charset Registration
29157
 
+              Procedures", BCP 19, RFC 2978, October 2000.
29158
 
+
29159
 
+   [BCP35]    Petke, R. and I. King, "Registration Procedures for URL
29160
 
+              Scheme Names", BCP 35, RFC 2717, November 1999.
29161
 
+
29162
 
+   [RFC0952]  Harrenstien, K., Stahl, M., and E. Feinler, "DoD Internet
29163
 
+              host table specification", RFC 952, October 1985.
29164
 
+
29165
 
+   [RFC1034]  Mockapetris, P., "Domain names - concepts and facilities",
29166
 
+              STD 13, RFC 1034, November 1987.
29167
 
+
29168
 
+   [RFC1123]  Braden, R., "Requirements for Internet Hosts - Application
29169
 
+              and Support", STD 3, RFC 1123, October 1989.
29170
 
+
29171
 
+   [RFC1535]  Gavron, E., "A Security Problem and Proposed Correction
29172
 
+              With Widely Deployed DNS Software", RFC 1535,
29173
 
+              October 1993.
29174
 
+
29175
 
+   [RFC1630]  Berners-Lee, T., "Universal Resource Identifiers in WWW: A
29176
 
+              Unifying Syntax for the Expression of Names and Addresses
29177
 
+              of Objects on the Network as used in the World-Wide Web",
29178
 
+              RFC 1630, June 1994.
29179
 
+
29180
 
+   [RFC1736]  Kunze, J., "Functional Recommendations for Internet
29181
 
+              Resource Locators", RFC 1736, February 1995.
29182
 
+
29183
 
+   [RFC1737]  Sollins, K. and L. Masinter, "Functional Requirements for
29184
 
+              Uniform Resource Names", RFC 1737, December 1994.
29185
 
+
29186
 
+   [RFC1738]  Berners-Lee, T., Masinter, L., and M. McCahill, "Uniform
29187
 
+              Resource Locators (URL)", RFC 1738, December 1994.
29188
 
+
29189
 
+   [RFC1808]  Fielding, R., "Relative Uniform Resource Locators",
29190
 
+              RFC 1808, June 1995.
29191
 
+
29192
 
+
29193
 
+
29194
 
+
29195
 
+Berners-Lee, et al.         Standards Track                    [Page 47]
29196
 
+
29197
 
+RFC 3986                   URI Generic Syntax               January 2005
29198
 
+
29199
 
+
29200
 
+   [RFC2046]  Freed, N. and N. Borenstein, "Multipurpose Internet Mail
29201
 
+              Extensions (MIME) Part Two: Media Types", RFC 2046,
29202
 
+              November 1996.
29203
 
+
29204
 
+   [RFC2141]  Moats, R., "URN Syntax", RFC 2141, May 1997.
29205
 
+
29206
 
+   [RFC2396]  Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform
29207
 
+              Resource Identifiers (URI): Generic Syntax", RFC 2396,
29208
 
+              August 1998.
29209
 
+
29210
 
+   [RFC2518]  Goland, Y., Whitehead, E., Faizi, A., Carter, S., and D.
29211
 
+              Jensen, "HTTP Extensions for Distributed Authoring --
29212
 
+              WEBDAV", RFC 2518, February 1999.
29213
 
+
29214
 
+   [RFC2557]  Palme, J., Hopmann, A., and N. Shelness, "MIME
29215
 
+              Encapsulation of Aggregate Documents, such as HTML
29216
 
+              (MHTML)", RFC 2557, March 1999.
29217
 
+
29218
 
+   [RFC2718]  Masinter, L., Alvestrand, H., Zigmond, D., and R. Petke,
29219
 
+              "Guidelines for new URL Schemes", RFC 2718, November 1999.
29220
 
+
29221
 
+   [RFC2732]  Hinden, R., Carpenter, B., and L. Masinter, "Format for
29222
 
+              Literal IPv6 Addresses in URL's", RFC 2732, December 1999.
29223
 
+
29224
 
+   [RFC3305]  Mealling, M. and R. Denenberg, "Report from the Joint
29225
 
+              W3C/IETF URI Planning Interest Group: Uniform Resource
29226
 
+              Identifiers (URIs), URLs, and Uniform Resource Names
29227
 
+              (URNs): Clarifications and Recommendations", RFC 3305,
29228
 
+              August 2002.
29229
 
+
29230
 
+   [RFC3490]  Faltstrom, P., Hoffman, P., and A. Costello,
29231
 
+              "Internationalizing Domain Names in Applications (IDNA)",
29232
 
+              RFC 3490, March 2003.
29233
 
+
29234
 
+   [RFC3513]  Hinden, R. and S. Deering, "Internet Protocol Version 6
29235
 
+              (IPv6) Addressing Architecture", RFC 3513, April 2003.
29236
 
+
29237
 
+   [Siedzik]  Siedzik, R., "Semantic Attacks: What's in a URL?",
29238
 
+              April 2001, <http://www.giac.org/practical/gsec/
29239
 
+              Richard_Siedzik_GSEC.pdf>.
29240
 
+
29241
 
+
29242
 
+
29243
 
+
29244
 
+
29245
 
+
29246
 
+
29247
 
+
29248
 
+
29249
 
+
29250
 
+
29251
 
+Berners-Lee, et al.         Standards Track                    [Page 48]
29252
 
+
29253
 
+RFC 3986                   URI Generic Syntax               January 2005
29254
 
+
29255
 
+
29256
 
+Appendix A.  Collected ABNF for URI
29257
 
+
29258
 
+   URI           = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
29259
 
+
29260
 
+   hier-part     = "//" authority path-abempty
29261
 
+                 / path-absolute
29262
 
+                 / path-rootless
29263
 
+                 / path-empty
29264
 
+
29265
 
+   URI-reference = URI / relative-ref
29266
 
+
29267
 
+   absolute-URI  = scheme ":" hier-part [ "?" query ]
29268
 
+
29269
 
+   relative-ref  = relative-part [ "?" query ] [ "#" fragment ]
29270
 
+
29271
 
+   relative-part = "//" authority path-abempty
29272
 
+                 / path-absolute
29273
 
+                 / path-noscheme
29274
 
+                 / path-empty
29275
 
+
29276
 
+   scheme        = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
29277
 
+
29278
 
+   authority     = [ userinfo "@" ] host [ ":" port ]
29279
 
+   userinfo      = *( unreserved / pct-encoded / sub-delims / ":" )
29280
 
+   host          = IP-literal / IPv4address / reg-name
29281
 
+   port          = *DIGIT
29282
 
+
29283
 
+   IP-literal    = "[" ( IPv6address / IPvFuture  ) "]"
29284
 
+
29285
 
+   IPvFuture     = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )
29286
 
+
29287
 
+   IPv6address   =                            6( h16 ":" ) ls32
29288
 
+                 /                       "::" 5( h16 ":" ) ls32
29289
 
+                 / [               h16 ] "::" 4( h16 ":" ) ls32
29290
 
+                 / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32
29291
 
+                 / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32
29292
 
+                 / [ *3( h16 ":" ) h16 ] "::"    h16 ":"   ls32
29293
 
+                 / [ *4( h16 ":" ) h16 ] "::"              ls32
29294
 
+                 / [ *5( h16 ":" ) h16 ] "::"              h16
29295
 
+                 / [ *6( h16 ":" ) h16 ] "::"
29296
 
+
29297
 
+   h16           = 1*4HEXDIG
29298
 
+   ls32          = ( h16 ":" h16 ) / IPv4address
29299
 
+   IPv4address   = dec-octet "." dec-octet "." dec-octet "." dec-octet
29300
 
+
29301
 
+
29302
 
+
29303
 
+
29304
 
+
29305
 
+
29306
 
+
29307
 
+Berners-Lee, et al.         Standards Track                    [Page 49]
29308
 
+
29309
 
+RFC 3986                   URI Generic Syntax               January 2005
29310
 
+
29311
 
+
29312
 
+   dec-octet     = DIGIT                 ; 0-9
29313
 
+                 / %x31-39 DIGIT         ; 10-99
29314
 
+                 / "1" 2DIGIT            ; 100-199
29315
 
+                 / "2" %x30-34 DIGIT     ; 200-249
29316
 
+                 / "25" %x30-35          ; 250-255
29317
 
+
29318
 
+   reg-name      = *( unreserved / pct-encoded / sub-delims )
29319
 
+
29320
 
+   path          = path-abempty    ; begins with "/" or is empty
29321
 
+                 / path-absolute   ; begins with "/" but not "//"
29322
 
+                 / path-noscheme   ; begins with a non-colon segment
29323
 
+                 / path-rootless   ; begins with a segment
29324
 
+                 / path-empty      ; zero characters
29325
 
+
29326
 
+   path-abempty  = *( "/" segment )
29327
 
+   path-absolute = "/" [ segment-nz *( "/" segment ) ]
29328
 
+   path-noscheme = segment-nz-nc *( "/" segment )
29329
 
+   path-rootless = segment-nz *( "/" segment )
29330
 
+   path-empty    = 0<pchar>
29331
 
+
29332
 
+   segment       = *pchar
29333
 
+   segment-nz    = 1*pchar
29334
 
+   segment-nz-nc = 1*( unreserved / pct-encoded / sub-delims / "@" )
29335
 
+                 ; non-zero-length segment without any colon ":"
29336
 
+
29337
 
+   pchar         = unreserved / pct-encoded / sub-delims / ":" / "@"
29338
 
+
29339
 
+   query         = *( pchar / "/" / "?" )
29340
 
+
29341
 
+   fragment      = *( pchar / "/" / "?" )
29342
 
+
29343
 
+   pct-encoded   = "%" HEXDIG HEXDIG
29344
 
+
29345
 
+   unreserved    = ALPHA / DIGIT / "-" / "." / "_" / "~"
29346
 
+   reserved      = gen-delims / sub-delims
29347
 
+   gen-delims    = ":" / "/" / "?" / "#" / "[" / "]" / "@"
29348
 
+   sub-delims    = "!" / "$" / "&" / "'" / "(" / ")"
29349
 
+                 / "*" / "+" / "," / ";" / "="
29350
 
+
29351
 
+Appendix B.  Parsing a URI Reference with a Regular Expression
29352
 
+
29353
 
+   As the "first-match-wins" algorithm is identical to the "greedy"
29354
 
+   disambiguation method used by POSIX regular expressions, it is
29355
 
+   natural and commonplace to use a regular expression for parsing the
29356
 
+   potential five components of a URI reference.
29357
 
+
29358
 
+   The following line is the regular expression for breaking-down a
29359
 
+   well-formed URI reference into its components.
29360
 
+
29361
 
+
29362
 
+
29363
 
+Berners-Lee, et al.         Standards Track                    [Page 50]
29364
 
+
29365
 
+RFC 3986                   URI Generic Syntax               January 2005
29366
 
+
29367
 
+
29368
 
+      ^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?
29369
 
+       12            3  4          5       6  7        8 9
29370
 
+
29371
 
+   The numbers in the second line above are only to assist readability;
29372
 
+   they indicate the reference points for each subexpression (i.e., each
29373
 
+   paired parenthesis).  We refer to the value matched for subexpression
29374
 
+   <n> as $<n>.  For example, matching the above expression to
29375
 
+
29376
 
+      http://www.ics.uci.edu/pub/ietf/uri/#Related
29377
 
+
29378
 
+   results in the following subexpression matches:
29379
 
+
29380
 
+      $1 = http:
29381
 
+      $2 = http
29382
 
+      $3 = //www.ics.uci.edu
29383
 
+      $4 = www.ics.uci.edu
29384
 
+      $5 = /pub/ietf/uri/
29385
 
+      $6 = <undefined>
29386
 
+      $7 = <undefined>
29387
 
+      $8 = #Related
29388
 
+      $9 = Related
29389
 
+
29390
 
+   where <undefined> indicates that the component is not present, as is
29391
 
+   the case for the query component in the above example.  Therefore, we
29392
 
+   can determine the value of the five components as
29393
 
+
29394
 
+      scheme    = $2
29395
 
+      authority = $4
29396
 
+      path      = $5
29397
 
+      query     = $7
29398
 
+      fragment  = $9
29399
 
+
29400
 
+   Going in the opposite direction, we can recreate a URI reference from
29401
 
+   its components by using the algorithm of Section 5.3.
29402
 
+
29403
 
+Appendix C.  Delimiting a URI in Context
29404
 
+
29405
 
+   URIs are often transmitted through formats that do not provide a
29406
 
+   clear context for their interpretation.  For example, there are many
29407
 
+   occasions when a URI is included in plain text; examples include text
29408
 
+   sent in email, USENET news, and on printed paper.  In such cases, it
29409
 
+   is important to be able to delimit the URI from the rest of the text,
29410
 
+   and in particular from punctuation marks that might be mistaken for
29411
 
+   part of the URI.
29412
 
+
29413
 
+   In practice, URIs are delimited in a variety of ways, but usually
29414
 
+   within double-quotes "http://example.com/", angle brackets
29415
 
+   <http://example.com/>, or just by using whitespace:
29416
 
+
29417
 
+
29418
 
+
29419
 
+Berners-Lee, et al.         Standards Track                    [Page 51]
29420
 
+
29421
 
+RFC 3986                   URI Generic Syntax               January 2005
29422
 
+
29423
 
+
29424
 
+      http://example.com/
29425
 
+
29426
 
+   These wrappers do not form part of the URI.
29427
 
+
29428
 
+   In some cases, extra whitespace (spaces, line-breaks, tabs, etc.) may
29429
 
+   have to be added to break a long URI across lines.  The whitespace
29430
 
+   should be ignored when the URI is extracted.
29431
 
+
29432
 
+   No whitespace should be introduced after a hyphen ("-") character.
29433
 
+   Because some typesetters and printers may (erroneously) introduce a
29434
 
+   hyphen at the end of line when breaking it, the interpreter of a URI
29435
 
+   containing a line break immediately after a hyphen should ignore all
29436
 
+   whitespace around the line break and should be aware that the hyphen
29437
 
+   may or may not actually be part of the URI.
29438
 
+
29439
 
+   Using <> angle brackets around each URI is especially recommended as
29440
 
+   a delimiting style for a reference that contains embedded whitespace.
29441
 
+
29442
 
+   The prefix "URL:" (with or without a trailing space) was formerly
29443
 
+   recommended as a way to help distinguish a URI from other bracketed
29444
 
+   designators, though it is not commonly used in practice and is no
29445
 
+   longer recommended.
29446
 
+
29447
 
+   For robustness, software that accepts user-typed URI should attempt
29448
 
+   to recognize and strip both delimiters and embedded whitespace.
29449
 
+
29450
 
+   For example, the text
29451
 
+
29452
 
+      Yes, Jim, I found it under "http://www.w3.org/Addressing/",
29453
 
+      but you can probably pick it up from <ftp://foo.example.
29454
 
+      com/rfc/>.  Note the warning in <http://www.ics.uci.edu/pub/
29455
 
+      ietf/uri/historical.html#WARNING>.
29456
 
+
29457
 
+   contains the URI references
29458
 
+
29459
 
+      http://www.w3.org/Addressing/
29460
 
+      ftp://foo.example.com/rfc/
29461
 
+      http://www.ics.uci.edu/pub/ietf/uri/historical.html#WARNING
29462
 
+
29463
 
+
29464
 
+
29465
 
+
29466
 
+
29467
 
+
29468
 
+
29469
 
+
29470
 
+
29471
 
+
29472
 
+
29473
 
+
29474
 
+
29475
 
+Berners-Lee, et al.         Standards Track                    [Page 52]
29476
 
+
29477
 
+RFC 3986                   URI Generic Syntax               January 2005
29478
 
+
29479
 
+
29480
 
+Appendix D.  Changes from RFC 2396
29481
 
+
29482
 
+D.1.  Additions
29483
 
+
29484
 
+   An ABNF rule for URI has been introduced to correspond to one common
29485
 
+   usage of the term: an absolute URI with optional fragment.
29486
 
+
29487
 
+   IPv6 (and later) literals have been added to the list of possible
29488
 
+   identifiers for the host portion of an authority component, as
29489
 
+   described by [RFC2732], with the addition of "[" and "]" to the
29490
 
+   reserved set and a version flag to anticipate future versions of IP
29491
 
+   literals.  Square brackets are now specified as reserved within the
29492
 
+   authority component and are not allowed outside their use as
29493
 
+   delimiters for an IP literal within host.  In order to make this
29494
 
+   change without changing the technical definition of the path, query,
29495
 
+   and fragment components, those rules were redefined to directly
29496
 
+   specify the characters allowed.
29497
 
+
29498
 
+   As [RFC2732] defers to [RFC3513] for definition of an IPv6 literal
29499
 
+   address, which, unfortunately, lacks an ABNF description of
29500
 
+   IPv6address, we created a new ABNF rule for IPv6address that matches
29501
 
+   the text representations defined by Section 2.2 of [RFC3513].
29502
 
+   Likewise, the definition of IPv4address has been improved in order to
29503
 
+   limit each decimal octet to the range 0-255.
29504
 
+
29505
 
+   Section 6, on URI normalization and comparison, has been completely
29506
 
+   rewritten and extended by using input from Tim Bray and discussion
29507
 
+   within the W3C Technical Architecture Group.
29508
 
+
29509
 
+D.2.  Modifications
29510
 
+
29511
 
+   The ad-hoc BNF syntax of RFC 2396 has been replaced with the ABNF of
29512
 
+   [RFC2234].  This change required all rule names that formerly
29513
 
+   included underscore characters to be renamed with a dash instead.  In
29514
 
+   addition, a number of syntax rules have been eliminated or simplified
29515
 
+   to make the overall grammar more comprehensible.  Specifications that
29516
 
+   refer to the obsolete grammar rules may be understood by replacing
29517
 
+   those rules according to the following table:
29518
 
+
29519
 
+
29520
 
+
29521
 
+
29522
 
+
29523
 
+
29524
 
+
29525
 
+
29526
 
+
29527
 
+
29528
 
+
29529
 
+
29530
 
+
29531
 
+Berners-Lee, et al.         Standards Track                    [Page 53]
29532
 
+
29533
 
+RFC 3986                   URI Generic Syntax               January 2005
29534
 
+
29535
 
+
29536
 
+   +----------------+--------------------------------------------------+
29537
 
+   | obsolete rule  | translation                                      |
29538
 
+   +----------------+--------------------------------------------------+
29539
 
+   | absoluteURI    | absolute-URI                                     |
29540
 
+   | relativeURI    | relative-part [ "?" query ]                      |
29541
 
+   | hier_part      | ( "//" authority path-abempty /                  |
29542
 
+   |                | path-absolute ) [ "?" query ]                    |
29543
 
+   |                |                                                  |
29544
 
+   | opaque_part    | path-rootless [ "?" query ]                      |
29545
 
+   | net_path       | "//" authority path-abempty                      |
29546
 
+   | abs_path       | path-absolute                                    |
29547
 
+   | rel_path       | path-rootless                                    |
29548
 
+   | rel_segment    | segment-nz-nc                                    |
29549
 
+   | reg_name       | reg-name                                         |
29550
 
+   | server         | authority                                        |
29551
 
+   | hostport       | host [ ":" port ]                                |
29552
 
+   | hostname       | reg-name                                         |
29553
 
+   | path_segments  | path-abempty                                     |
29554
 
+   | param          | *<pchar excluding ";">                           |
29555
 
+   |                |                                                  |
29556
 
+   | uric           | unreserved / pct-encoded / ";" / "?" / ":"       |
29557
 
+   |                |  / "@" / "&" / "=" / "+" / "$" / "," / "/"       |
29558
 
+   |                |                                                  |
29559
 
+   | uric_no_slash  | unreserved / pct-encoded / ";" / "?" / ":"       |
29560
 
+   |                |  / "@" / "&" / "=" / "+" / "$" / ","             |
29561
 
+   |                |                                                  |
29562
 
+   | mark           | "-" / "_" / "." / "!" / "~" / "*" / "'"          |
29563
 
+   |                |  / "(" / ")"                                     |
29564
 
+   |                |                                                  |
29565
 
+   | escaped        | pct-encoded                                      |
29566
 
+   | hex            | HEXDIG                                           |
29567
 
+   | alphanum       | ALPHA / DIGIT                                    |
29568
 
+   +----------------+--------------------------------------------------+
29569
 
+
29570
 
+   Use of the above obsolete rules for the definition of scheme-specific
29571
 
+   syntax is deprecated.
29572
 
+
29573
 
+   Section 2, on characters, has been rewritten to explain what
29574
 
+   characters are reserved, when they are reserved, and why they are
29575
 
+   reserved, even when they are not used as delimiters by the generic
29576
 
+   syntax.  The mark characters that are typically unsafe to decode,
29577
 
+   including the exclamation mark ("!"), asterisk ("*"), single-quote
29578
 
+   ("'"), and open and close parentheses ("(" and ")"), have been moved
29579
 
+   to the reserved set in order to clarify the distinction between
29580
 
+   reserved and unreserved and, hopefully, to answer the most common
29581
 
+   question of scheme designers.  Likewise, the section on
29582
 
+   percent-encoded characters has been rewritten, and URI normalizers
29583
 
+   are now given license to decode any percent-encoded octets
29584
 
+
29585
 
+
29586
 
+
29587
 
+Berners-Lee, et al.         Standards Track                    [Page 54]
29588
 
+
29589
 
+RFC 3986                   URI Generic Syntax               January 2005
29590
 
+
29591
 
+
29592
 
+   corresponding to unreserved characters.  In general, the terms
29593
 
+   "escaped" and "unescaped" have been replaced with "percent-encoded"
29594
 
+   and "decoded", respectively, to reduce confusion with other forms of
29595
 
+   escape mechanisms.
29596
 
+
29597
 
+   The ABNF for URI and URI-reference has been redesigned to make them
29598
 
+   more friendly to LALR parsers and to reduce complexity.  As a result,
29599
 
+   the layout form of syntax description has been removed, along with
29600
 
+   the uric, uric_no_slash, opaque_part, net_path, abs_path, rel_path,
29601
 
+   path_segments, rel_segment, and mark rules.  All references to
29602
 
+   "opaque" URIs have been replaced with a better description of how the
29603
 
+   path component may be opaque to hierarchy.  The relativeURI rule has
29604
 
+   been replaced with relative-ref to avoid unnecessary confusion over
29605
 
+   whether they are a subset of URI.  The ambiguity regarding the
29606
 
+   parsing of URI-reference as a URI or a relative-ref with a colon in
29607
 
+   the first segment has been eliminated through the use of five
29608
 
+   separate path matching rules.
29609
 
+
29610
 
+   The fragment identifier has been moved back into the section on
29611
 
+   generic syntax components and within the URI and relative-ref rules,
29612
 
+   though it remains excluded from absolute-URI.  The number sign ("#")
29613
 
+   character has been moved back to the reserved set as a result of
29614
 
+   reintegrating the fragment syntax.
29615
 
+
29616
 
+   The ABNF has been corrected to allow the path component to be empty.
29617
 
+   This also allows an absolute-URI to consist of nothing after the
29618
 
+   "scheme:", as is present in practice with the "dav:" namespace
29619
 
+   [RFC2518] and with the "about:" scheme used internally by many WWW
29620
 
+   browser implementations.  The ambiguity regarding the boundary
29621
 
+   between authority and path has been eliminated through the use of
29622
 
+   five separate path matching rules.
29623
 
+
29624
 
+   Registry-based naming authorities that use the generic syntax are now
29625
 
+   defined within the host rule.  This change allows current
29626
 
+   implementations, where whatever name provided is simply fed to the
29627
 
+   local name resolution mechanism, to be consistent with the
29628
 
+   specification.  It also removes the need to re-specify DNS name
29629
 
+   formats here.  Furthermore, it allows the host component to contain
29630
 
+   percent-encoded octets, which is necessary to enable
29631
 
+   internationalized domain names to be provided in URIs, processed in
29632
 
+   their native character encodings at the application layers above URI
29633
 
+   processing, and passed to an IDNA library as a registered name in the
29634
 
+   UTF-8 character encoding.  The server, hostport, hostname,
29635
 
+   domainlabel, toplabel, and alphanum rules have been removed.
29636
 
+
29637
 
+   The resolving relative references algorithm of [RFC2396] has been
29638
 
+   rewritten with pseudocode for this revision to improve clarity and
29639
 
+   fix the following issues:
29640
 
+
29641
 
+
29642
 
+
29643
 
+Berners-Lee, et al.         Standards Track                    [Page 55]
29644
 
+
29645
 
+RFC 3986                   URI Generic Syntax               January 2005
29646
 
+
29647
 
+
29648
 
+   o  [RFC2396] section 5.2, step 6a, failed to account for a base URI
29649
 
+      with no path.
29650
 
+
29651
 
+   o  Restored the behavior of [RFC1808] where, if the reference
29652
 
+      contains an empty path and a defined query component, the target
29653
 
+      URI inherits the base URI's path component.
29654
 
+
29655
 
+   o  The determination of whether a URI reference is a same-document
29656
 
+      reference has been decoupled from the URI parser, simplifying the
29657
 
+      URI processing interface within applications in a way consistent
29658
 
+      with the internal architecture of deployed URI processing
29659
 
+      implementations.  The determination is now based on comparison to
29660
 
+      the base URI after transforming a reference to absolute form,
29661
 
+      rather than on the format of the reference itself.  This change
29662
 
+      may result in more references being considered "same-document"
29663
 
+      under this specification than there would be under the rules given
29664
 
+      in RFC 2396, especially when normalization is used to reduce
29665
 
+      aliases.  However, it does not change the status of existing
29666
 
+      same-document references.
29667
 
+
29668
 
+   o  Separated the path merge routine into two routines: merge, for
29669
 
+      describing combination of the base URI path with a relative-path
29670
 
+      reference, and remove_dot_segments, for describing how to remove
29671
 
+      the special "." and ".." segments from a composed path.  The
29672
 
+      remove_dot_segments algorithm is now applied to all URI reference
29673
 
+      paths in order to match common implementations and to improve the
29674
 
+      normalization of URIs in practice.  This change only impacts the
29675
 
+      parsing of abnormal references and same-scheme references wherein
29676
 
+      the base URI has a non-hierarchical path.
29677
 
+
29678
 
+Index
29679
 
+
29680
 
+   A
29681
 
+      ABNF  11
29682
 
+      absolute  27
29683
 
+      absolute-path  26
29684
 
+      absolute-URI  27
29685
 
+      access  9
29686
 
+      authority  17, 18
29687
 
+
29688
 
+   B
29689
 
+      base URI  28
29690
 
+
29691
 
+   C
29692
 
+      character encoding  4
29693
 
+      character  4
29694
 
+      characters  8, 11
29695
 
+      coded character set  4
29696
 
+
29697
 
+
29698
 
+
29699
 
+Berners-Lee, et al.         Standards Track                    [Page 56]
29700
 
+
29701
 
+RFC 3986                   URI Generic Syntax               January 2005
29702
 
+
29703
 
+
29704
 
+   D
29705
 
+      dec-octet  20
29706
 
+      dereference  9
29707
 
+      dot-segments  23
29708
 
+
29709
 
+   F
29710
 
+      fragment  16, 24
29711
 
+
29712
 
+   G
29713
 
+      gen-delims  13
29714
 
+      generic syntax  6
29715
 
+
29716
 
+   H
29717
 
+      h16  20
29718
 
+      hier-part  16
29719
 
+      hierarchical  10
29720
 
+      host  18
29721
 
+
29722
 
+   I
29723
 
+      identifier  5
29724
 
+      IP-literal  19
29725
 
+      IPv4  20
29726
 
+      IPv4address  19, 20
29727
 
+      IPv6  19
29728
 
+      IPv6address  19, 20
29729
 
+      IPvFuture  19
29730
 
+
29731
 
+   L
29732
 
+      locator  7
29733
 
+      ls32  20
29734
 
+
29735
 
+   M
29736
 
+      merge  32
29737
 
+
29738
 
+   N
29739
 
+      name  7
29740
 
+      network-path  26
29741
 
+
29742
 
+   P
29743
 
+      path  16, 22, 26
29744
 
+         path-abempty  22
29745
 
+         path-absolute  22
29746
 
+         path-empty  22
29747
 
+         path-noscheme  22
29748
 
+         path-rootless  22
29749
 
+      path-abempty  16, 22, 26
29750
 
+      path-absolute  16, 22, 26
29751
 
+      path-empty  16, 22, 26
29752
 
+
29753
 
+
29754
 
+
29755
 
+Berners-Lee, et al.         Standards Track                    [Page 57]
29756
 
+
29757
 
+RFC 3986                   URI Generic Syntax               January 2005
29758
 
+
29759
 
+
29760
 
+      path-rootless  16, 22
29761
 
+      pchar  23
29762
 
+      pct-encoded  12
29763
 
+      percent-encoding  12
29764
 
+      port  22
29765
 
+
29766
 
+   Q
29767
 
+      query  16, 23
29768
 
+
29769
 
+   R
29770
 
+      reg-name  21
29771
 
+      registered name  20
29772
 
+      relative  10, 28
29773
 
+      relative-path  26
29774
 
+      relative-ref  26
29775
 
+      remove_dot_segments  33
29776
 
+      representation  9
29777
 
+      reserved  12
29778
 
+      resolution  9, 28
29779
 
+      resource  5
29780
 
+      retrieval  9
29781
 
+
29782
 
+   S
29783
 
+      same-document  27
29784
 
+      sameness  9
29785
 
+      scheme  16, 17
29786
 
+      segment  22, 23
29787
 
+         segment-nz  23
29788
 
+         segment-nz-nc  23
29789
 
+      sub-delims  13
29790
 
+      suffix  27
29791
 
+
29792
 
+   T
29793
 
+      transcription  8
29794
 
+
29795
 
+   U
29796
 
+      uniform  4
29797
 
+      unreserved  13
29798
 
+      URI grammar
29799
 
+         absolute-URI  27
29800
 
+         ALPHA  11
29801
 
+         authority  18
29802
 
+         CR  11
29803
 
+         dec-octet  20
29804
 
+         DIGIT  11
29805
 
+         DQUOTE  11
29806
 
+         fragment  24
29807
 
+         gen-delims  13
29808
 
+
29809
 
+
29810
 
+
29811
 
+Berners-Lee, et al.         Standards Track                    [Page 58]
29812
 
+
29813
 
+RFC 3986                   URI Generic Syntax               January 2005
29814
 
+
29815
 
+
29816
 
+         h16  20
29817
 
+         HEXDIG  11
29818
 
+         hier-part  16
29819
 
+         host  19
29820
 
+         IP-literal  19
29821
 
+         IPv4address  20
29822
 
+         IPv6address  20
29823
 
+         IPvFuture  19
29824
 
+         LF  11
29825
 
+         ls32  20
29826
 
+         OCTET  11
29827
 
+         path  22
29828
 
+         path-abempty  22
29829
 
+         path-absolute  22
29830
 
+         path-empty  22
29831
 
+         path-noscheme  22
29832
 
+         path-rootless  22
29833
 
+         pchar  23
29834
 
+         pct-encoded  12
29835
 
+         port  22
29836
 
+         query  24
29837
 
+         reg-name  21
29838
 
+         relative-ref  26
29839
 
+         reserved  13
29840
 
+         scheme  17
29841
 
+         segment  23
29842
 
+         segment-nz  23
29843
 
+         segment-nz-nc  23
29844
 
+         SP  11
29845
 
+         sub-delims  13
29846
 
+         unreserved  13
29847
 
+         URI  16
29848
 
+         URI-reference  25
29849
 
+         userinfo  18
29850
 
+      URI  16
29851
 
+      URI-reference  25
29852
 
+      URL  7
29853
 
+      URN  7
29854
 
+      userinfo  18
29855
 
+
29856
 
+
29857
 
+
29858
 
+
29859
 
+
29860
 
+
29861
 
+
29862
 
+
29863
 
+
29864
 
+
29865
 
+
29866
 
+
29867
 
+Berners-Lee, et al.         Standards Track                    [Page 59]
29868
 
+
29869
 
+RFC 3986                   URI Generic Syntax               January 2005
29870
 
+
29871
 
+
29872
 
+Authors' Addresses
29873
 
+
29874
 
+   Tim Berners-Lee
29875
 
+   World Wide Web Consortium
29876
 
+   Massachusetts Institute of Technology
29877
 
+   77 Massachusetts Avenue
29878
 
+   Cambridge, MA  02139
29879
 
+   USA
29880
 
+
29881
 
+   Phone: +1-617-253-5702
29882
 
+   Fax:   +1-617-258-5999
29883
 
+   EMail: timbl@w3.org
29884
 
+   URI:   http://www.w3.org/People/Berners-Lee/
29885
 
+
29886
 
+
29887
 
+   Roy T. Fielding
29888
 
+   Day Software
29889
 
+   5251 California Ave., Suite 110
29890
 
+   Irvine, CA  92617
29891
 
+   USA
29892
 
+
29893
 
+   Phone: +1-949-679-2960
29894
 
+   Fax:   +1-949-679-2972
29895
 
+   EMail: fielding@gbiv.com
29896
 
+   URI:   http://roy.gbiv.com/
29897
 
+
29898
 
+
29899
 
+   Larry Masinter
29900
 
+   Adobe Systems Incorporated
29901
 
+   345 Park Ave
29902
 
+   San Jose, CA  95110
29903
 
+   USA
29904
 
+
29905
 
+   Phone: +1-408-536-3024
29906
 
+   EMail: LMM@acm.org
29907
 
+   URI:   http://larry.masinter.net/
29908
 
+
29909
 
+
29910
 
+
29911
 
+
29912
 
+
29913
 
+
29914
 
+
29915
 
+
29916
 
+
29917
 
+
29918
 
+
29919
 
+
29920
 
+
29921
 
+
29922
 
+
29923
 
+Berners-Lee, et al.         Standards Track                    [Page 60]
29924
 
+
29925
 
+RFC 3986                   URI Generic Syntax               January 2005
29926
 
+
29927
 
+
29928
 
+Full Copyright Statement
29929
 
+
29930
 
+   Copyright (C) The Internet Society (2005).
29931
 
+
29932
 
+   This document is subject to the rights, licenses and restrictions
29933
 
+   contained in BCP 78, and except as set forth therein, the authors
29934
 
+   retain all their rights.
29935
 
+
29936
 
+   This document and the information contained herein are provided on an
29937
 
+   "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS
29938
 
+   OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET
29939
 
+   ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED,
29940
 
+   INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE
29941
 
+   INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
29942
 
+   WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
29943
 
+
29944
 
+Intellectual Property
29945
 
+
29946
 
+   The IETF takes no position regarding the validity or scope of any
29947
 
+   Intellectual Property Rights or other rights that might be claimed to
29948
 
+   pertain to the implementation or use of the technology described in
29949
 
+   this document or the extent to which any license under such rights
29950
 
+   might or might not be available; nor does it represent that it has
29951
 
+   made any independent effort to identify any such rights.  Information
29952
 
+   on the IETF's procedures with respect to rights in IETF Documents can
29953
 
+   be found in BCP 78 and BCP 79.
29954
 
+
29955
 
+   Copies of IPR disclosures made to the IETF Secretariat and any
29956
 
+   assurances of licenses to be made available, or the result of an
29957
 
+   attempt made to obtain a general license or permission for the use of
29958
 
+   such proprietary rights by implementers or users of this
29959
 
+   specification can be obtained from the IETF on-line IPR repository at
29960
 
+   http://www.ietf.org/ipr.
29961
 
+
29962
 
+   The IETF invites any interested party to bring to its attention any
29963
 
+   copyrights, patents or patent applications, or other proprietary
29964
 
+   rights that may cover technology that may be required to implement
29965
 
+   this standard.  Please address the information to the IETF at ietf-
29966
 
+   ipr@ietf.org.
29967
 
+
29968
 
+
29969
 
+Acknowledgement
29970
 
+
29971
 
+   Funding for the RFC Editor function is currently provided by the
29972
 
+   Internet Society.
29973
 
+
29974
 
+
29975
 
+
29976
 
+
29977
 
+
29978
 
+
29979
 
+Berners-Lee, et al.         Standards Track                    [Page 61]
29980
 
+
29981
 
diff -urN dovecot-1.2.4/dovecot-libsieve/doc/rfc/utf-8.rfc3629.txt dovecot-1.2.4.debian/dovecot-libsieve/doc/rfc/utf-8.rfc3629.txt
29982
 
--- dovecot-1.2.4/dovecot-libsieve/doc/rfc/utf-8.rfc3629.txt    1970-01-01 01:00:00.000000000 +0100
29983
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/doc/rfc/utf-8.rfc3629.txt     2008-07-18 12:11:28.000000000 +0200
29984
 
@@ -0,0 +1,787 @@
29985
 
+
29986
 
+
29987
 
+
29988
 
+
29989
 
+
29990
 
+
29991
 
+Network Working Group                                         F. Yergeau
29992
 
+Request for Comments: 3629                             Alis Technologies
29993
 
+STD: 63                                                    November 2003
29994
 
+Obsoletes: 2279
29995
 
+Category: Standards Track
29996
 
+
29997
 
+
29998
 
+              UTF-8, a transformation format of ISO 10646
29999
 
+
30000
 
+Status of this Memo
30001
 
+
30002
 
+   This document specifies an Internet standards track protocol for the
30003
 
+   Internet community, and requests discussion and suggestions for
30004
 
+   improvements.  Please refer to the current edition of the "Internet
30005
 
+   Official Protocol Standards" (STD 1) for the standardization state
30006
 
+   and status of this protocol.  Distribution of this memo is unlimited.
30007
 
+
30008
 
+Copyright Notice
30009
 
+
30010
 
+   Copyright (C) The Internet Society (2003).  All Rights Reserved.
30011
 
+
30012
 
+Abstract
30013
 
+
30014
 
+   ISO/IEC 10646-1 defines a large character set called the Universal
30015
 
+   Character Set (UCS) which encompasses most of the world's writing
30016
 
+   systems.  The originally proposed encodings of the UCS, however, were
30017
 
+   not compatible with many current applications and protocols, and this
30018
 
+   has led to the development of UTF-8, the object of this memo.  UTF-8
30019
 
+   has the characteristic of preserving the full US-ASCII range,
30020
 
+   providing compatibility with file systems, parsers and other software
30021
 
+   that rely on US-ASCII values but are transparent to other values.
30022
 
+   This memo obsoletes and replaces RFC 2279.
30023
 
+
30024
 
+Table of Contents
30025
 
+
30026
 
+   1.  Introduction . . . . . . . . . . . . . . . . . . . . . . . . .  2
30027
 
+   2.  Notational conventions . . . . . . . . . . . . . . . . . . . .  3
30028
 
+   3.  UTF-8 definition . . . . . . . . . . . . . . . . . . . . . . .  4
30029
 
+   4.  Syntax of UTF-8 Byte Sequences . . . . . . . . . . . . . . . .  5
30030
 
+   5.  Versions of the standards  . . . . . . . . . . . . . . . . . .  6
30031
 
+   6.  Byte order mark (BOM)  . . . . . . . . . . . . . . . . . . . .  6
30032
 
+   7.  Examples . . . . . . . . . . . . . . . . . . . . . . . . . . .  8
30033
 
+   8.  MIME registration  . . . . . . . . . . . . . . . . . . . . . .  9
30034
 
+   9.  IANA Considerations  . . . . . . . . . . . . . . . . . . . . . 10
30035
 
+   10. Security Considerations  . . . . . . . . . . . . . . . . . . . 10
30036
 
+   11. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . 11
30037
 
+   12. Changes from RFC 2279  . . . . . . . . . . . . . . . . . . . . 11
30038
 
+   13. Normative References . . . . . . . . . . . . . . . . . . . . . 12
30039
 
+
30040
 
+
30041
 
+
30042
 
+Yergeau                     Standards Track                     [Page 1]
30043
 
+
30044
 
+RFC 3629                         UTF-8                     November 2003
30045
 
+
30046
 
+
30047
 
+   14. Informative References . . . . . . . . . . . . . . . . . . . . 12
30048
 
+   15. URI's  . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
30049
 
+   16. Intellectual Property Statement  . . . . . . . . . . . . . . . 13
30050
 
+   17. Author's Address . . . . . . . . . . . . . . . . . . . . . . . 13
30051
 
+   18. Full Copyright Statement . . . . . . . . . . . . . . . . . . . 14
30052
 
+
30053
 
+1. Introduction
30054
 
+
30055
 
+   ISO/IEC 10646 [ISO.10646] defines a large character set called the
30056
 
+   Universal Character Set (UCS), which encompasses most of the world's
30057
 
+   writing systems.  The same set of characters is defined by the
30058
 
+   Unicode standard [UNICODE], which further defines additional
30059
 
+   character properties and other application details of great interest
30060
 
+   to implementers.  Up to the present time, changes in Unicode and
30061
 
+   amendments and additions to ISO/IEC 10646 have tracked each other, so
30062
 
+   that the character repertoires and code point assignments have
30063
 
+   remained in sync.  The relevant standardization committees have
30064
 
+   committed to maintain this very useful synchronism.
30065
 
+
30066
 
+   ISO/IEC 10646 and Unicode define several encoding forms of their
30067
 
+   common repertoire: UTF-8, UCS-2, UTF-16, UCS-4 and UTF-32.  In an
30068
 
+   encoding form, each character is represented as one or more encoding
30069
 
+   units.  All standard UCS encoding forms except UTF-8 have an encoding
30070
 
+   unit larger than one octet, making them hard to use in many current
30071
 
+   applications and protocols that assume 8 or even 7 bit characters.
30072
 
+
30073
 
+   UTF-8, the object of this memo, has a one-octet encoding unit.  It
30074
 
+   uses all bits of an octet, but has the quality of preserving the full
30075
 
+   US-ASCII [US-ASCII] range: US-ASCII characters are encoded in one
30076
 
+   octet having the normal US-ASCII value, and any octet with such a
30077
 
+   value can only stand for a US-ASCII character, and nothing else.
30078
 
+
30079
 
+   UTF-8 encodes UCS characters as a varying number of octets, where the
30080
 
+   number of octets, and the value of each, depend on the integer value
30081
 
+   assigned to the character in ISO/IEC 10646 (the character number,
30082
 
+   a.k.a. code position, code point or Unicode scalar value).  This
30083
 
+   encoding form has the following characteristics (all values are in
30084
 
+   hexadecimal):
30085
 
+
30086
 
+   o  Character numbers from U+0000 to U+007F (US-ASCII repertoire)
30087
 
+      correspond to octets 00 to 7F (7 bit US-ASCII values).  A direct
30088
 
+      consequence is that a plain ASCII string is also a valid UTF-8
30089
 
+      string.
30090
 
+
30091
 
+
30092
 
+
30093
 
+
30094
 
+
30095
 
+
30096
 
+
30097
 
+
30098
 
+Yergeau                     Standards Track                     [Page 2]
30099
 
+
30100
 
+RFC 3629                         UTF-8                     November 2003
30101
 
+
30102
 
+
30103
 
+   o  US-ASCII octet values do not appear otherwise in a UTF-8 encoded
30104
 
+      character stream.  This provides compatibility with file systems
30105
 
+      or other software (e.g., the printf() function in C libraries)
30106
 
+      that parse based on US-ASCII values but are transparent to other
30107
 
+      values.
30108
 
+
30109
 
+   o  Round-trip conversion is easy between UTF-8 and other encoding
30110
 
+      forms.
30111
 
+
30112
 
+   o  The first octet of a multi-octet sequence indicates the number of
30113
 
+      octets in the sequence.
30114
 
+
30115
 
+   o  The octet values C0, C1, F5 to FF never appear.
30116
 
+
30117
 
+   o  Character boundaries are easily found from anywhere in an octet
30118
 
+      stream.
30119
 
+
30120
 
+   o  The byte-value lexicographic sorting order of UTF-8 strings is the
30121
 
+      same as if ordered by character numbers.  Of course this is of
30122
 
+      limited interest since a sort order based on character numbers is
30123
 
+      almost never culturally valid.
30124
 
+
30125
 
+   o  The Boyer-Moore fast search algorithm can be used with UTF-8 data.
30126
 
+
30127
 
+   o  UTF-8 strings can be fairly reliably recognized as such by a
30128
 
+      simple algorithm, i.e., the probability that a string of
30129
 
+      characters in any other encoding appears as valid UTF-8 is low,
30130
 
+      diminishing with increasing string length.
30131
 
+
30132
 
+   UTF-8 was devised in September 1992 by Ken Thompson, guided by design
30133
 
+   criteria specified by Rob Pike, with the objective of defining a UCS
30134
 
+   transformation format usable in the Plan9 operating system in a non-
30135
 
+   disruptive manner.  Thompson's design was stewarded through
30136
 
+   standardization by the X/Open Joint Internationalization Group XOJIG
30137
 
+   (see [FSS_UTF]), bearing the names FSS-UTF (variant FSS/UTF), UTF-2
30138
 
+   and finally UTF-8 along the way.
30139
 
+
30140
 
+2.  Notational conventions
30141
 
+
30142
 
+   The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
30143
 
+   "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
30144
 
+   document are to be interpreted as described in [RFC2119].
30145
 
+
30146
 
+   UCS characters are designated by the U+HHHH notation, where HHHH is a
30147
 
+   string of from 4 to 6 hexadecimal digits representing the character
30148
 
+   number in ISO/IEC 10646.
30149
 
+
30150
 
+
30151
 
+
30152
 
+
30153
 
+
30154
 
+Yergeau                     Standards Track                     [Page 3]
30155
 
+
30156
 
+RFC 3629                         UTF-8                     November 2003
30157
 
+
30158
 
+
30159
 
+3.  UTF-8 definition
30160
 
+
30161
 
+   UTF-8 is defined by the Unicode Standard [UNICODE].  Descriptions and
30162
 
+   formulae can also be found in Annex D of ISO/IEC 10646-1 [ISO.10646]
30163
 
+
30164
 
+   In UTF-8, characters from the U+0000..U+10FFFF range (the UTF-16
30165
 
+   accessible range) are encoded using sequences of 1 to 4 octets.  The
30166
 
+   only octet of a "sequence" of one has the higher-order bit set to 0,
30167
 
+   the remaining 7 bits being used to encode the character number.  In a
30168
 
+   sequence of n octets, n>1, the initial octet has the n higher-order
30169
 
+   bits set to 1, followed by a bit set to 0.  The remaining bit(s) of
30170
 
+   that octet contain bits from the number of the character to be
30171
 
+   encoded.  The following octet(s) all have the higher-order bit set to
30172
 
+   1 and the following bit set to 0, leaving 6 bits in each to contain
30173
 
+   bits from the character to be encoded.
30174
 
+
30175
 
+   The table below summarizes the format of these different octet types.
30176
 
+   The letter x indicates bits available for encoding bits of the
30177
 
+   character number.
30178
 
+
30179
 
+   Char. number range  |        UTF-8 octet sequence
30180
 
+      (hexadecimal)    |              (binary)
30181
 
+   --------------------+---------------------------------------------
30182
 
+   0000 0000-0000 007F | 0xxxxxxx
30183
 
+   0000 0080-0000 07FF | 110xxxxx 10xxxxxx
30184
 
+   0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
30185
 
+   0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
30186
 
+
30187
 
+   Encoding a character to UTF-8 proceeds as follows:
30188
 
+
30189
 
+   1.  Determine the number of octets required from the character number
30190
 
+       and the first column of the table above.  It is important to note
30191
 
+       that the rows of the table are mutually exclusive, i.e., there is
30192
 
+       only one valid way to encode a given character.
30193
 
+
30194
 
+   2.  Prepare the high-order bits of the octets as per the second
30195
 
+       column of the table.
30196
 
+
30197
 
+   3.  Fill in the bits marked x from the bits of the character number,
30198
 
+       expressed in binary.  Start by putting the lowest-order bit of
30199
 
+       the character number in the lowest-order position of the last
30200
 
+       octet of the sequence, then put the next higher-order bit of the
30201
 
+       character number in the next higher-order position of that octet,
30202
 
+       etc.  When the x bits of the last octet are filled in, move on to
30203
 
+       the next to last octet, then to the preceding one, etc. until all
30204
 
+       x bits are filled in.
30205
 
+
30206
 
+
30207
 
+
30208
 
+
30209
 
+
30210
 
+Yergeau                     Standards Track                     [Page 4]
30211
 
+
30212
 
+RFC 3629                         UTF-8                     November 2003
30213
 
+
30214
 
+
30215
 
+   The definition of UTF-8 prohibits encoding character numbers between
30216
 
+   U+D800 and U+DFFF, which are reserved for use with the UTF-16
30217
 
+   encoding form (as surrogate pairs) and do not directly represent
30218
 
+   characters.  When encoding in UTF-8 from UTF-16 data, it is necessary
30219
 
+   to first decode the UTF-16 data to obtain character numbers, which
30220
 
+   are then encoded in UTF-8 as described above.  This contrasts with
30221
 
+   CESU-8 [CESU-8], which is a UTF-8-like encoding that is not meant for
30222
 
+   use on the Internet.  CESU-8 operates similarly to UTF-8 but encodes
30223
 
+   the UTF-16 code values (16-bit quantities) instead of the character
30224
 
+   number (code point).  This leads to different results for character
30225
 
+   numbers above 0xFFFF; the CESU-8 encoding of those characters is NOT
30226
 
+   valid UTF-8.
30227
 
+
30228
 
+   Decoding a UTF-8 character proceeds as follows:
30229
 
+
30230
 
+   1.  Initialize a binary number with all bits set to 0.  Up to 21 bits
30231
 
+       may be needed.
30232
 
+
30233
 
+   2.  Determine which bits encode the character number from the number
30234
 
+       of octets in the sequence and the second column of the table
30235
 
+       above (the bits marked x).
30236
 
+
30237
 
+   3.  Distribute the bits from the sequence to the binary number, first
30238
 
+       the lower-order bits from the last octet of the sequence and
30239
 
+       proceeding to the left until no x bits are left.  The binary
30240
 
+       number is now equal to the character number.
30241
 
+
30242
 
+   Implementations of the decoding algorithm above MUST protect against
30243
 
+   decoding invalid sequences.  For instance, a naive implementation may
30244
 
+   decode the overlong UTF-8 sequence C0 80 into the character U+0000,
30245
 
+   or the surrogate pair ED A1 8C ED BE B4 into U+233B4.  Decoding
30246
 
+   invalid sequences may have security consequences or cause other
30247
 
+   problems.  See Security Considerations (Section 10) below.
30248
 
+
30249
 
+4.  Syntax of UTF-8 Byte Sequences
30250
 
+
30251
 
+   For the convenience of implementors using ABNF, a definition of UTF-8
30252
 
+   in ABNF syntax is given here.
30253
 
+
30254
 
+   A UTF-8 string is a sequence of octets representing a sequence of UCS
30255
 
+   characters.  An octet sequence is valid UTF-8 only if it matches the
30256
 
+   following syntax, which is derived from the rules for encoding UTF-8
30257
 
+   and is expressed in the ABNF of [RFC2234].
30258
 
+
30259
 
+   UTF8-octets = *( UTF8-char )
30260
 
+   UTF8-char   = UTF8-1 / UTF8-2 / UTF8-3 / UTF8-4
30261
 
+   UTF8-1      = %x00-7F
30262
 
+   UTF8-2      = %xC2-DF UTF8-tail
30263
 
+
30264
 
+
30265
 
+
30266
 
+Yergeau                     Standards Track                     [Page 5]
30267
 
+
30268
 
+RFC 3629                         UTF-8                     November 2003
30269
 
+
30270
 
+
30271
 
+   UTF8-3      = %xE0 %xA0-BF UTF8-tail / %xE1-EC 2( UTF8-tail ) /
30272
 
+                 %xED %x80-9F UTF8-tail / %xEE-EF 2( UTF8-tail )
30273
 
+   UTF8-4      = %xF0 %x90-BF 2( UTF8-tail ) / %xF1-F3 3( UTF8-tail ) /
30274
 
+                 %xF4 %x80-8F 2( UTF8-tail )
30275
 
+   UTF8-tail   = %x80-BF
30276
 
+
30277
 
+   NOTE -- The authoritative definition of UTF-8 is in [UNICODE].  This
30278
 
+   grammar is believed to describe the same thing Unicode describes, but
30279
 
+   does not claim to be authoritative.  Implementors are urged to rely
30280
 
+   on the authoritative source, rather than on this ABNF.
30281
 
+
30282
 
+5.  Versions of the standards
30283
 
+
30284
 
+   ISO/IEC 10646 is updated from time to time by publication of
30285
 
+   amendments and additional parts; similarly, new versions of the
30286
 
+   Unicode standard are published over time.  Each new version obsoletes
30287
 
+   and replaces the previous one, but implementations, and more
30288
 
+   significantly data, are not updated instantly.
30289
 
+
30290
 
+   In general, the changes amount to adding new characters, which does
30291
 
+   not pose particular problems with old data.  In 1996, Amendment 5 to
30292
 
+   the 1993 edition of ISO/IEC 10646 and Unicode 2.0 moved and expanded
30293
 
+   the Korean Hangul block, thereby making any previous data containing
30294
 
+   Hangul characters invalid under the new version.  Unicode 2.0 has the
30295
 
+   same difference from Unicode 1.1.  The justification for allowing
30296
 
+   such an incompatible change was that there were no major
30297
 
+   implementations and no significant amounts of data containing Hangul.
30298
 
+   The incident has been dubbed the "Korean mess", and the relevant
30299
 
+   committees have pledged to never, ever again make such an
30300
 
+   incompatible change (see Unicode Consortium Policies [1]).
30301
 
+
30302
 
+   New versions, and in particular any incompatible changes, have
30303
 
+   consequences regarding MIME charset labels, to be discussed in MIME
30304
 
+   registration (Section 8).
30305
 
+
30306
 
+6.  Byte order mark (BOM)
30307
 
+
30308
 
+   The UCS character U+FEFF "ZERO WIDTH NO-BREAK SPACE" is also known
30309
 
+   informally as "BYTE ORDER MARK" (abbreviated "BOM").  This character
30310
 
+   can be used as a genuine "ZERO WIDTH NO-BREAK SPACE" within text, but
30311
 
+   the BOM name hints at a second possible usage of the character:  to
30312
 
+   prepend a U+FEFF character to a stream of UCS characters as a
30313
 
+   "signature".  A receiver of such a serialized stream may then use the
30314
 
+   initial character as a hint that the stream consists of UCS
30315
 
+   characters and also to recognize which UCS encoding is involved and,
30316
 
+   with encodings having a multi-octet encoding unit, as a way to
30317
 
+
30318
 
+
30319
 
+
30320
 
+
30321
 
+
30322
 
+Yergeau                     Standards Track                     [Page 6]
30323
 
+
30324
 
+RFC 3629                         UTF-8                     November 2003
30325
 
+
30326
 
+
30327
 
+   recognize the serialization order of the octets.  UTF-8 having a
30328
 
+   single-octet encoding unit, this last function is useless and the BOM
30329
 
+   will always appear as the octet sequence EF BB BF.
30330
 
+
30331
 
+   It is important to understand that the character U+FEFF appearing at
30332
 
+   any position other than the beginning of a stream MUST be interpreted
30333
 
+   with the semantics for the zero-width non-breaking space, and MUST
30334
 
+   NOT be interpreted as a signature.  When interpreted as a signature,
30335
 
+   the Unicode standard suggests than an initial U+FEFF character may be
30336
 
+   stripped before processing the text.  Such stripping is necessary in
30337
 
+   some cases (e.g., when concatenating two strings, because otherwise
30338
 
+   the resulting string may contain an unintended "ZERO WIDTH NO-BREAK
30339
 
+   SPACE" at the connection point), but might affect an external process
30340
 
+   at a different layer (such as a digital signature or a count of the
30341
 
+   characters) that is relying on the presence of all characters in the
30342
 
+   stream.  It is therefore RECOMMENDED to avoid stripping an initial
30343
 
+   U+FEFF interpreted as a signature without a good reason, to ignore it
30344
 
+   instead of stripping it when appropriate (such as for display) and to
30345
 
+   strip it only when really necessary.
30346
 
+
30347
 
+   U+FEFF in the first position of a stream MAY be interpreted as a
30348
 
+   zero-width non-breaking space, and is not always a signature.  In an
30349
 
+   attempt at diminishing this uncertainty, Unicode 3.2 adds a new
30350
 
+   character, U+2060 "WORD JOINER", with exactly the same semantics and
30351
 
+   usage as U+FEFF except for the signature function, and strongly
30352
 
+   recommends its exclusive use for expressing word-joining semantics.
30353
 
+   Eventually, following this recommendation will make it all but
30354
 
+   certain that any initial U+FEFF is a signature, not an intended "ZERO
30355
 
+   WIDTH NO-BREAK SPACE".
30356
 
+
30357
 
+   In the meantime, the uncertainty unfortunately remains and may affect
30358
 
+   Internet protocols.  Protocol specifications MAY restrict usage of
30359
 
+   U+FEFF as a signature in order to reduce or eliminate the potential
30360
 
+   ill effects of this uncertainty.  In the interest of striking a
30361
 
+   balance between the advantages (reduction of uncertainty) and
30362
 
+   drawbacks (loss of the signature function) of such restrictions, it
30363
 
+   is useful to distinguish a few cases:
30364
 
+
30365
 
+   o  A protocol SHOULD forbid use of U+FEFF as a signature for those
30366
 
+      textual protocol elements that the protocol mandates to be always
30367
 
+      UTF-8, the signature function being totally useless in those
30368
 
+      cases.
30369
 
+
30370
 
+   o  A protocol SHOULD also forbid use of U+FEFF as a signature for
30371
 
+      those textual protocol elements for which the protocol provides
30372
 
+      character encoding identification mechanisms, when it is expected
30373
 
+      that implementations of the protocol will be in a position to
30374
 
+      always use the mechanisms properly.  This will be the case when
30375
 
+
30376
 
+
30377
 
+
30378
 
+Yergeau                     Standards Track                     [Page 7]
30379
 
+
30380
 
+RFC 3629                         UTF-8                     November 2003
30381
 
+
30382
 
+
30383
 
+      the protocol elements are maintained tightly under the control of
30384
 
+      the implementation from the time of their creation to the time of
30385
 
+      their (properly labeled) transmission.
30386
 
+
30387
 
+   o  A protocol SHOULD NOT forbid use of U+FEFF as a signature for
30388
 
+      those textual protocol elements for which the protocol does not
30389
 
+      provide character encoding identification mechanisms, when a ban
30390
 
+      would be unenforceable, or when it is expected that
30391
 
+      implementations of the protocol will not be in a position to
30392
 
+      always use the mechanisms properly.  The latter two cases are
30393
 
+      likely to occur with larger protocol elements such as MIME
30394
 
+      entities, especially when implementations of the protocol will
30395
 
+      obtain such entities from file systems, from protocols that do not
30396
 
+      have encoding identification mechanisms for payloads (such as FTP)
30397
 
+      or from other protocols that do not guarantee proper
30398
 
+      identification of character encoding (such as HTTP).
30399
 
+
30400
 
+   When a protocol forbids use of U+FEFF as a signature for a certain
30401
 
+   protocol element, then any initial U+FEFF in that protocol element
30402
 
+   MUST be interpreted as a "ZERO WIDTH NO-BREAK SPACE".  When a
30403
 
+   protocol does NOT forbid use of U+FEFF as a signature for a certain
30404
 
+   protocol element, then implementations SHOULD be prepared to handle a
30405
 
+   signature in that element and react appropriately: using the
30406
 
+   signature to identify the character encoding as necessary and
30407
 
+   stripping or ignoring the signature as appropriate.
30408
 
+
30409
 
+7.  Examples
30410
 
+
30411
 
+   The character sequence U+0041 U+2262 U+0391 U+002E "A<NOT IDENTICAL
30412
 
+   TO><ALPHA>." is encoded in UTF-8 as follows:
30413
 
+
30414
 
+       --+--------+-----+--
30415
 
+       41 E2 89 A2 CE 91 2E
30416
 
+       --+--------+-----+--
30417
 
+
30418
 
+   The character sequence U+D55C U+AD6D U+C5B4 (Korean "hangugeo",
30419
 
+   meaning "the Korean language") is encoded in UTF-8 as follows:
30420
 
+
30421
 
+       --------+--------+--------
30422
 
+       ED 95 9C EA B5 AD EC 96 B4
30423
 
+       --------+--------+--------
30424
 
+
30425
 
+   The character sequence U+65E5 U+672C U+8A9E (Japanese "nihongo",
30426
 
+   meaning "the Japanese language") is encoded in UTF-8 as follows:
30427
 
+
30428
 
+       --------+--------+--------
30429
 
+       E6 97 A5 E6 9C AC E8 AA 9E
30430
 
+       --------+--------+--------
30431
 
+
30432
 
+
30433
 
+
30434
 
+Yergeau                     Standards Track                     [Page 8]
30435
 
+
30436
 
+RFC 3629                         UTF-8                     November 2003
30437
 
+
30438
 
+
30439
 
+   The character U+233B4 (a Chinese character meaning 'stump of tree'),
30440
 
+   prepended with a UTF-8 BOM, is encoded in UTF-8 as follows:
30441
 
+
30442
 
+       --------+-----------
30443
 
+       EF BB BF F0 A3 8E B4
30444
 
+       --------+-----------
30445
 
+
30446
 
+8.  MIME registration
30447
 
+
30448
 
+   This memo serves as the basis for registration of the MIME charset
30449
 
+   parameter for UTF-8, according to [RFC2978].  The charset parameter
30450
 
+   value is "UTF-8".  This string labels media types containing text
30451
 
+   consisting of characters from the repertoire of ISO/IEC 10646
30452
 
+   including all amendments at least up to amendment 5 of the 1993
30453
 
+   edition (Korean block), encoded to a sequence of octets using the
30454
 
+   encoding scheme outlined above.  UTF-8 is suitable for use in MIME
30455
 
+   content types under the "text" top-level type.
30456
 
+
30457
 
+   It is noteworthy that the label "UTF-8" does not contain a version
30458
 
+   identification, referring generically to ISO/IEC 10646.  This is
30459
 
+   intentional, the rationale being as follows:
30460
 
+
30461
 
+   A MIME charset label is designed to give just the information needed
30462
 
+   to interpret a sequence of bytes received on the wire into a sequence
30463
 
+   of characters, nothing more (see [RFC2045], section 2.2).  As long as
30464
 
+   a character set standard does not change incompatibly, version
30465
 
+   numbers serve no purpose, because one gains nothing by learning from
30466
 
+   the tag that newly assigned characters may be received that one
30467
 
+   doesn't know about.  The tag itself doesn't teach anything about the
30468
 
+   new characters, which are going to be received anyway.
30469
 
+
30470
 
+   Hence, as long as the standards evolve compatibly, the apparent
30471
 
+   advantage of having labels that identify the versions is only that,
30472
 
+   apparent.  But there is a disadvantage to such version-dependent
30473
 
+   labels: when an older application receives data accompanied by a
30474
 
+   newer, unknown label, it may fail to recognize the label and be
30475
 
+   completely unable to deal with the data, whereas a generic, known
30476
 
+   label would have triggered mostly correct processing of the data,
30477
 
+   which may well not contain any new characters.
30478
 
+
30479
 
+   Now the "Korean mess" (ISO/IEC 10646 amendment 5) is an incompatible
30480
 
+   change, in principle contradicting the appropriateness of a version
30481
 
+   independent MIME charset label as described above.  But the
30482
 
+   compatibility problem can only appear with data containing Korean
30483
 
+   Hangul characters encoded according to Unicode 1.1 (or equivalently
30484
 
+   ISO/IEC 10646 before amendment 5), and there is arguably no such data
30485
 
+   to worry about, this being the very reason the incompatible change
30486
 
+   was deemed acceptable.
30487
 
+
30488
 
+
30489
 
+
30490
 
+Yergeau                     Standards Track                     [Page 9]
30491
 
+
30492
 
+RFC 3629                         UTF-8                     November 2003
30493
 
+
30494
 
+
30495
 
+   In practice, then, a version-independent label is warranted, provided
30496
 
+   the label is understood to refer to all versions after Amendment 5,
30497
 
+   and provided no incompatible change actually occurs.  Should
30498
 
+   incompatible changes occur in a later version of ISO/IEC 10646, the
30499
 
+   MIME charset label defined here will stay aligned with the previous
30500
 
+   version until and unless the IETF specifically decides otherwise.
30501
 
+
30502
 
+9.  IANA Considerations
30503
 
+
30504
 
+   The entry for UTF-8 in the IANA charset registry has been updated to
30505
 
+   point to this memo.
30506
 
+
30507
 
+10.  Security Considerations
30508
 
+
30509
 
+   Implementers of UTF-8 need to consider the security aspects of how
30510
 
+   they handle illegal UTF-8 sequences.  It is conceivable that in some
30511
 
+   circumstances an attacker would be able to exploit an incautious
30512
 
+   UTF-8 parser by sending it an octet sequence that is not permitted by
30513
 
+   the UTF-8 syntax.
30514
 
+
30515
 
+   A particularly subtle form of this attack can be carried out against
30516
 
+   a parser which performs security-critical validity checks against the
30517
 
+   UTF-8 encoded form of its input, but interprets certain illegal octet
30518
 
+   sequences as characters.  For example, a parser might prohibit the
30519
 
+   NUL character when encoded as the single-octet sequence 00, but
30520
 
+   erroneously allow the illegal two-octet sequence C0 80 and interpret
30521
 
+   it as a NUL character.  Another example might be a parser which
30522
 
+   prohibits the octet sequence 2F 2E 2E 2F ("/../"), yet permits the
30523
 
+   illegal octet sequence 2F C0 AE 2E 2F.  This last exploit has
30524
 
+   actually been used in a widespread virus attacking Web servers in
30525
 
+   2001; thus, the security threat is very real.
30526
 
+
30527
 
+   Another security issue occurs when encoding to UTF-8: the ISO/IEC
30528
 
+   10646 description of UTF-8 allows encoding character numbers up to
30529
 
+   U+7FFFFFFF, yielding sequences of up to 6 bytes.  There is therefore
30530
 
+   a risk of buffer overflow if the range of character numbers is not
30531
 
+   explicitly limited to U+10FFFF or if buffer sizing doesn't take into
30532
 
+   account the possibility of 5- and 6-byte sequences.
30533
 
+
30534
 
+   Security may also be impacted by a characteristic of several
30535
 
+   character encodings, including UTF-8: the "same thing" (as far as a
30536
 
+   user can tell) can be represented by several distinct character
30537
 
+   sequences.  For instance, an e with acute accent can be represented
30538
 
+   by the precomposed U+00E9 E ACUTE character or by the canonically
30539
 
+   equivalent sequence U+0065 U+0301 (E + COMBINING ACUTE).  Even though
30540
 
+   UTF-8 provides a single byte sequence for each character sequence,
30541
 
+   the existence of multiple character sequences for "the same thing"
30542
 
+   may have security consequences whenever string matching, indexing,
30543
 
+
30544
 
+
30545
 
+
30546
 
+Yergeau                     Standards Track                    [Page 10]
30547
 
+
30548
 
+RFC 3629                         UTF-8                     November 2003
30549
 
+
30550
 
+
30551
 
+   searching, sorting, regular expression matching and selection are
30552
 
+   involved.  An example would be string matching of an identifier
30553
 
+   appearing in a credential and in access control list entries.  This
30554
 
+   issue is amenable to solutions based on Unicode Normalization Forms,
30555
 
+   see [UAX15].
30556
 
+
30557
 
+11.  Acknowledgements
30558
 
+
30559
 
+   The following have participated in the drafting and discussion of
30560
 
+   this memo: James E. Agenbroad, Harald Alvestrand, Andries Brouwer,
30561
 
+   Mark Davis, Martin J. Duerst, Patrick Faltstrom, Ned Freed, David
30562
 
+   Goldsmith, Tony Hansen, Edwin F. Hart, Paul Hoffman, David Hopwood,
30563
 
+   Simon Josefsson, Kent Karlsson, Dan Kohn, Markus Kuhn, Michael Kung,
30564
 
+   Alain LaBonte, Ira McDonald, Alexey Melnikov, MURATA Makoto, John
30565
 
+   Gardiner Myers, Chris Newman, Dan Oscarsson, Roozbeh Pournader,
30566
 
+   Murray Sargent, Markus Scherer, Keld Simonsen, Arnold Winkler,
30567
 
+   Kenneth Whistler and Misha Wolf.
30568
 
+
30569
 
+12.  Changes from RFC 2279
30570
 
+
30571
 
+   o  Restricted the range of characters to 0000-10FFFF (the UTF-16
30572
 
+      accessible range).
30573
 
+
30574
 
+   o  Made Unicode the source of the normative definition of UTF-8,
30575
 
+      keeping ISO/IEC 10646 as the reference for characters.
30576
 
+
30577
 
+   o  Straightened out terminology.  UTF-8 now described in terms of an
30578
 
+      encoding form of the character number.  UCS-2 and UCS-4 almost
30579
 
+      disappeared.
30580
 
+
30581
 
+   o  Turned the note warning against decoding of invalid sequences into
30582
 
+      a normative MUST NOT.
30583
 
+
30584
 
+   o  Added a new section about the UTF-8 BOM, with advice for
30585
 
+      protocols.
30586
 
+
30587
 
+   o  Removed suggested UNICODE-1-1-UTF-8 MIME charset registration.
30588
 
+
30589
 
+   o  Added an ABNF syntax for valid UTF-8 octet sequences
30590
 
+
30591
 
+   o  Expanded Security Considerations section, in particular impact of
30592
 
+      Unicode normalization
30593
 
+
30594
 
+
30595
 
+
30596
 
+
30597
 
+
30598
 
+
30599
 
+
30600
 
+
30601
 
+
30602
 
+Yergeau                     Standards Track                    [Page 11]
30603
 
+
30604
 
+RFC 3629                         UTF-8                     November 2003
30605
 
+
30606
 
+
30607
 
+13.  Normative References
30608
 
+
30609
 
+   [RFC2119]   Bradner, S., "Key words for use in RFCs to Indicate
30610
 
+               Requirement Levels", BCP 14, RFC 2119, March 1997.
30611
 
+
30612
 
+   [ISO.10646] International Organization for Standardization,
30613
 
+               "Information Technology - Universal Multiple-octet coded
30614
 
+               Character Set (UCS)", ISO/IEC Standard 10646,  comprised
30615
 
+               of ISO/IEC 10646-1:2000, "Information technology --
30616
 
+               Universal Multiple-Octet Coded Character Set (UCS) --
30617
 
+               Part 1: Architecture and Basic Multilingual Plane",
30618
 
+               ISO/IEC 10646-2:2001, "Information technology --
30619
 
+               Universal Multiple-Octet Coded Character Set (UCS) --
30620
 
+               Part 2:  Supplementary Planes" and ISO/IEC 10646-
30621
 
+               1:2000/Amd 1:2002, "Mathematical symbols and other
30622
 
+               characters".
30623
 
+
30624
 
+   [UNICODE]   The Unicode Consortium, "The Unicode Standard -- Version
30625
 
+               4.0",  defined by The Unicode Standard, Version 4.0
30626
 
+               (Boston, MA, Addison-Wesley, 2003.  ISBN 0-321-18578-1),
30627
 
+               April 2003, <http://www.unicode.org/unicode/standard/
30628
 
+               versions/enumeratedversions.html#Unicode_4_0_0>.
30629
 
+
30630
 
+14.  Informative References
30631
 
+
30632
 
+   [CESU-8]    Phipps, T., "Unicode Technical Report #26: Compatibility
30633
 
+               Encoding Scheme for UTF-16: 8-Bit (CESU-8)", UTR 26,
30634
 
+               April 2002,
30635
 
+               <http://www.unicode.org/unicode/reports/tr26/>.
30636
 
+
30637
 
+   [FSS_UTF]   X/Open Company Ltd., "X/Open Preliminary Specification --
30638
 
+               File System Safe UCS Transformation Format (FSS-UTF)",
30639
 
+               May 1993, <http://wwwold.dkuug.dk/jtc1/sc22/wg20/docs/
30640
 
+               N193-FSS-UTF.pdf>.
30641
 
+
30642
 
+   [RFC2045]   Freed, N. and N. Borenstein, "Multipurpose Internet Mail
30643
 
+               Extensions (MIME) Part One: Format of Internet Message
30644
 
+               Bodies", RFC 2045, November 1996.
30645
 
+
30646
 
+   [RFC2234]   Crocker, D. and P. Overell, "Augmented BNF for Syntax
30647
 
+               Specifications: ABNF", RFC 2234, November 1997.
30648
 
+
30649
 
+   [RFC2978]   Freed, N. and J. Postel, "IANA Charset Registration
30650
 
+               Procedures", BCP 19, RFC 2978, October 2000.
30651
 
+
30652
 
+
30653
 
+
30654
 
+
30655
 
+
30656
 
+
30657
 
+
30658
 
+Yergeau                     Standards Track                    [Page 12]
30659
 
+
30660
 
+RFC 3629                         UTF-8                     November 2003
30661
 
+
30662
 
+
30663
 
+   [UAX15]     Davis, M. and M. Duerst, "Unicode Standard Annex #15:
30664
 
+               Unicode Normalization Forms",  An integral part of The
30665
 
+               Unicode Standard, Version 4.0.0, April 2003, <http://
30666
 
+               www.unicode.org/unicode/reports/tr15>.
30667
 
+
30668
 
+   [US-ASCII]  American National Standards Institute, "Coded Character
30669
 
+               Set - 7-bit American Standard Code for Information
30670
 
+               Interchange", ANSI X3.4, 1986.
30671
 
+
30672
 
+15.  URIs
30673
 
+
30674
 
+   [1]  <http://www.unicode.org/unicode/standard/policies.html>
30675
 
+
30676
 
+16.  Intellectual Property Statement
30677
 
+
30678
 
+   The IETF takes no position regarding the validity or scope of any
30679
 
+   intellectual property or other rights that might be claimed to
30680
 
+   pertain to the implementation or use of the technology described in
30681
 
+   this document or the extent to which any license under such rights
30682
 
+   might or might not be available; neither does it represent that it
30683
 
+   has made any effort to identify any such rights.  Information on the
30684
 
+   IETF's procedures with respect to rights in standards-track and
30685
 
+   standards-related documentation can be found in BCP-11.  Copies of
30686
 
+   claims of rights made available for publication and any assurances of
30687
 
+   licenses to be made available, or the result of an attempt made to
30688
 
+   obtain a general license or permission for the use of such
30689
 
+   proprietary rights by implementors or users of this specification can
30690
 
+   be obtained from the IETF Secretariat.
30691
 
+
30692
 
+   The IETF invites any interested party to bring to its attention any
30693
 
+   copyrights, patents or patent applications, or other proprietary
30694
 
+   rights which may cover technology that may be required to practice
30695
 
+   this standard.  Please address the information to the IETF Executive
30696
 
+   Director.
30697
 
+
30698
 
+17.  Author's Address
30699
 
+
30700
 
+   Francois Yergeau
30701
 
+   Alis Technologies
30702
 
+   100, boul. Alexis-Nihon, bureau 600
30703
 
+   Montreal, QC  H4M 2P2
30704
 
+   Canada
30705
 
+
30706
 
+   Phone: +1 514 747 2547
30707
 
+   Fax:   +1 514 747 2561
30708
 
+   EMail: fyergeau@alis.com
30709
 
+
30710
 
+
30711
 
+
30712
 
+
30713
 
+
30714
 
+Yergeau                     Standards Track                    [Page 13]
30715
 
+
30716
 
+RFC 3629                         UTF-8                     November 2003
30717
 
+
30718
 
+
30719
 
+18.  Full Copyright Statement
30720
 
+
30721
 
+   Copyright (C) The Internet Society (2003).  All Rights Reserved.
30722
 
+
30723
 
+   This document and translations of it may be copied and furnished to
30724
 
+   others, and derivative works that comment on or otherwise explain it
30725
 
+   or assist in its implementation may be prepared, copied, published
30726
 
+   and distributed, in whole or in part, without restriction of any
30727
 
+   kind, provided that the above copyright notice and this paragraph are
30728
 
+   included on all such copies and derivative works.  However, this
30729
 
+   document itself may not be modified in any way, such as by removing
30730
 
+   the copyright notice or references to the Internet Society or other
30731
 
+   Internet organizations, except as needed for the purpose of
30732
 
+   developing Internet standards in which case the procedures for
30733
 
+   copyrights defined in the Internet Standards process must be
30734
 
+   followed, or as required to translate it into languages other than
30735
 
+   English.
30736
 
+
30737
 
+   The limited permissions granted above are perpetual and will not be
30738
 
+   revoked by the Internet Society or its successors or assignees.
30739
 
+
30740
 
+   This document and the information contained herein is provided on an
30741
 
+   "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
30742
 
+   TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
30743
 
+   BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
30744
 
+   HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
30745
 
+   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
30746
 
+
30747
 
+Acknowledgement
30748
 
+
30749
 
+   Funding for the RFC Editor function is currently provided by the
30750
 
+   Internet Society.
30751
 
+
30752
 
+
30753
 
+
30754
 
+
30755
 
+
30756
 
+
30757
 
+
30758
 
+
30759
 
+
30760
 
+
30761
 
+
30762
 
+
30763
 
+
30764
 
+
30765
 
+
30766
 
+
30767
 
+
30768
 
+
30769
 
+
30770
 
+Yergeau                     Standards Track                    [Page 14]
30771
 
+
30772
 
diff -urN dovecot-1.2.4/dovecot-libsieve/doc/rfc/vacation.rfc5230.txt dovecot-1.2.4.debian/dovecot-libsieve/doc/rfc/vacation.rfc5230.txt
30773
 
--- dovecot-1.2.4/dovecot-libsieve/doc/rfc/vacation.rfc5230.txt 1970-01-01 01:00:00.000000000 +0100
30774
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/doc/rfc/vacation.rfc5230.txt  2008-01-04 23:12:31.000000000 +0100
30775
 
@@ -0,0 +1,899 @@
30776
 
+
30777
 
+
30778
 
+
30779
 
+
30780
 
+
30781
 
+
30782
 
+Network Working Group                                       T. Showalter
30783
 
+Request for Comments: 5230
30784
 
+Category: Standards Track                                  N. Freed, Ed.
30785
 
+                                                        Sun Microsystems
30786
 
+                                                            January 2008
30787
 
+
30788
 
+
30789
 
+               Sieve Email Filtering: Vacation Extension
30790
 
+
30791
 
+Status of This Memo
30792
 
+
30793
 
+   This document specifies an Internet standards track protocol for the
30794
 
+   Internet community, and requests discussion and suggestions for
30795
 
+   improvements.  Please refer to the current edition of the "Internet
30796
 
+   Official Protocol Standards" (STD 1) for the standardization state
30797
 
+   and status of this protocol.  Distribution of this memo is unlimited.
30798
 
+
30799
 
+Abstract
30800
 
+
30801
 
+   This document describes an extension to the Sieve email filtering
30802
 
+   language for an autoresponder similar to that of the Unix "vacation"
30803
 
+   command for replying to messages.  Various safety features are
30804
 
+   included to prevent problems such as message loops.
30805
 
+
30806
 
+
30807
 
+
30808
 
+
30809
 
+
30810
 
+
30811
 
+
30812
 
+
30813
 
+
30814
 
+
30815
 
+
30816
 
+
30817
 
+
30818
 
+
30819
 
+
30820
 
+
30821
 
+
30822
 
+
30823
 
+
30824
 
+
30825
 
+
30826
 
+
30827
 
+
30828
 
+
30829
 
+
30830
 
+
30831
 
+
30832
 
+
30833
 
+Showalter & Freed           Standards Track                     [Page 1]
30834
 
+
30835
 
+RFC 5230               Sieve: Vacation Extension            January 2008
30836
 
+
30837
 
+
30838
 
+Table of Contents
30839
 
+
30840
 
+   1.  Introduction . . . . . . . . . . . . . . . . . . . . . . . . .  3
30841
 
+   2.  Conventions Used in This Document  . . . . . . . . . . . . . .  3
30842
 
+   3.  Capability Identifier  . . . . . . . . . . . . . . . . . . . .  3
30843
 
+   4.  Vacation Action  . . . . . . . . . . . . . . . . . . . . . . .  3
30844
 
+     4.1.  Days Parameter . . . . . . . . . . . . . . . . . . . . . .  3
30845
 
+     4.2.  Previous Response Tracking . . . . . . . . . . . . . . . .  4
30846
 
+     4.3.  Subject and From Parameters  . . . . . . . . . . . . . . .  6
30847
 
+     4.4.  MIME Parameter . . . . . . . . . . . . . . . . . . . . . .  6
30848
 
+     4.5.  Address Parameter and Limiting Replies to Personal
30849
 
+           Messages . . . . . . . . . . . . . . . . . . . . . . . . .  7
30850
 
+     4.6.  Restricting Replies to Automated Processes and Mailing
30851
 
+           Lists  . . . . . . . . . . . . . . . . . . . . . . . . . .  8
30852
 
+     4.7.  Interaction with Other Sieve Actions . . . . . . . . . . .  8
30853
 
+     4.8.  Examples . . . . . . . . . . . . . . . . . . . . . . . . .  9
30854
 
+   5.  Response Message Generation  . . . . . . . . . . . . . . . . .  9
30855
 
+     5.1.  SMTP MAIL FROM Address . . . . . . . . . . . . . . . . . .  9
30856
 
+     5.2.  Date . . . . . . . . . . . . . . . . . . . . . . . . . . .  9
30857
 
+     5.3.  Subject  . . . . . . . . . . . . . . . . . . . . . . . . . 10
30858
 
+     5.4.  From . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
30859
 
+     5.5.  To . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
30860
 
+     5.6.  Auto-Submitted . . . . . . . . . . . . . . . . . . . . . . 10
30861
 
+     5.7.  Message Body . . . . . . . . . . . . . . . . . . . . . . . 10
30862
 
+     5.8.  In-Reply-To and References . . . . . . . . . . . . . . . . 10
30863
 
+   6.  Relationship to Recommendations for Automatic Responses to
30864
 
+       Electronic Mail  . . . . . . . . . . . . . . . . . . . . . . . 11
30865
 
+   7.  Internationalization Considerations  . . . . . . . . . . . . . 11
30866
 
+   8.  Security Considerations  . . . . . . . . . . . . . . . . . . . 12
30867
 
+   9.  IANA Considerations  . . . . . . . . . . . . . . . . . . . . . 12
30868
 
+   10. References . . . . . . . . . . . . . . . . . . . . . . . . . . 13
30869
 
+     10.1. Normative References . . . . . . . . . . . . . . . . . . . 13
30870
 
+     10.2. Informative References . . . . . . . . . . . . . . . . . . 13
30871
 
+   Appendix A.  Acknowledgements  . . . . . . . . . . . . . . . . . . 15
30872
 
+
30873
 
+
30874
 
+
30875
 
+
30876
 
+
30877
 
+
30878
 
+
30879
 
+
30880
 
+
30881
 
+
30882
 
+
30883
 
+
30884
 
+
30885
 
+
30886
 
+
30887
 
+
30888
 
+
30889
 
+Showalter & Freed           Standards Track                     [Page 2]
30890
 
+
30891
 
+RFC 5230               Sieve: Vacation Extension            January 2008
30892
 
+
30893
 
+
30894
 
+1.  Introduction
30895
 
+
30896
 
+   This document defines an extension to the Sieve language defined in
30897
 
+   [RFC5228] for notification that messages to a particular recipient
30898
 
+   will not be answered immediately.
30899
 
+
30900
 
+2.  Conventions Used in This Document
30901
 
+
30902
 
+   Conventions for notations are as in [RFC5228] section 1.1.
30903
 
+
30904
 
+   The key words "MUST", "MUST NOT", "SHOULD", "SHOULD NOT", "REQUIRED",
30905
 
+   and "MAY" in this document are to be interpreted as defined in
30906
 
+   [RFC2119].
30907
 
+
30908
 
+3.  Capability Identifier
30909
 
+
30910
 
+   Sieve implementations that implement vacation have an identifier of
30911
 
+   "vacation" for use with the capability mechanism.
30912
 
+
30913
 
+4.  Vacation Action
30914
 
+
30915
 
+   Usage:   vacation [":days" number] [":subject" string]
30916
 
+                     [":from" string] [":addresses" string-list]
30917
 
+                     [":mime"] [":handle" string] <reason: string>
30918
 
+
30919
 
+   The "vacation" action implements a vacation autoresponder similar to
30920
 
+   the vacation command available under many versions of Unix.  Its
30921
 
+   purpose is to provide correspondents with notification that the user
30922
 
+   is away for an extended period of time and that they should not
30923
 
+   expect quick responses.
30924
 
+
30925
 
+   "Vacation" is used to respond to a message with another message.
30926
 
+   Vacation's messages are always addressed to the Return-Path address
30927
 
+   (that is, the envelope from address) of the message being responded
30928
 
+   to.
30929
 
+
30930
 
+4.1.  Days Parameter
30931
 
+
30932
 
+   The ":days" argument is used to specify the period in which addresses
30933
 
+   are kept and are not responded to, and is always specified in days.
30934
 
+   The minimum value used for this parameter is normally 1.  Sites MAY
30935
 
+   define a different minimum value as long as the minimum is greater
30936
 
+   than 0.  Sites MAY also define a maximum days value, which MUST be
30937
 
+   greater than 7, and SHOULD be greater than 30.
30938
 
+
30939
 
+   If ":days" is omitted, the default value is either 7 or the minimum
30940
 
+   value (as defined above), whichever is greater.
30941
 
+
30942
 
+
30943
 
+
30944
 
+
30945
 
+Showalter & Freed           Standards Track                     [Page 3]
30946
 
+
30947
 
+RFC 5230               Sieve: Vacation Extension            January 2008
30948
 
+
30949
 
+
30950
 
+   If the parameter given to ":days" is less than the minimum value,
30951
 
+   then the minimum value is used instead.
30952
 
+
30953
 
+   If ":days" exceeds the site-defined maximum, the site-defined maximum
30954
 
+   is used instead.
30955
 
+
30956
 
+4.2.  Previous Response Tracking
30957
 
+
30958
 
+   "Vacation" keeps track of all the responses it has sent to each
30959
 
+   address in some period (as specified by the :days optional argument).
30960
 
+   If vacation has not previously sent the response to this address
30961
 
+   within the given time period, it sends the "reason" argument to the
30962
 
+   SMTP MAIL FROM address [RFC2821] of the message that is being
30963
 
+   responded to.  (The SMTP MAIL FROM address should be available in the
30964
 
+   Return-path: header field if Sieve processing occurs after final
30965
 
+   delivery.)
30966
 
+
30967
 
+   Tracking is not just per address, but must also take the vacation
30968
 
+   response itself into account.  A script writer might, for example,
30969
 
+   have a vacation action that will send a general notice only once in
30970
 
+   any two-week period.  However, even if a sender has received this
30971
 
+   general notice, it may be important to send a specific notice when a
30972
 
+   message about something timely or something specific has been
30973
 
+   detected.
30974
 
+
30975
 
+   A particular vacation response can be identified in one of two ways.
30976
 
+   The first way is via an explicit :handle argument, which attaches a
30977
 
+   name to the response.  All vacation statements that use the same
30978
 
+   handle will be considered the same response for tracking purposes.
30979
 
+
30980
 
+   The second way is via a synthesis of the :subject, :from, :mime, and
30981
 
+   reason vacation command arguments.  All vacation actions that do not
30982
 
+   contain an explicit handle and that use an identical combination of
30983
 
+   these arguments are considered the same for tracking purposes.
30984
 
+
30985
 
+   For instance, if coyote@desert.example.org sends mail to
30986
 
+   roadrunner@acme.example.com twice, once with the subject "Cyrus bug"
30987
 
+   and once with the subject "come over for dinner", and
30988
 
+   roadrunner@acme.example.com has the script shown below,
30989
 
+   coyote@desert.example.org would receive two responses, one with the
30990
 
+   first message, one with the second.
30991
 
+
30992
 
+   require "vacation";
30993
 
+   if header :contains "subject" "cyrus" {
30994
 
+       vacation "I'm out -- send mail to cyrus-bugs";
30995
 
+   } else {
30996
 
+       vacation "I'm out -- call me at +1 304 555 0123";
30997
 
+   }
30998
 
+
30999
 
+
31000
 
+
31001
 
+Showalter & Freed           Standards Track                     [Page 4]
31002
 
+
31003
 
+RFC 5230               Sieve: Vacation Extension            January 2008
31004
 
+
31005
 
+
31006
 
+   In the above example, coyote@desert.example.org gets the second
31007
 
+   message despite having gotten the first one because separate vacation
31008
 
+   responses have been triggered.  This behavior is REQUIRED.
31009
 
+
31010
 
+   There is one important exception to this rule, however.  If the Sieve
31011
 
+   variables extension [RFC5229] is used, the arguments MUST NOT have
31012
 
+   undergone variable expansion prior to their use in response tracking.
31013
 
+   This is so that examples like the following script will only generate
31014
 
+   a single response to each incoming message with a different subject
31015
 
+   line.
31016
 
+
31017
 
+   require ["vacation", "variables"];
31018
 
+   if header :matches "subject" "*" {
31019
 
+       vacation :subject "Automatic response to: ${1}"
31020
 
+                "I'm away -- send mail to foo in my absence";
31021
 
+   }
31022
 
+
31023
 
+   As noted above, the optional ":handle" parameter can be used to tell
31024
 
+   the Sieve interpreter to treat two vacation actions with different
31025
 
+   arguments as the same command for purposes of response tracking.  The
31026
 
+   argument to ":handle" is a string that identifies the type of
31027
 
+   response being sent.  For instance, if tweety@cage.example.org sends
31028
 
+   mail to spike@doghouse.example.com twice, one with the subject
31029
 
+   "lunch?" and once with the subject "dinner?", and
31030
 
+   spike@doghouse.example.com has the script shown below,
31031
 
+   tweety@cage.example.org will only receive a single response.  (Which
31032
 
+   response is sent depends on the order in which the messages are
31033
 
+   processed.)
31034
 
+
31035
 
+   require "vacation";
31036
 
+   if header :contains "subject" "lunch" {
31037
 
+       vacation :handle "ran-away" "I'm out and can't meet for lunch";
31038
 
+   } else {
31039
 
+       vacation :handle "ran-away" "I'm out";
31040
 
+   }
31041
 
+
31042
 
+   NOTE: One way to implement the necessary mechanism here is to store a
31043
 
+   hash of either the current handle and the recipient address or, if no
31044
 
+   handle is provided, a hash of the vacation action parameters
31045
 
+   specifying the message content and the recipient address.  If a
31046
 
+   script is changed, implementations MAY reset the records of who has
31047
 
+   been responded to and when they have been responded to.
31048
 
+
31049
 
+   IMPLEMENTATION NOTE: Care must be taken in constructing a hash of
31050
 
+   vacation action parameters.  In particular, since most parameters are
31051
 
+   optional, it is important not to let the same string used as the
31052
 
+   value for different parameters produce the same hash value.  One
31053
 
+
31054
 
+
31055
 
+
31056
 
+
31057
 
+Showalter & Freed           Standards Track                     [Page 5]
31058
 
+
31059
 
+RFC 5230               Sieve: Vacation Extension            January 2008
31060
 
+
31061
 
+
31062
 
+   possible way to accomplish this is to apply the hash to a series of
31063
 
+   counted or null terminated strings, one for each possible parameter
31064
 
+   in particular order.
31065
 
+
31066
 
+   Implementations are free to limit the number of remembered responses;
31067
 
+   however, the limit MUST NOT be less than 1000.  When limiting the
31068
 
+   number of tracked responses, implementations SHOULD discard the
31069
 
+   oldest ones first.
31070
 
+
31071
 
+4.3.  Subject and From Parameters
31072
 
+
31073
 
+   The ":subject" parameter specifies a subject line to attach to any
31074
 
+   vacation response that is generated.  UTF-8 characters can be used in
31075
 
+   the string argument; implementations MUST convert the string to
31076
 
+   [RFC2047] encoded words if and only if non-ASCII characters are
31077
 
+   present.  Implementations MUST generate an appropriate default
31078
 
+   subject line as specified below if no :subject parameter is
31079
 
+   specified.
31080
 
+
31081
 
+   A ":from" parameter may be used to specify an alternate address to
31082
 
+   use in the From field of vacation messages.  The string must specify
31083
 
+   a valid [RFC2822] mailbox-list.  Implementations SHOULD check the
31084
 
+   syntax and generate an error when a syntactically invalid ":from"
31085
 
+   parameter is specified.  Implementations MAY also impose restrictions
31086
 
+   on what addresses can specified in a ":from" parameter; it is
31087
 
+   suggested that values that fail such a validity check simply be
31088
 
+   ignored rather than cause the vacation action to fail.
31089
 
+
31090
 
+4.4.  MIME Parameter
31091
 
+
31092
 
+   The ":mime" parameter, if supplied, specifies that the reason string
31093
 
+   is, in fact, a MIME entity as defined in [RFC2045] section 2.4,
31094
 
+   including both MIME headers and content.
31095
 
+
31096
 
+   If the optional :mime parameter is not supplied, the reason string is
31097
 
+   considered a UTF-8 string.
31098
 
+
31099
 
+
31100
 
+
31101
 
+
31102
 
+
31103
 
+
31104
 
+
31105
 
+
31106
 
+
31107
 
+
31108
 
+
31109
 
+
31110
 
+
31111
 
+
31112
 
+
31113
 
+Showalter & Freed           Standards Track                     [Page 6]
31114
 
+
31115
 
+RFC 5230               Sieve: Vacation Extension            January 2008
31116
 
+
31117
 
+
31118
 
+   require "vacation";
31119
 
+   vacation :mime text:
31120
 
+   Content-Type: multipart/alternative; boundary=foo
31121
 
+
31122
 
+   --foo
31123
 
+
31124
 
+   I'm at the beach relaxing.  Mmmm, surf...
31125
 
+
31126
 
+   --foo
31127
 
+   Content-Type: text/html; charset=us-ascii
31128
 
+
31129
 
+   <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN"
31130
 
+    "http://www.w3.org/TR/REC-html40/strict.dtd">
31131
 
+   <HTML><HEAD><TITLE>How to relax</TITLE>
31132
 
+   <BASE HREF="http://home.example.com/pictures/"></HEAD>
31133
 
+   <BODY><P>I'm at the <A HREF="beach.gif">beach</A> relaxing.
31134
 
+   Mmmm, <A HREF="ocean.gif">surf</A>...
31135
 
+   </BODY></HTML>
31136
 
+
31137
 
+   --foo--
31138
 
+   .
31139
 
+
31140
 
+4.5.  Address Parameter and Limiting Replies to Personal Messages
31141
 
+
31142
 
+   "Vacation" MUST NOT respond to a message unless the recipient user's
31143
 
+   email address is in a "To", "Cc", "Bcc", "Resent-To", "Resent-Cc", or
31144
 
+   "Resent-Bcc" line of the original message.  An email address is
31145
 
+   considered to belong to the recipient if it is one of:
31146
 
+
31147
 
+   1.  an email address known by the implementation to be associated
31148
 
+       with the recipient,
31149
 
+
31150
 
+   2.  the final envelope recipient address if it's available to the
31151
 
+       implementation, or
31152
 
+
31153
 
+   3.  an address specified by the script writer via the ":addresses"
31154
 
+       argument described in the next paragraph.
31155
 
+
31156
 
+   Users can supply additional mail addresses that are theirs with the
31157
 
+   ":addresses" argument, which takes a string-list listing additional
31158
 
+   addresses that a user might have.  These addresses are considered to
31159
 
+   belong to the recipient user in addition to the addresses known to
31160
 
+   the implementation.
31161
 
+
31162
 
+
31163
 
+
31164
 
+
31165
 
+
31166
 
+
31167
 
+
31168
 
+
31169
 
+Showalter & Freed           Standards Track                     [Page 7]
31170
 
+
31171
 
+RFC 5230               Sieve: Vacation Extension            January 2008
31172
 
+
31173
 
+
31174
 
+4.6.  Restricting Replies to Automated Processes and Mailing Lists
31175
 
+
31176
 
+   Implementations MAY refuse to send a vacation response to a message
31177
 
+   that contains any header or content that makes it appear that a
31178
 
+   response would not be appropriate.
31179
 
+
31180
 
+   Implementations MUST have a list of addresses that "vacation" MUST
31181
 
+   NOT send mail to.  However, the contents of this list are
31182
 
+   implementation defined.  The purpose of this list is to stop mail
31183
 
+   from going to addresses used by system daemons that would not care if
31184
 
+   the user is actually reading her mail.
31185
 
+
31186
 
+   Implementations are encouraged, however, to include well-known
31187
 
+   addresses like "MAILER-DAEMON", "LISTSERV", "majordomo", and other
31188
 
+   addresses typically used only by automated systems.  Additionally,
31189
 
+   addresses ending in "-request" or beginning in "owner-", i.e.,
31190
 
+   reserved for mailing list software, are also suggested.
31191
 
+
31192
 
+   Implementors may take guidance from [RFC2142], but should be careful.
31193
 
+   Some addresses, like "POSTMASTER", are generally actually managed by
31194
 
+   people, and people do care if the user is going to be unavailable.
31195
 
+
31196
 
+   Implementations SHOULD NOT respond to any message that contains a
31197
 
+   "List-Id" [RFC2919], "List-Help", "List-Subscribe", "List-
31198
 
+   Unsubscribe", "List-Post", "List-Owner", or "List-Archive" [RFC2369]
31199
 
+   header field.
31200
 
+
31201
 
+   Implementations SHOULD NOT respond to any message that has an "Auto-
31202
 
+   submitted" header field with a value other than "no".  This header
31203
 
+   field is described in [RFC3834].
31204
 
+
31205
 
+4.7.  Interaction with Other Sieve Actions
31206
 
+
31207
 
+   Vacation does not affect Sieve's implicit keep action.
31208
 
+
31209
 
+   Vacation can only be executed once per script.  A script MUST fail
31210
 
+   with an appropriate error if it attempts to execute two or more
31211
 
+   vacation actions.
31212
 
+
31213
 
+   Implementations MUST NOT consider vacation used with discard, keep,
31214
 
+   fileinto, or redirect an error.  The vacation action is incompatible
31215
 
+   with the Sieve reject and refuse actions [REJECT].
31216
 
+
31217
 
+
31218
 
+
31219
 
+
31220
 
+
31221
 
+
31222
 
+
31223
 
+
31224
 
+
31225
 
+Showalter & Freed           Standards Track                     [Page 8]
31226
 
+
31227
 
+RFC 5230               Sieve: Vacation Extension            January 2008
31228
 
+
31229
 
+
31230
 
+4.8.  Examples
31231
 
+
31232
 
+   Here is a simple use of vacation.
31233
 
+
31234
 
+   require "vacation";
31235
 
+   vacation :days 23 :addresses ["tjs@example.edu",
31236
 
+                                 "ts4z@landru.example.edu"]
31237
 
+   "I'm away until October 19.
31238
 
+   If it's an emergency, call 911, I guess." ;
31239
 
+
31240
 
+   By mingling vacation with other rules, users can do something more
31241
 
+   selective.
31242
 
+
31243
 
+   require "vacation";
31244
 
+   if header :contains "from" "boss@example.edu" {
31245
 
+       redirect "pleeb@isp.example.org";
31246
 
+   } else {
31247
 
+       vacation "Sorry, I'm away, I'll read your
31248
 
+   message when I get around to it.";
31249
 
+   }
31250
 
+
31251
 
+5.  Response Message Generation
31252
 
+
31253
 
+   This section details the requirements for the generated response
31254
 
+   message.
31255
 
+
31256
 
+   It is worth noting that the input message and arguments may be in
31257
 
+   UTF-8, and that implementations MUST deal with UTF-8 input, although
31258
 
+   implementations MAY transcode to other character sets as regional
31259
 
+   taste dictates.  When :mime is used, the reason argument also
31260
 
+   contains MIME header information.  The headers must conform to MIME
31261
 
+   conventions; in particular, 8bit text is not allowed.
31262
 
+   Implementations SHOULD reject vacation :mime actions containing 8bit
31263
 
+   header material.
31264
 
+
31265
 
+5.1.  SMTP MAIL FROM Address
31266
 
+
31267
 
+   The SMTP MAIL FROM address of the message envelope SHOULD be set to
31268
 
+   <>.  NOTIFY=NEVER SHOULD also be set in the RCPT TO line during the
31269
 
+   SMTP transaction if the NOTARY SMTP extension [RFC3461] is available.
31270
 
+
31271
 
+5.2.  Date
31272
 
+
31273
 
+   The Date field SHOULD be set to the date and time when the vacation
31274
 
+   response was generated.  Note that this may not be the same as the
31275
 
+   time the message was delivered to the user.
31276
 
+
31277
 
+
31278
 
+
31279
 
+
31280
 
+
31281
 
+Showalter & Freed           Standards Track                     [Page 9]
31282
 
+
31283
 
+RFC 5230               Sieve: Vacation Extension            January 2008
31284
 
+
31285
 
+
31286
 
+5.3.  Subject
31287
 
+
31288
 
+   Users can specify the Subject of the reply with the ":subject"
31289
 
+   parameter.  If the :subject parameter is not supplied, then the
31290
 
+   subject is generated as follows: The subject is set to the characters
31291
 
+   "Auto: " followed by the original subject.  An appropriate fixed
31292
 
+   Subject, such as "Automated reply", SHOULD be used in the event that
31293
 
+   :subject isn't specified and the original message doesn't contain a
31294
 
+   Subject field.
31295
 
+
31296
 
+5.4.  From
31297
 
+
31298
 
+   Unless explicitly overridden with a :from parameter, the From field
31299
 
+   SHOULD be set to the address of the owner of the Sieve script.
31300
 
+
31301
 
+5.5.  To
31302
 
+
31303
 
+   The To field SHOULD be set to the address of the recipient of the
31304
 
+   response.
31305
 
+
31306
 
+5.6.  Auto-Submitted
31307
 
+
31308
 
+   An Auto-Submitted field with a value of "auto-replied" SHOULD be
31309
 
+   included in the message header of any vacation message sent.
31310
 
+
31311
 
+5.7.  Message Body
31312
 
+
31313
 
+   The body of the message is taken from the reason string in the
31314
 
+   vacation command.
31315
 
+
31316
 
+5.8.  In-Reply-To and References
31317
 
+
31318
 
+   Replies MUST have the In-Reply-To field set to the Message-ID of the
31319
 
+   original message, and the References field SHOULD be updated with the
31320
 
+   Message-ID of the original message.
31321
 
+
31322
 
+   If the original message lacks a Message-ID, an In-Reply-To need not
31323
 
+   be generated, and References need not be changed.
31324
 
+
31325
 
+   Section 3.6.4 of [RFC2822] provides a complete description of how
31326
 
+   References fields should be generated.
31327
 
+
31328
 
+
31329
 
+
31330
 
+
31331
 
+
31332
 
+
31333
 
+
31334
 
+
31335
 
+
31336
 
+
31337
 
+Showalter & Freed           Standards Track                    [Page 10]
31338
 
+
31339
 
+RFC 5230               Sieve: Vacation Extension            January 2008
31340
 
+
31341
 
+
31342
 
+6.  Relationship to Recommendations for Automatic Responses to
31343
 
+    Electronic Mail
31344
 
+
31345
 
+   The vacation extension implements a "Personal Responder" in the
31346
 
+   terminology defined in [RFC3834].  Care has been taken in this
31347
 
+   specification to comply with the recommendations of [RFC3834]
31348
 
+   regarding how personal responders should behave.
31349
 
+
31350
 
+7.  Internationalization Considerations
31351
 
+
31352
 
+   Internationalization capabilities provided by the base Sieve language
31353
 
+   are discussed in [RFC5228].  However, the vacation extension is the
31354
 
+   first Sieve extension to be defined that is capable of creating
31355
 
+   entirely new messages.  This section deals with internationalization
31356
 
+   issues raised by the use of the vacation extension.
31357
 
+
31358
 
+   Vacation messages are normally written using the UTF-8 charset,
31359
 
+   allowing text to be written in most of the world's languages.
31360
 
+   Additionally, the :mime parameter allows specification of arbitrary
31361
 
+   MIME content.  In particular, this makes it possible to use
31362
 
+   multipart/alternative objects to specify vacation responses in
31363
 
+   multiple languages simultaneously.
31364
 
+
31365
 
+   The Sieve language itself allows a vacation response to be selected
31366
 
+   based on the content of the original message.  For example, the
31367
 
+   Accept-Language or Content-Language header fields [RFC3282] could be
31368
 
+   checked and used to select appropriate text:
31369
 
+
31370
 
+   require "vacation";
31371
 
+   if header :contains ["accept-language", "content-language"] "en"
31372
 
+   {
31373
 
+       vacation "I am away this week.";
31374
 
+   } else {
31375
 
+       vacation "Estoy ausente esta semana.";
31376
 
+   }
31377
 
+
31378
 
+   Note that this rather simplistic test of the field values fails to
31379
 
+   take the structure of the fields into account and hence could be
31380
 
+   fooled by some more complex field values.  A more elaborate test
31381
 
+   could be used to deal with this problem.
31382
 
+
31383
 
+   The approach of explicitly coding language selection criteria in
31384
 
+   scripts is preferred because in many cases language selection issues
31385
 
+   are conflated with other selection issues.  For example, it may be
31386
 
+   appropriate to use informal text in one language for vacation
31387
 
+   responses sent to a fellow employee while using more formal text in a
31388
 
+   different language in a response sent to a total stranger outside the
31389
 
+   company:
31390
 
+
31391
 
+
31392
 
+
31393
 
+Showalter & Freed           Standards Track                    [Page 11]
31394
 
+
31395
 
+RFC 5230               Sieve: Vacation Extension            January 2008
31396
 
+
31397
 
+
31398
 
+   require "vacation";
31399
 
+   if address :matches "from" "*@ourdivision.example.com"
31400
 
+   {
31401
 
+       vacation :subject "Gone fishing"
31402
 
+                "Having lots of fun! Back in a day or two!";
31403
 
+   } else {
31404
 
+       vacation :subject "Je suis parti cette semaine"
31405
 
+                "Je lirai votre message quand je retourne.";
31406
 
+   }
31407
 
+
31408
 
+   IMPLEMENTATION NOTE: A graphical Sieve generation interface could in
31409
 
+   principle be used to hide the complexity of specifying response
31410
 
+   selection criteria from end users.  Figuring out the right set of
31411
 
+   options to present in a graphical interface is likely a nontrivial
31412
 
+   proposition, but this is more because of the need to employ a variety
31413
 
+   of criteria to select different sorts of responses to send to
31414
 
+   different classes of people than because of the issues involved in
31415
 
+   selecting a response in an appropriate language.
31416
 
+
31417
 
+8.  Security Considerations
31418
 
+
31419
 
+   It is critical that implementations correctly implement the behavior
31420
 
+   and restrictions described throughout this document.  Replies MUST
31421
 
+   NOT be sent out in response to messages not sent directly to the
31422
 
+   user, and replies MUST NOT be sent out more often than the :days
31423
 
+   argument states unless the script changes.
31424
 
+
31425
 
+   If mail is forwarded from a site that uses subaddressing, it may be
31426
 
+   impossible to list all recipient addresses with ":addresses".
31427
 
+
31428
 
+   Security issues associated with mail auto-responders are fully
31429
 
+   discussed in the security considerations section of [RFC3834].  This
31430
 
+   document is believed not to introduce any additional security
31431
 
+   considerations in this general area.
31432
 
+
31433
 
+9.  IANA Considerations
31434
 
+
31435
 
+   The following template specifies the IANA registration of the
31436
 
+   vacation Sieve extension specified in this document:
31437
 
+
31438
 
+   To: iana@iana.org
31439
 
+   Subject: Registration of new Sieve extension
31440
 
+
31441
 
+   Capability name: vacation
31442
 
+   Description:     adds an action for generating an auto-reply saying
31443
 
+                    that the original message will not be read or
31444
 
+                    answered immediately
31445
 
+   RFC number:      RFC 5230
31446
 
+
31447
 
+
31448
 
+
31449
 
+Showalter & Freed           Standards Track                    [Page 12]
31450
 
+
31451
 
+RFC 5230               Sieve: Vacation Extension            January 2008
31452
 
+
31453
 
+
31454
 
+   Contact address: The Sieve discussion list <ietf-mta-filters@imc.org>
31455
 
+
31456
 
+   This information has been added to the list of Sieve extensions given
31457
 
+   on http://www.iana.org/assignments/sieve-extensions.
31458
 
+
31459
 
+10.  References
31460
 
+
31461
 
+10.1.  Normative References
31462
 
+
31463
 
+   [RFC2045]  Freed, N. and N. Borenstein, "Multipurpose Internet Mail
31464
 
+              Extensions (MIME) Part One: Format of Internet Message
31465
 
+              Bodies", RFC 2045, November 1996.
31466
 
+
31467
 
+   [RFC2047]  Moore, K., "MIME (Multipurpose Internet Mail Extensions)
31468
 
+              Part Three: Message Header Extensions for Non-ASCII Text",
31469
 
+              RFC 2047, November 1996.
31470
 
+
31471
 
+   [RFC2119]  Bradner, S., "Key words for use in RFCs to Indicate
31472
 
+              Requirement Levels", BCP 14, RFC 2119, March 1997.
31473
 
+
31474
 
+   [RFC2822]  Resnick, P., "Internet Message Format", RFC 2822,
31475
 
+              April 2001.
31476
 
+
31477
 
+   [RFC3461]  Moore, K., "Simple Mail Transfer Protocol (SMTP) Service
31478
 
+              Extension for Delivery Status Notifications (DSNs)",
31479
 
+              RFC 3461, January 2003.
31480
 
+
31481
 
+   [RFC3834]  Moore, K., "Recommendations for Automatic Responses to
31482
 
+              Electronic Mail", RFC 3834, August 2004.
31483
 
+
31484
 
+   [RFC5228]  Guenther, P., Ed. and T. Showalter, Ed., "Sieve: An Email
31485
 
+              Filtering Language", RFC 5228, January 2008.
31486
 
+
31487
 
+   [RFC5229]  Homme, K., "Sieve Email Filtering: Variables Extension",
31488
 
+              RFC 5229, January 2008.
31489
 
+
31490
 
+10.2.  Informative References
31491
 
+
31492
 
+   [REJECT]   Stone, A., Elvey, M., and A. Melnikov, "Sieve Email
31493
 
+              Filtering: Reject Extension", Work in Progress,
31494
 
+              October 2007.
31495
 
+
31496
 
+   [RFC2142]  Crocker, D., "MAILBOX NAMES FOR COMMON SERVICES, ROLES AND
31497
 
+              FUNCTIONS", RFC 2142, May 1997.
31498
 
+
31499
 
+   [RFC2369]  Neufeld, G. and J. Baer, "The Use of URLs as Meta-Syntax
31500
 
+              for Core Mail List Commands and their Transport through
31501
 
+              Message Header Fields", RFC 2369, July 1998.
31502
 
+
31503
 
+
31504
 
+
31505
 
+Showalter & Freed           Standards Track                    [Page 13]
31506
 
+
31507
 
+RFC 5230               Sieve: Vacation Extension            January 2008
31508
 
+
31509
 
+
31510
 
+   [RFC2821]  Klensin, J., "Simple Mail Transfer Protocol", RFC 2821,
31511
 
+              April 2001.
31512
 
+
31513
 
+   [RFC2919]  Chandhok, R. and G. Wenger, "List-Id: A Structured Field
31514
 
+              and Namespace for the Identification of Mailing Lists",
31515
 
+              RFC 2919, March 2001.
31516
 
+
31517
 
+   [RFC3282]  Alvestrand, H., "Content Language Headers", RFC 3282,
31518
 
+              May 2002.
31519
 
+
31520
 
+
31521
 
+
31522
 
+
31523
 
+
31524
 
+
31525
 
+
31526
 
+
31527
 
+
31528
 
+
31529
 
+
31530
 
+
31531
 
+
31532
 
+
31533
 
+
31534
 
+
31535
 
+
31536
 
+
31537
 
+
31538
 
+
31539
 
+
31540
 
+
31541
 
+
31542
 
+
31543
 
+
31544
 
+
31545
 
+
31546
 
+
31547
 
+
31548
 
+
31549
 
+
31550
 
+
31551
 
+
31552
 
+
31553
 
+
31554
 
+
31555
 
+
31556
 
+
31557
 
+
31558
 
+
31559
 
+
31560
 
+
31561
 
+Showalter & Freed           Standards Track                    [Page 14]
31562
 
+
31563
 
+RFC 5230               Sieve: Vacation Extension            January 2008
31564
 
+
31565
 
+
31566
 
+Appendix A.  Acknowledgements
31567
 
+
31568
 
+   This extension is obviously inspired by Eric Allman's vacation
31569
 
+   program under Unix.  The authors owe a great deal to Carnegie Mellon
31570
 
+   University, Cyrus Daboo, Lawrence Greenfield, Michael Haardt, Kjetil
31571
 
+   Torgrim Homme, Arnt Gulbrandsen, Mark Mallett, Alexey Melnikov,
31572
 
+   Jeffrey Hutzelman, Philip Guenther, and many others whose names have
31573
 
+   been lost during the inexcusably long gestation period of this
31574
 
+   document.
31575
 
+
31576
 
+Authors' Addresses
31577
 
+
31578
 
+   Tim Showalter
31579
 
+
31580
 
+   EMail: tjs@psaux.com
31581
 
+
31582
 
+
31583
 
+   Ned Freed (editor)
31584
 
+   Sun Microsystems
31585
 
+   3401 Centrelake Drive, Suite 410
31586
 
+   Ontario, CA  92761-1205
31587
 
+   USA
31588
 
+
31589
 
+   Phone: +1 909 457 4293
31590
 
+   EMail: ned.freed@mrochek.com
31591
 
+
31592
 
+
31593
 
+
31594
 
+
31595
 
+
31596
 
+
31597
 
+
31598
 
+
31599
 
+
31600
 
+
31601
 
+
31602
 
+
31603
 
+
31604
 
+
31605
 
+
31606
 
+
31607
 
+
31608
 
+
31609
 
+
31610
 
+
31611
 
+
31612
 
+
31613
 
+
31614
 
+
31615
 
+
31616
 
+
31617
 
+Showalter & Freed           Standards Track                    [Page 15]
31618
 
+
31619
 
+RFC 5230               Sieve: Vacation Extension            January 2008
31620
 
+
31621
 
+
31622
 
+Full Copyright Statement
31623
 
+
31624
 
+   Copyright (C) The IETF Trust (2008).
31625
 
+
31626
 
+   This document is subject to the rights, licenses and restrictions
31627
 
+   contained in BCP 78, and except as set forth therein, the authors
31628
 
+   retain all their rights.
31629
 
+
31630
 
+   This document and the information contained herein are provided on an
31631
 
+   "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS
31632
 
+   OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY, THE IETF TRUST AND
31633
 
+   THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS
31634
 
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF
31635
 
+   THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
31636
 
+   WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
31637
 
+
31638
 
+Intellectual Property
31639
 
+
31640
 
+   The IETF takes no position regarding the validity or scope of any
31641
 
+   Intellectual Property Rights or other rights that might be claimed to
31642
 
+   pertain to the implementation or use of the technology described in
31643
 
+   this document or the extent to which any license under such rights
31644
 
+   might or might not be available; nor does it represent that it has
31645
 
+   made any independent effort to identify any such rights.  Information
31646
 
+   on the procedures with respect to rights in RFC documents can be
31647
 
+   found in BCP 78 and BCP 79.
31648
 
+
31649
 
+   Copies of IPR disclosures made to the IETF Secretariat and any
31650
 
+   assurances of licenses to be made available, or the result of an
31651
 
+   attempt made to obtain a general license or permission for the use of
31652
 
+   such proprietary rights by implementers or users of this
31653
 
+   specification can be obtained from the IETF on-line IPR repository at
31654
 
+   http://www.ietf.org/ipr.
31655
 
+
31656
 
+   The IETF invites any interested party to bring to its attention any
31657
 
+   copyrights, patents or patent applications, or other proprietary
31658
 
+   rights that may cover technology that may be required to implement
31659
 
+   this standard.  Please address the information to the IETF at
31660
 
+   ietf-ipr@ietf.org.
31661
 
+
31662
 
+
31663
 
+
31664
 
+
31665
 
+
31666
 
+
31667
 
+
31668
 
+
31669
 
+
31670
 
+
31671
 
+
31672
 
+
31673
 
+Showalter & Freed           Standards Track                    [Page 16]
31674
 
+
31675
 
diff -urN dovecot-1.2.4/dovecot-libsieve/doc/rfc/variables.rfc5229.txt dovecot-1.2.4.debian/dovecot-libsieve/doc/rfc/variables.rfc5229.txt
31676
 
--- dovecot-1.2.4/dovecot-libsieve/doc/rfc/variables.rfc5229.txt        1970-01-01 01:00:00.000000000 +0100
31677
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/doc/rfc/variables.rfc5229.txt 2008-07-30 15:17:37.000000000 +0200
31678
 
@@ -0,0 +1,619 @@
31679
 
+
31680
 
+
31681
 
+
31682
 
+
31683
 
+
31684
 
+
31685
 
+Network Working Group                                           K. Homme
31686
 
+Request for Comments: 5229                            University of Oslo
31687
 
+Updates: 5228                                               January 2008
31688
 
+Category: Standards Track
31689
 
+
31690
 
+
31691
 
+               Sieve Email Filtering: Variables Extension
31692
 
+
31693
 
+Status of This Memo
31694
 
+
31695
 
+   This document specifies an Internet standards track protocol for the
31696
 
+   Internet community, and requests discussion and suggestions for
31697
 
+   improvements.  Please refer to the current edition of the "Internet
31698
 
+   Official Protocol Standards" (STD 1) for the standardization state
31699
 
+   and status of this protocol.  Distribution of this memo is unlimited.
31700
 
+
31701
 
+Abstract
31702
 
+
31703
 
+   In advanced mail filtering rule sets, it is useful to keep state or
31704
 
+   configuration details across rules.  This document updates the Sieve
31705
 
+   filtering language (RFC 5228) with an extension to support variables.
31706
 
+   The extension changes the interpretation of strings, adds an action
31707
 
+   to store data in variables, and supplies a new test so that the value
31708
 
+   of a string can be examined.
31709
 
+
31710
 
+
31711
 
+
31712
 
+
31713
 
+
31714
 
+
31715
 
+
31716
 
+
31717
 
+
31718
 
+
31719
 
+
31720
 
+
31721
 
+
31722
 
+
31723
 
+
31724
 
+
31725
 
+
31726
 
+
31727
 
+
31728
 
+
31729
 
+
31730
 
+
31731
 
+
31732
 
+
31733
 
+
31734
 
+
31735
 
+
31736
 
+Homme                       Standards Track                     [Page 1]
31737
 
+
31738
 
+RFC 5229               Sieve: Variables Extension           January 2008
31739
 
+
31740
 
+
31741
 
+1.  Introduction
31742
 
+
31743
 
+   This is an extension to the Sieve language defined by [SIEVE].  It
31744
 
+   adds support for storing and referencing named data.  The mechanisms
31745
 
+   detailed in this document will only apply to Sieve scripts that
31746
 
+   include a require clause for the "variables" extension.  The require
31747
 
+   clauses themselves are not affected by this extension.
31748
 
+
31749
 
+   Conventions for notations are as in [SIEVE] section 1.1, including
31750
 
+   use of [KEYWORDS] and [ABNF].  The grammar builds on the grammar of
31751
 
+   [SIEVE].  In this document, "character" means a character from the
31752
 
+   ISO 10646 coded character set [ISO10646], which may consist of
31753
 
+   multiple octets coded in [UTF-8], and "variable" is a named reference
31754
 
+   to data stored or read back using the mechanisms of this extension.
31755
 
+
31756
 
+2.  Capability Identifier
31757
 
+
31758
 
+   The capability string associated with the extension defined in this
31759
 
+   document is "variables".
31760
 
+
31761
 
+3.  Interpretation of Strings
31762
 
+
31763
 
+   This extension changes the semantics of quoted-string, multi-line-
31764
 
+   literal and multi-line-dotstuff found in [SIEVE] to enable the
31765
 
+   inclusion of the value of variables.
31766
 
+
31767
 
+   When a string is evaluated, substrings matching variable-ref SHALL be
31768
 
+   replaced by the value of variable-name.  Only one pass through the
31769
 
+   string SHALL be done.  Variable names are case insensitive, so "foo"
31770
 
+   and "FOO" refer to the same variable.  Unknown variables are replaced
31771
 
+   by the empty string.
31772
 
+
31773
 
+      variable-ref        =  "${" [namespace] variable-name "}"
31774
 
+      namespace           =  identifier "." *sub-namespace
31775
 
+      sub-namespace       =  variable-name "."
31776
 
+      variable-name       =  num-variable / identifier
31777
 
+      num-variable        =  1*DIGIT
31778
 
+
31779
 
+   Examples:
31780
 
+      "&%${}!"     => unchanged, as the empty string is an illegal
31781
 
+                      identifier
31782
 
+      "${doh!}"    => unchanged, as "!" is illegal in identifiers
31783
 
+
31784
 
+      The variable "company" holds the value "ACME".  No other variables
31785
 
+      are set.
31786
 
+
31787
 
+      "${full}"         => the empty string
31788
 
+      "${company}"      => "ACME"
31789
 
+
31790
 
+
31791
 
+
31792
 
+Homme                       Standards Track                     [Page 2]
31793
 
+
31794
 
+RFC 5229               Sieve: Variables Extension           January 2008
31795
 
+
31796
 
+
31797
 
+      "${BAD${Company}" => "${BADACME"
31798
 
+      "${President, ${Company} Inc.}"
31799
 
+                        => "${President, ACME Inc.}"
31800
 
+
31801
 
+   The expanded string MUST use the variable values that are current
31802
 
+   when control reaches the statement the string is part of.
31803
 
+
31804
 
+   Strings where no variable substitutions take place are referred to as
31805
 
+   constant strings.  Future extensions may specify that passing non-
31806
 
+   constant strings as arguments to its actions or tests is an error.
31807
 
+
31808
 
+   Namespaces are meant for future extensions that make internal state
31809
 
+   available through variables.  These variables SHOULD be put in a
31810
 
+   namespace whose first component is the same as its capability string.
31811
 
+   Such extensions SHOULD state which, if any, of the variables in its
31812
 
+   namespace are modifiable with the "set" action.
31813
 
+
31814
 
+   References to namespaces without a prior require statement for the
31815
 
+   relevant extension MUST cause an error.
31816
 
+
31817
 
+   Tests or actions in future extensions may need to access the
31818
 
+   unexpanded version of the string argument and, e.g., do the expansion
31819
 
+   after setting variables in its namespace.  The design of the
31820
 
+   implementation should allow this.
31821
 
+
31822
 
+3.1.  Quoting and Encoded Characters
31823
 
+
31824
 
+   The semantics of quoting using backslash are not changed: backslash
31825
 
+   quoting is resolved before doing variable substitution.  Similarly,
31826
 
+   encoded character processing (see Section 2.4.2.4 of [SIEVE]) is
31827
 
+   performed before doing variable substitution, but after quoting.
31828
 
+
31829
 
+   Examples:
31830
 
+      "${fo\o}"  => ${foo}  => the expansion of variable foo.
31831
 
+      "${fo\\o}" => ${fo\o} => illegal identifier => left verbatim.
31832
 
+      "\${foo}"  => ${foo}  => the expansion of variable foo.
31833
 
+      "\\${foo}" => \${foo} => a backslash character followed by the
31834
 
+                               expansion of variable foo.
31835
 
+
31836
 
+      If it is required to include a character sequence such as
31837
 
+      "${beep}" verbatim in a text literal, the user can define a
31838
 
+      variable to circumvent expansion to the empty string.
31839
 
+
31840
 
+   Example:
31841
 
+      set "dollar" "$";
31842
 
+      set "text" "regarding ${dollar}{beep}";
31843
 
+
31844
 
+
31845
 
+
31846
 
+
31847
 
+
31848
 
+Homme                       Standards Track                     [Page 3]
31849
 
+
31850
 
+RFC 5229               Sieve: Variables Extension           January 2008
31851
 
+
31852
 
+
31853
 
+   Example:
31854
 
+      require ["encoded-character", "variables"];
31855
 
+      set "name" "Ethelbert"
31856
 
+      if header :contains "Subject" "dear${hex:20 24 7b 4e}ame}" {
31857
 
+          # the test string is "dear Ethelbert"
31858
 
+      }
31859
 
+
31860
 
+3.2.  Match Variables
31861
 
+
31862
 
+   A "match variable" has a name consisting only of decimal digits and
31863
 
+   has no namespace component.
31864
 
+
31865
 
+   The decimal value of the match variable name will index the list of
31866
 
+   matching strings from the most recently evaluated successful match of
31867
 
+   type ":matches".  The list is empty if no match has been successful.
31868
 
+
31869
 
+       Note: Extra leading zeroes are allowed and ignored.
31870
 
+
31871
 
+   The list will contain one string for each wildcard ("?" and "*") in
31872
 
+   the match pattern.  Each string holds the substring from the source
31873
 
+   value that the corresponding wildcard expands to, possibly the empty
31874
 
+   string.  The wildcards match as little as possible (non-greedy
31875
 
+   matching).
31876
 
+
31877
 
+   The first string in the list has index 1.  If the index is out of
31878
 
+   range, the empty string will be substituted.  Index 0 contains the
31879
 
+   matched part of the source value.
31880
 
+
31881
 
+   The interpreter MUST short-circuit tests, i.e., not perform more
31882
 
+   tests than necessary to find the result.  Evaluation order MUST be
31883
 
+   left to right.  If a test has two or more list arguments, the
31884
 
+   implementation is free to choose which to iterate over first.
31885
 
+
31886
 
+   An extension describing a new match type (e.g., [REGEX]) MAY specify
31887
 
+   that match variables are set as a side effect when the match type is
31888
 
+   used in a script that has enabled the "variables" extension.
31889
 
+
31890
 
+   Example:
31891
 
+
31892
 
+      require ["fileinto", "variables"];
31893
 
+
31894
 
+      if header :matches "List-ID" "*<*@*" {
31895
 
+          fileinto "INBOX.lists.${2}"; stop;
31896
 
+      }
31897
 
+
31898
 
+
31899
 
+
31900
 
+
31901
 
+
31902
 
+
31903
 
+
31904
 
+Homme                       Standards Track                     [Page 4]
31905
 
+
31906
 
+RFC 5229               Sieve: Variables Extension           January 2008
31907
 
+
31908
 
+
31909
 
+      # Imagine the header
31910
 
+      # Subject: [acme-users] [fwd] version 1.0 is out
31911
 
+      if header :matches "Subject" "[*] *" {
31912
 
+          # ${1} will hold "acme-users",
31913
 
+          # ${2} will hold "[fwd] version 1.0 is out"
31914
 
+          fileinfo "INBOX.lists.${1}"; stop;
31915
 
+      }
31916
 
+
31917
 
+      # Imagine the header
31918
 
+      # To: coyote@ACME.Example.COM
31919
 
+      if address :matches ["To", "Cc"] ["coyote@**.com",
31920
 
+              "wile@**.com"] {
31921
 
+          # ${0} is the matching address
31922
 
+          # ${1} is always the empty string
31923
 
+          # ${2} is part of the domain name ("ACME.Example")
31924
 
+          fileinto "INBOX.business.${2}"; stop;
31925
 
+      } else {
31926
 
+          # Control wouldn't reach this block if any match was
31927
 
+          # successful, so no match variables are set at this
31928
 
+          # point.
31929
 
+      }
31930
 
+
31931
 
+      if anyof (true, address :domain :matches "To" "*.com") {
31932
 
+          # The second test is never evaluated, so there are
31933
 
+          # still no match variables set.
31934
 
+          stop;
31935
 
+      }
31936
 
+
31937
 
+4.  Action set
31938
 
+
31939
 
+   Usage:    set [MODIFIER] <name: string> <value: string>
31940
 
+
31941
 
+   The "set" action stores the specified value in the variable
31942
 
+   identified by name.  The name MUST be a constant string and conform
31943
 
+   to the syntax of variable-name.  Match variables cannot be set.  A
31944
 
+   namespace cannot be used unless an extension explicitly allows its
31945
 
+   use in "set".  An invalid name MUST be detected as a syntax error.
31946
 
+
31947
 
+   Modifiers are applied on a value before it is stored in the variable.
31948
 
+   See the next section for details.
31949
 
+
31950
 
+   Variables are only visible to the currently running script.  Note:
31951
 
+   Future extensions may provide different scoping rules for variables.
31952
 
+
31953
 
+   Variable names are case insensitive.
31954
 
+
31955
 
+
31956
 
+
31957
 
+
31958
 
+
31959
 
+
31960
 
+Homme                       Standards Track                     [Page 5]
31961
 
+
31962
 
+RFC 5229               Sieve: Variables Extension           January 2008
31963
 
+
31964
 
+
31965
 
+   Example:
31966
 
+      set "honorific"  "Mr";
31967
 
+      set "first_name" "Wile";
31968
 
+      set "last_name"  "Coyote";
31969
 
+      set "vacation" text:
31970
 
+      Dear ${HONORIFIC} ${last_name},
31971
 
+      I'm out, please leave a message after the meep.
31972
 
+      .
31973
 
+      ;
31974
 
+
31975
 
+   "set" does not affect the implicit keep.  It is compatible with all
31976
 
+   actions defined in [SIEVE].
31977
 
+
31978
 
+4.1.  Modifiers
31979
 
+
31980
 
+   Usage:  ":lower" / ":upper" / ":lowerfirst" / ":upperfirst" /
31981
 
+           ":quotewildcard" / ":length"
31982
 
+
31983
 
+   Modifier names are case insensitive.  Unknown modifiers MUST yield a
31984
 
+   syntax error.  More than one modifier can be specified, in which case
31985
 
+   they are applied according to this precedence list, largest value
31986
 
+   first:
31987
 
+
31988
 
+                     +--------------------------------+
31989
 
+                     | Precedence     Modifier        |
31990
 
+                     +--------------------------------+
31991
 
+                     |     40         :lower          |
31992
 
+                     |                :upper          |
31993
 
+                     +--------------------------------+
31994
 
+                     |     30         :lowerfirst     |
31995
 
+                     |                :upperfirst     |
31996
 
+                     +--------------------------------+
31997
 
+                     |     20         :quotewildcard  |
31998
 
+                     +--------------------------------+
31999
 
+                     |     10         :length         |
32000
 
+                     +--------------------------------+
32001
 
+
32002
 
+   It is an error to use two or more modifiers of the same precedence in
32003
 
+   a single "set" action.
32004
 
+
32005
 
+   Examples:
32006
 
+      # The value assigned to the variable is printed after the arrow
32007
 
+      set "a" "juMBlEd lETteRS";             => "juMBlEd lETteRS"
32008
 
+      set :length "b" "${a}";                => "15"
32009
 
+      set :lower "b" "${a}";                 => "jumbled letters"
32010
 
+      set :upperfirst "b" "${a}";            => "JuMBlEd lETteRS"
32011
 
+      set :upperfirst :lower "b" "${a}";     => "Jumbled letters"
32012
 
+      set :quotewildcard "b" "Rock*";        => "Rock\*"
32013
 
+
32014
 
+
32015
 
+
32016
 
+Homme                       Standards Track                     [Page 6]
32017
 
+
32018
 
+RFC 5229               Sieve: Variables Extension           January 2008
32019
 
+
32020
 
+
32021
 
+4.1.1.  Modifier ":length"
32022
 
+
32023
 
+   The value is the decimal number of characters in the expansion,
32024
 
+   converted to a string.
32025
 
+
32026
 
+4.1.2.  Modifier ":quotewildcard"
32027
 
+
32028
 
+   This modifier adds the necessary quoting to ensure that the expanded
32029
 
+   text will only match a literal occurrence if used as a parameter to
32030
 
+   :matches.  Every character with special meaning ("*", "?",  and "\")
32031
 
+   is prefixed with "\" in the expansion.
32032
 
+
32033
 
+4.1.3.  Case Modifiers
32034
 
+
32035
 
+   These modifiers change the letters of the text from upper to lower
32036
 
+   case or vice versa.  Characters other than "A"-"Z" and "a"-"z" from
32037
 
+   US-ASCII are left unchanged.
32038
 
+
32039
 
+4.1.3.1.  Modifier ":upper"
32040
 
+
32041
 
+   All lower case letters are converted to their upper case
32042
 
+   counterparts.
32043
 
+
32044
 
+4.1.3.2.  Modifier ":lower"
32045
 
+
32046
 
+   All upper case letters are converted to their lower case
32047
 
+   counterparts.
32048
 
+
32049
 
+4.1.3.3.  Modifier ":upperfirst"
32050
 
+
32051
 
+   The first character of the string is converted to upper case if it is
32052
 
+   a letter and set in lower case.  The rest of the string is left
32053
 
+   unchanged.
32054
 
+
32055
 
+4.1.3.4.  Modifier ":lowerfirst"
32056
 
+
32057
 
+   The first character of the string is converted to lower case if it is
32058
 
+   a letter and set in upper case.  The rest of the string is left
32059
 
+   unchanged.
32060
 
+
32061
 
+5.  Test string
32062
 
+
32063
 
+   Usage:  string [MATCH-TYPE] [COMPARATOR]
32064
 
+           <source: string-list> <key-list: string-list>
32065
 
+
32066
 
+   The "string" test evaluates to true if any of the source strings
32067
 
+   matches any key.  The type of match defaults to ":is".
32068
 
+
32069
 
+
32070
 
+
32071
 
+
32072
 
+Homme                       Standards Track                     [Page 7]
32073
 
+
32074
 
+RFC 5229               Sieve: Variables Extension           January 2008
32075
 
+
32076
 
+
32077
 
+   In the "string" test, both source and key-list are taken from the
32078
 
+   script, not the message, and whitespace stripping MUST NOT be done
32079
 
+   unless the script explicitly requests this through some future
32080
 
+   mechanism.
32081
 
+
32082
 
+   Example:
32083
 
+      set "state" "${state} pending";
32084
 
+      if string :matches " ${state} " "* pending *" {
32085
 
+          # the above test always succeeds
32086
 
+      }
32087
 
+
32088
 
+   The "relational" extension [RELATIONAL] adds a match type called
32089
 
+   ":count".  The count of a single string is 0 if it is the empty
32090
 
+   string, or 1 otherwise.  The count of a string list is the sum of the
32091
 
+   counts of the member strings.
32092
 
+
32093
 
+6.  Implementation Limits
32094
 
+
32095
 
+   An implementation of this document MUST support at least 128 distinct
32096
 
+   variables.  The supported length of variable names MUST be at least
32097
 
+   32 characters.  Each variable MUST be able to hold at least 4000
32098
 
+   characters.  Attempts to set the variable to a value larger than what
32099
 
+   the implementation supports SHOULD be reported as an error at
32100
 
+   compile-time if possible.  If the attempt is discovered during run-
32101
 
+   time, the value SHOULD be truncated, and it MUST NOT be treated as an
32102
 
+   error.
32103
 
+
32104
 
+   Match variables ${1} through ${9} MUST be supported.  References to
32105
 
+   higher indices than those the implementation supports MUST be treated
32106
 
+   as a syntax error, which SHOULD be discovered at compile-time.
32107
 
+
32108
 
+7.  Security Considerations
32109
 
+
32110
 
+   When match variables are used, and the author of the script isn't
32111
 
+   careful, strings can contain arbitrary values controlled by the
32112
 
+   sender of the mail.
32113
 
+
32114
 
+   Since values stored by "set" that exceed implementation limits are
32115
 
+   silently truncated, it's not appropriate to store large structures
32116
 
+   with security implications in variables.
32117
 
+
32118
 
+   The introduction of variables makes advanced decision making easier
32119
 
+   to write, but since no looping construct is provided, all Sieve
32120
 
+   scripts will terminate in an orderly manner.
32121
 
+
32122
 
+   Sieve filtering should not be relied on as a security measure against
32123
 
+   hostile mail messages.  Sieve is designed to do simple, mostly static
32124
 
+   tests, and is not suitable for use as a spam or virus checker, where
32125
 
+
32126
 
+
32127
 
+
32128
 
+Homme                       Standards Track                     [Page 8]
32129
 
+
32130
 
+RFC 5229               Sieve: Variables Extension           January 2008
32131
 
+
32132
 
+
32133
 
+   the perpetrator has a motivation to vary the format of the mail in
32134
 
+   order to avoid filtering rules.  See also [SPAMTEST].
32135
 
+
32136
 
+8.  IANA Considerations
32137
 
+
32138
 
+   The following template specifies the IANA registration of the
32139
 
+   variables Sieve extension specified in this document:
32140
 
+
32141
 
+   To: iana@iana.org
32142
 
+   Subject: Registration of new Sieve extension
32143
 
+
32144
 
+   Capability name: variables
32145
 
+   Description:     Adds support for variables to the Sieve filtering
32146
 
+                    language.
32147
 
+   RFC number:      RFC 5229
32148
 
+   Contact address: The Sieve discussion list <ietf-mta-filters@imc.org>
32149
 
+
32150
 
+9.  Acknowledgments
32151
 
+
32152
 
+   Thanks to Cyrus Daboo, Jutta Degener, Ned Freed, Lawrence Greenfield,
32153
 
+   Jeffrey Hutzelman, Mark E. Mallett, Alexey Melnikov, Peder Stray, and
32154
 
+   Nigel Swinson for valuable feedback.
32155
 
+
32156
 
+10.  References
32157
 
+
32158
 
+10.1.  Normative References
32159
 
+
32160
 
+   [ABNF]       Crocker, D., Ed., and Overell, P., "Augmented BNF for
32161
 
+                Syntax Specifications: ABNF", RFC 4234, October 2005.
32162
 
+
32163
 
+   [KEYWORDS]   Bradner, S., "Key words for use in RFCs to Indicate
32164
 
+                Requirement Levels", BCP 14, RFC 2119, March 1997.
32165
 
+
32166
 
+   [RELATIONAL] Segmuller, W. and B. Leiba, "Sieve Email Filtering:
32167
 
+                Relational Extension", RFC 5231, January 2008.
32168
 
+
32169
 
+   [SIEVE]      Guenther, P., Ed., and T. Showalter, Ed., "Sieve: An
32170
 
+                Email Filtering Language", RFC 5228, January 2008.
32171
 
+
32172
 
+   [UTF-8]      Yergeau, F., "UTF-8, a transformation format of Unicode
32173
 
+                and ISO 10646", RFC 3629, November 2003.
32174
 
+
32175
 
+10.2.  Informative References
32176
 
+
32177
 
+   [ISO10646]   ISO/IEC, "Information Technology - Universal Multiple-
32178
 
+                Octet Coded Character Set (UCS) - Part 1: Architecture
32179
 
+                and Basic Multilingual Plane", May 1993, with
32180
 
+                amendments.
32181
 
+
32182
 
+
32183
 
+
32184
 
+Homme                       Standards Track                     [Page 9]
32185
 
+
32186
 
+RFC 5229               Sieve: Variables Extension           January 2008
32187
 
+
32188
 
+
32189
 
+   [REGEX]      Murchison, K., "Sieve Email Filtering -- Regular
32190
 
+                Expression Extension", Work in Progress, February 2006.
32191
 
+
32192
 
+   [SPAMTEST]   Daboo, C., "Sieve Email Filtering: Spamtest and
32193
 
+                Virustest Extensions", RFC 5235, January 2008.
32194
 
+
32195
 
+Author's Address
32196
 
+
32197
 
+   Kjetil T. Homme
32198
 
+   University of Oslo
32199
 
+   PO Box 1080
32200
 
+   0316 Oslo, Norway
32201
 
+
32202
 
+   Phone: +47 9366 0091
32203
 
+   EMail: kjetilho@ifi.uio.no
32204
 
+
32205
 
+
32206
 
+
32207
 
+
32208
 
+
32209
 
+
32210
 
+
32211
 
+
32212
 
+
32213
 
+
32214
 
+
32215
 
+
32216
 
+
32217
 
+
32218
 
+
32219
 
+
32220
 
+
32221
 
+
32222
 
+
32223
 
+
32224
 
+
32225
 
+
32226
 
+
32227
 
+
32228
 
+
32229
 
+
32230
 
+
32231
 
+
32232
 
+
32233
 
+
32234
 
+
32235
 
+
32236
 
+
32237
 
+
32238
 
+
32239
 
+
32240
 
+Homme                       Standards Track                    [Page 10]
32241
 
+
32242
 
+RFC 5229               Sieve: Variables Extension           January 2008
32243
 
+
32244
 
+
32245
 
+Full Copyright Statement
32246
 
+
32247
 
+   Copyright (C) The IETF Trust (2008).
32248
 
+
32249
 
+   This document is subject to the rights, licenses and restrictions
32250
 
+   contained in BCP 78, and except as set forth therein, the authors
32251
 
+   retain all their rights.
32252
 
+
32253
 
+   This document and the information contained herein are provided on an
32254
 
+   "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS
32255
 
+   OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY, THE IETF TRUST AND
32256
 
+   THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS
32257
 
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF
32258
 
+   THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
32259
 
+   WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
32260
 
+
32261
 
+Intellectual Property
32262
 
+
32263
 
+   The IETF takes no position regarding the validity or scope of any
32264
 
+   Intellectual Property Rights or other rights that might be claimed to
32265
 
+   pertain to the implementation or use of the technology described in
32266
 
+   this document or the extent to which any license under such rights
32267
 
+   might or might not be available; nor does it represent that it has
32268
 
+   made any independent effort to identify any such rights.  Information
32269
 
+   on the procedures with respect to rights in RFC documents can be
32270
 
+   found in BCP 78 and BCP 79.
32271
 
+
32272
 
+   Copies of IPR disclosures made to the IETF Secretariat and any
32273
 
+   assurances of licenses to be made available, or the result of an
32274
 
+   attempt made to obtain a general license or permission for the use of
32275
 
+   such proprietary rights by implementers or users of this
32276
 
+   specification can be obtained from the IETF on-line IPR repository at
32277
 
+   http://www.ietf.org/ipr.
32278
 
+
32279
 
+   The IETF invites any interested party to bring to its attention any
32280
 
+   copyrights, patents or patent applications, or other proprietary
32281
 
+   rights that may cover technology that may be required to implement
32282
 
+   this standard.  Please address the information to the IETF at
32283
 
+   ietf-ipr@ietf.org.
32284
 
+
32285
 
+
32286
 
+
32287
 
+
32288
 
+
32289
 
+
32290
 
+
32291
 
+
32292
 
+
32293
 
+
32294
 
+
32295
 
+
32296
 
+Homme                       Standards Track                    [Page 11]
32297
 
+
32298
 
diff -urN dovecot-1.2.4/dovecot-libsieve/dsieve-config.h.in dovecot-1.2.4.debian/dovecot-libsieve/dsieve-config.h.in
32299
 
--- dovecot-1.2.4/dovecot-libsieve/dsieve-config.h.in   1970-01-01 01:00:00.000000000 +0100
32300
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/dsieve-config.h.in    2009-07-20 23:30:49.000000000 +0200
32301
 
@@ -0,0 +1,9 @@
32302
 
+
32303
 
+/* Define to the full name of this Sieve implementation. */
32304
 
+#undef SIEVE_NAME
32305
 
+
32306
 
+/* Define to the version of this Sieve implementation. */
32307
 
+#undef SIEVE_VERSION
32308
 
+
32309
 
+/* Define to build Sieve unfinished features/extensions. */
32310
 
+#undef HAVE_SIEVE_UNFINISHED
32311
 
diff -urN dovecot-1.2.4/dovecot-libsieve/dummy-config.h.in dovecot-1.2.4.debian/dovecot-libsieve/dummy-config.h.in
32312
 
--- dovecot-1.2.4/dovecot-libsieve/dummy-config.h.in    1970-01-01 01:00:00.000000000 +0100
32313
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/dummy-config.h.in     2009-08-21 00:55:41.000000000 +0200
32314
 
@@ -0,0 +1,65 @@
32315
 
+/* dummy-config.h.in.  Generated from configure.in by autoheader.  */
32316
 
+
32317
 
+/* Define to 1 if you have the <dlfcn.h> header file. */
32318
 
+#undef HAVE_DLFCN_H
32319
 
+
32320
 
+/* Define to 1 if you have the <inttypes.h> header file. */
32321
 
+#undef HAVE_INTTYPES_H
32322
 
+
32323
 
+/* Define to 1 if you have the <memory.h> header file. */
32324
 
+#undef HAVE_MEMORY_H
32325
 
+
32326
 
+/* Define to build Sieve unfinished features/extensions. */
32327
 
+#undef HAVE_SIEVE_UNFINISHED
32328
 
+
32329
 
+/* Define to 1 if you have the <stdint.h> header file. */
32330
 
+#undef HAVE_STDINT_H
32331
 
+
32332
 
+/* Define to 1 if you have the <stdlib.h> header file. */
32333
 
+#undef HAVE_STDLIB_H
32334
 
+
32335
 
+/* Define to 1 if you have the <strings.h> header file. */
32336
 
+#undef HAVE_STRINGS_H
32337
 
+
32338
 
+/* Define to 1 if you have the <string.h> header file. */
32339
 
+#undef HAVE_STRING_H
32340
 
+
32341
 
+/* Define to 1 if you have the <sys/stat.h> header file. */
32342
 
+#undef HAVE_SYS_STAT_H
32343
 
+
32344
 
+/* Define to 1 if you have the <sys/types.h> header file. */
32345
 
+#undef HAVE_SYS_TYPES_H
32346
 
+
32347
 
+/* Define to 1 if you have the <unistd.h> header file. */
32348
 
+#undef HAVE_UNISTD_H
32349
 
+
32350
 
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
32351
 
+   */
32352
 
+#undef LT_OBJDIR
32353
 
+
32354
 
+/* Define to the address where bug reports for this package should be sent. */
32355
 
+#undef PACKAGE_BUGREPORT
32356
 
+
32357
 
+/* Define to the full name of this package. */
32358
 
+#undef PACKAGE_NAME
32359
 
+
32360
 
+/* Define to the full name and version of this package. */
32361
 
+#undef PACKAGE_STRING
32362
 
+
32363
 
+/* Define to the one symbol short name of this package. */
32364
 
+#undef PACKAGE_TARNAME
32365
 
+
32366
 
+/* Define to the home page for this package. */
32367
 
+#undef PACKAGE_URL
32368
 
+
32369
 
+/* Define to the version of this package. */
32370
 
+#undef PACKAGE_VERSION
32371
 
+
32372
 
+/* Define to the full name of this Sieve implementation. */
32373
 
+#undef SIEVE_NAME
32374
 
+
32375
 
+/* Define to the version of this Sieve implementation. */
32376
 
+#undef SIEVE_VERSION
32377
 
+
32378
 
+/* Define to 1 if you have the ANSI C header files. */
32379
 
+#undef STDC_HEADERS
32380
 
diff -urN dovecot-1.2.4/dovecot-libsieve/examples/elvey.sieve dovecot-1.2.4.debian/dovecot-libsieve/examples/elvey.sieve
32381
 
--- dovecot-1.2.4/dovecot-libsieve/examples/elvey.sieve 1970-01-01 01:00:00.000000000 +0100
32382
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/examples/elvey.sieve  2008-10-04 10:41:25.000000000 +0200
32383
 
@@ -0,0 +1,153 @@
32384
 
+# Example Sieve Script
32385
 
+#   Author: Matthew Elvey (Slightly modified to remove syntax and context errors)
32386
 
+#   URL: http://www.elvey.com/it/sieve/SieveScript.txt
32387
 
+
32388
 
+# Initial version completed and put in place 4/1/02 by Matthew Elvey  (firstname@lastname.com ; I've checked and it's not a valid address.); Copyright (C).and.current as of 5/19/2002 
32389
 
+#Change log:
32390
 
+#+ spam[:high]; major reordering; +DFC,BugTraq, PB up +Economist, FolderPath corrections 
32391
 
+#+ redid .0 matches. +Korean + whitelist +@f(useful once I start bouncing mail!)
32392
 
+#+open mag, simplifications, to fm=spamNOTwhite, Bulk changes, IETF rules, +lst
32393
 
+#Reword spam bounce.+scalable@ re-correction+++Work+activate Spam Optimization, etc...
32394
 
+#oops high = 2x threshold, so 2x1 is 2!  Too low. To @fm:bounce.  Added tons of comments.
32395
 
+require ["fileinto", "reject", "vacation", "envelope", "regex"];
32396
 
+
32397
 
+if header :contains "subject" ["un eject", "lastname.com/spamoff.htm agreed to"] {  #I give out "uneject" to people to let them bypass the spam or size filters.
32398
 
+  keep;
32399
 
+} elsif header :contains "subject" ["ADV:", "bounceme", "2002 Gov Grants",   #bounceme is useful for testing.
32400
 
+             "ADV:ADLT", "ADV-ADULT", "ADULT ADVERTISEMENT"] {  #Subject text required by various US State laws
32401
 
+  reject text: 
32402
 
+  Hello.  The server content filter/spam detector I use has bounced your message. It appears to be spam. 
32403
 
+
32404
 
+  I do not accept spam/UCE (Unsolicited Commercial Email). 
32405
 
+
32406
 
+Please ask me how to bypass this filter if your email is not UCE.  In that case, I am sorry about this 
32407
 
+highly unusual error.  The filter is >99% accurate.
32408
 
+
32409
 
+  (This is an automated message; I will not be aware that your message did not get through if I do not hear from you again.)
32410
 
+
32411
 
+  -Firstname
32412
 
+
32413
 
+  (P.S. You may also override the filter if you accept the terms at http://www.lastname.com/spamoff.htm, 
32414
 
+         by including "lastname.com/spamoff.htm agreed to." in the subject.)
32415
 
+.
32416
 
+   ;
32417
 
+}
32418
 
+# LINE 30.
32419
 
+  elsif size :over 10M {    # (note that the four leading dots get "stuffed" to three)
32420
 
+
32421
 
+  reject text:
32422
 
+   Message NOT delivered!
32423
 
+   This system normally accepts email that is less than 10MB in size, because that is how I configured it.
32424
 
+   You may want to put your file on a server and send me the URL.
32425
 
+   Or, you may request override permission and/or unreject instructions via another (smaller) email.
32426
 
+   Sorry for the inconvenience.
32427
 
+
32428
 
+   Thanks,
32429
 
+
32430
 
+.... Firstname
32431
 
+   (This is an automated message; I will not be aware that your message did not get through if I do not hear from you again.)
32432
 
+
32433
 
+   Unsolicited advertising sent to this E-Mail address is expressly prohibited 
32434
 
+   under USC Title 47, Section 227.  Violators are subject to charge of up to 
32435
 
+   $1,500 per incident or treble actual costs, whichever is greater.
32436
 
+.
32437
 
+  ; 
32438
 
+#LINE 47.
32439
 
+} elsif header :contains "From" "Firstname@lastname.com" {     #if I send myself email, leave it in the Inbox.
32440
 
+  keep;                        #next, is the processing for the various mailing lists I'm on.  
32441
 
+} elsif header :contains ["Sender", "X-Sender", "Mailing-List", "Delivered-To", "List-Post", "Subject", "To", "Cc", "From", "Reply-to", "Received"] "burningman" {
32442
 
+  fileinto "INBOX.DaBurn";
32443
 
+} elsif header :contains ["Subject", "From", "Received"] ["E*TRADE", "Datek", "TD Waterhouse", "NetBank"] {
32444
 
+  fileinto "INBOX.finances.status";
32445
 
+} elsif header :contains "subject" "\[pacbell" {
32446
 
+  fileinto "INBOX.pacbell.dslreports";
32447
 
+} elsif header :contains "From" ["owner-te-wg ", "te-wg ", "iana.org"] {
32448
 
+  fileinto "INBOX.lst.IETF";
32449
 
+} elsif header :contains ["Mailing-List", "Subject", "From", "Received"] ["Red Hat", "Double Funk Crunch", "@economist.com", "Open Magazine", "@nytimes.com", "mottimorell", "Harrow Technology Report"] {
32450
 
+  fileinto "INBOX.lst.interesting";
32451
 
+} elsif header :contains ["Mailing-List", "Subject", "From", "Received", "X-LinkName"] ["DJDragonfly", "Ebates", "Webmonkey", "DHJ8091@aol.com", "Expedia Fare Tracker", "SoulShine", "Martel and Nabiel", "\[ecc\]"] {
32452
 
+  fileinto "INBOX.lst.lame";
32453
 
+} elsif header :contains ["Subject", "From", "To"] ["guru.com", "monster.com", "hotjobs", "dice.com", "linkify.com"] {  #job boards and current clients.
32454
 
+  fileinto "INBOX.lst.jobs";
32455
 
+} elsif header :contains "subject" "\[yaba" {
32456
 
+  fileinto "INBOX.rec.yaba";
32457
 
+} elsif header :contains ["to", "cc"] "scalable@" {
32458
 
+  fileinto "INBOX.lst.scalable";
32459
 
+} elsif header :contains ["Sender", "To", "Return-Path", "Received"] "NTBUGTRAQ@listserv.ntbugtraq.com" {
32460
 
+  fileinto "INBOX.lst.bugtraq";
32461
 
+} elsif header :contains "subject" "Wired" {
32462
 
+  fileinto "INBOX.lst.wired";
32463
 
+#LINE 72.
32464
 
+} elsif anyof (header :contains "From" ["postmaster", "daemon", "abuse"], header :contains "Subject" ["warning:", "returned mail", "failure notice", "undelivered mail"] ) {
32465
 
+keep;          #this one is important - don't want to miss any bounce messages!
32466
 
+#LINE 77.
32467
 
+} elsif anyof (header :contains "From" ["and here I put a whitelist of pretty much all the email addresses in my address book - it's several pages..."]) {
32468
 
+  fileinto "INBOX.white"; 
32469
 
+# better than keep;
32470
 
+# LINE 106.
32471
 
+
32472
 
+
32473
 
+} elsif anyof (address :all :is ["To", "CC", "BCC"] "Firstname.lastname@fastmail.fm",    #a couple people send to this, but I have have all their addrs in whitelist so OK.
32474
 
+           header :matches "X-Spam-score"  ["9.?" , "10.?", "9", "10", "11.?", "12.?" ,"13.?", "14.?", "11", "12","13", "14", "15.?", "16.?", "17.?" ,"18.?", "19.?", "15", "16", "17" ,"18", "19", "2?.?", "2?", "3?.?" , "3?", "40"]) {               #"5.?", "6.?", "5", "6" "7.?" , "8.?" , "7", "8"
32475
 
+  reject text: 
32476
 
+  Hello.  The server content filter/spam detector I use has bounced your message. It appears to be spam. 
32477
 
+
32478
 
+  I do not accept spam/UCE (Unsolicited Commercial Email). 
32479
 
+
32480
 
+Please ask me how to bypass this filter if your email is not UCE.  In that case, I am sorry about this 
32481
 
+highly unusual error.  The filter is >99% accurate.
32482
 
+
32483
 
+  (This is an automated message; I will not be aware that your message did not get through if I do not hear from you again.)
32484
 
+
32485
 
+  -Firstname
32486
 
+
32487
 
+  (P.S. You may also override the filter if you accept the terms at http://www.lastname.com/spamoff.htm, 
32488
 
+         by including "lastname.com/spamoff.htm agreed to." in the subject.)
32489
 
+.
32490
 
+   ;
32491
 
+#LINE 127.
32492
 
32493
 
+} elsif 
32494
 
+header :matches "X-Spam" ["spam", "high"] { if                                 #optimization idea line 1/2
32495
 
+           header :matches "X-Spam-score" ["5.?", "6.?", "5", "6"] { 
32496
 
+  fileinto "INBOX.Spam.5-7"; 
32497
 
+} elsif header :matches "X-Spam-score" ["7.?" , "8.?" , "7", "8"] { 
32498
 
+  fileinto "INBOX.Spam.7-9"; 
32499
 
+#} elsif header :matches "X-Spam-score" ["9.?" , "10.?" , "9", "10"] {         #These lines obsoleted by reject text rule above, but others will find 'em useful!
32500
 
+#  fileinto "INBOX.Spam.9-11"; 
32501
 
+#} elsif header :matches "X-Spam-score" ["11.?" , "12.?" ,"13.?" , "14.?", "11" , "12" ,"13" , "14"] { 
32502
 
+#  fileinto "INBOX.Spam.11-15"; 
32503
 
+#} elsif header :matches "X-Spam-score" ["15.?" , "16.?" ,"17.?" ,"18.?" , "19.?", "15" , "16" ,"17" ,"18" , "19"] { 
32504
 
+#  fileinto "INBOX.Spam.15-20"; 
32505
 
+#} elsif header :matches "X-Spam-score" ["2?.?", "2?" ] {
32506
 
+#  fileinto "Inbox.Spam.20-30";
32507
 
+#} elsif header :matches "X-Spam-score" ["3?.?" , "3?", "40"] {
32508
 
+#fileinto "Inbox.Spam.30-40";
32509
 
+ }                                                                                     #optimization idea  line 2/2 
32510
 
+
32511
 
+#LINE 149.
32512
 
+       
32513
 
+} elsif header:contains ["Content-Type","Subject"] ["ks_c_5601-1987","euc_kr","euc-kr"]{
32514
 
+  fileinto "Inbox.Spam.kr";                                                            #block Korean; it's prolly spam and I certainly can't read it.
32515
 
+} elsif header :contains "Received" "yale.edu" {
32516
 
+  fileinto "INBOX.Yale";                                                               #if it made it past all the filters above, it's probably of interest.
32517
 
+      } elsif anyof (header :contains "Subject" ["HR 1910", "viagra", "MLM", "               ","       " ], # common in spam.  (prolly redundant to SpamAssassin.)
32518
 
+      not exists ["From", "Date"],                                             #RFC822 violations common in spam.
32519
 
+      header :contains ["Sender", "X-Sender", "Mailing-List", "X-Apparently-From", "X-Version", "X-Sender-IP", "Received", "Return-Path", "Delivered-To", "List-Post", "Date", "Subject", "To", "Cc", "From", "Reply-to", "X-AntiAbuse", "Content-Type", "Received", "X-LinkName"] ["btamail.net.cn", "@arabia.com" ] ) {               #spam havens.
32520
 
+  fileinto "INBOX.GreyMail";
32521
 
+} elsif header :contains ["Precedence", "Priority", "X-Priority", "Mailing-List", "Subject", "From", "Received", "X-LinkName"] ["Bulk", "Newsletter"] {
32522
 
+  fileinto "INBOX.Bulk Precedence";
32523
 
+} elsif header :contains ["to", "cc", "Received"] ["IT@lastname.com", "mail.freeservers.com"] {
32524
 
+  fileinto "INBOX.lastname.IT";
32525
 
+} elsif header :contains ["To", "CC"] "Firstname@lastname.com" {
32526
 
+  fileinto "INBOX.lastname.non-BCC";
32527
 
+}
32528
 
+#LINE 167.
32529
 
+#END OF SCRIPT.  Implied 'keep' is part of the Sieve spec.
32530
 
+
32531
 
+
32532
 
+
32533
 
+
32534
 
+
32535
 
32536
 
+
32537
 
Binary files dovecot-1.2.4/dovecot-libsieve/examples/elvey.svbin and dovecot-1.2.4.debian/dovecot-libsieve/examples/elvey.svbin differ
32538
 
diff -urN dovecot-1.2.4/dovecot-libsieve/examples/jerry.sieve dovecot-1.2.4.debian/dovecot-libsieve/examples/jerry.sieve
32539
 
--- dovecot-1.2.4/dovecot-libsieve/examples/jerry.sieve 1970-01-01 01:00:00.000000000 +0100
32540
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/examples/jerry.sieve  2008-10-04 10:41:25.000000000 +0200
32541
 
@@ -0,0 +1,224 @@
32542
 
+# Example Sieve Script
32543
 
+#   Author: Jerry
32544
 
+#   URL: http://www.emaildiscussions.com/showthread.php?postid=145322#post145322
32545
 
+
32546
 
+require ["fileinto", "reject", "vacation", "regex", "relational",
32547
 
+"comparator-i;ascii-numeric"];
32548
 
+
32549
 
+
32550
 
+#### BLACKLIST - BOUNCE ANYTHING THAT MATCHES
32551
 
+#    From individual addresses
32552
 
+         if header :contains "from"
32553
 
+         [
32554
 
+           "username@example.com",
32555
 
+           "username@example.net"
32556
 
+         ]
32557
 
+         { reject "Message bounced by server content filter"; stop; }
32558
 
+
32559
 
+#    From domains
32560
 
+         elsif header :contains "from"
32561
 
+         [
32562
 
+           "example.com",
32563
 
+           "example.net"
32564
 
+         ]
32565
 
+         { reject "Message bounced by server content filter"; stop; }
32566
 
+
32567
 
+
32568
 
+
32569
 
+#### BLACKLIST - DELETE ANYTHING THAT MATCHES
32570
 
+#    From individual addresses
32571
 
+         elsif header :contains "from"
32572
 
+         [
32573
 
+           "username@example.com",
32574
 
+           "username@example.net"
32575
 
+         ]
32576
 
+         { discard; stop; }
32577
 
+
32578
 
+#    From domains
32579
 
+         elsif header :contains "from"
32580
 
+         [
32581
 
+           "example.com",
32582
 
+           "example.net"
32583
 
+         ]
32584
 
+         { discard; stop; }
32585
 
+
32586
 
+#    I just added the following section after the joe-job
32587
 
+#    that we all suffered at the hands of "inbox.com".
32588
 
+#    The "myusername" is MY username at FastMail.
32589
 
+#    DISCARDing this mail instead of directing it to a
32590
 
+#    SPAM folder kept me from going over quota repeatedly.
32591
 
+
32592
 
+#    To individual addresses
32593
 
+         elsif header :contains "to"
32594
 
+         [
32595
 
+           "myusername@inbox.com",
32596
 
+           "myusername@example.net"
32597
 
+         ]
32598
 
+         { discard; stop; }
32599
 
+
32600
 
+         elsif  allof
32601
 
+             (
32602
 
+                 not anyof
32603
 
+                 (
32604
 
+#### WHITELIST - KEEP ANYTHING THAT MATCHES
32605
 
+#    From individual addresses
32606
 
+                     header :contains "from"
32607
 
+                     [
32608
 
+                       "username@example.com",
32609
 
+                       "username@example.net"
32610
 
+                     ],
32611
 
+
32612
 
+#    From trusted domains
32613
 
+                     header :contains "from"
32614
 
+                     [
32615
 
+                       "example.com",
32616
 
+                       "example.net"
32617
 
+                     ],
32618
 
+
32619
 
+#    Specific "to" address (mailing lists etc)
32620
 
+                     header :contains ["to", "cc"]
32621
 
+                     [
32622
 
+                       "username@example.com",
32623
 
+                       "username@example.net"
32624
 
+                     ],
32625
 
+
32626
 
+#    Specific "subject" keywords
32627
 
+                     header :contains "subject"
32628
 
+                     [
32629
 
+                       "code_word_for_friend_#1",
32630
 
+                       "code_word_for_friend_#2"
32631
 
+                     ]
32632
 
+
32633
 
+                 ),
32634
 
+                 anyof
32635
 
+                 (
32636
 
+
32637
 
+#    Filter by keywords in subject or from headers
32638
 
+                     header :contains ["subject", "from"]
32639
 
+                     [
32640
 
+                       "adilt", "adult", "advertise", "affordable",
32641
 
+                       "as seen on tv", "antenna", "alarm",
32642
 
+                       "background check", "bankrupt", "bargain",
32643
 
+                       "best price", "bikini", "boost reliability",
32644
 
+                       "brand new", "breast", "business directory",
32645
 
+                       "business opportunity", "based business", "best
32646
 
+                       deal", "bachelor's", "benefits", "cable",
32647
 
+                       "career", "casino", "celeb", "cheapest", "child
32648
 
+                       support", "cd-r", "catalog", "classified ad",
32649
 
+                       "click here", "coed", "classmate", "commerce",
32650
 
+                       "congratulations", "credit", "cruise", "cds",
32651
 
+                       "complimentary", "columbia house", "crushlink",
32652
 
+                       "debt", "detective", "diploma", "directv",
32653
 
+                       "directtv", "dish", "dream vacation", "deluxe",
32654
 
+                       "drug", "dvds", "dvd movie", "doubleclick",
32655
 
+                       "digital tv", "erotic", "exciting new",
32656
 
+                       "equalamail", "fantastic business", "fat
32657
 
+                       burning", "financial independence", "finalist",
32658
 
+                       "for life", "financing", "fitness", "fixed
32659
 
+                       rate", "four reports", "free!", "free
32660
 
+                       business", "from home", "funds", "fbi know",
32661
 
+                       "fortune", "gambl", "getaway", "girls", "great
32662
 
+                       price", "guaranteed", "get big", "get large",
32663
 
+                       "giveaway", "hard core", "hardcore", "home
32664
 
+                       document imaging", "home employment directory",
32665
 
+                       "homeowner", "home owner", "homeworker", "home
32666
 
+                       security", "home video", "immediate release",
32667
 
+                       "information you requested", "income",
32668
 
+                       "inkjet", "insurance", "interest rate",
32669
 
+                       "invest", "internet connection", "join price",
32670
 
+                       "judicial judgment", "just released", "know
32671
 
+                       your rights", "legal", "license", "loan", "long
32672
 
+                       distance", "look great", "low interest",
32673
 
+                       "low-interest", "low rate", "lust", "lbs",
32674
 
+                       "make money", "market", "master card",
32675
 
+                       "mastercard", "meg web", "merchant account",
32676
 
+                       "millionaire", "mini-vacation", "mortgage",
32677
 
+                       "master's", "magazine", "nasty", "new car",
32678
 
+                       "nigeria", "nude", "nympho", "naked",
32679
 
+                       "obligation", "online business", "opportunity",
32680
 
+                       "pager", "paying too much", "pda", "penis",
32681
 
+                       "pennies", "pills", "porn", "pounds",
32682
 
+                       "pre-approved", "prescri", "prscri", "prize",
32683
 
+                       "prostate", "printer ink", "quote", "refinanc",
32684
 
+                       "remove fat", "removing fat", "reward",
32685
 
+                       "sales", "satellite", "saw your site",
32686
 
+                       "scrambler", "sex", "smoking", "snoring", "some
32687
 
+                       people succeed", "special invitation", "special
32688
 
+                       offer", "stock", "saving", "singles", "teen",
32689
 
+                       "ticket", "tired of", "truth about anyone",
32690
 
+                       "the best", "ucking", "unbelievable",
32691
 
+                       "uncensored", "uncollected", "unlimited", "USA
32692
 
+                       domains", "urgent", "valium", "viagra",
32693
 
+                       "venture capital", "virgin", "visa", "vitamin",
32694
 
+                       "waist", "wealth", "webcam", "weight", "win a",
32695
 
+                       "winner", "win one", "work smarter", "work at
32696
 
+                       home", "xxx", "younger", "your web site", "your
32697
 
+                       money", "your date is wait",
32698
 
+                       "!!!", "$", "%", "10K"
32699
 
+                     ],
32700
 
+
32701
 
+#    Filter when the subject is all uppercase (no lowercase)
32702
 
+                     header :regex :comparator
32703
 
+                     "i;octet" "subject" "^[^[:lower:]]+$",
32704
 
+
32705
 
+#    Filter using regular expressions on the subject
32706
 
+                     header :regex    "subject"
32707
 
+                     [
32708
 
+                       "start.+business", "live.+auction",
32709
 
+                       "discover.+card", "pay.+college", "apr$",
32710
 
+                       "apr[^[:alnum:]]", "adv[^[:alnum:]]",
32711
 
+                       "free.+(coupon|info|install|money)",
32712
 
+                       "free.+(phone|sample|test|trial)",
32713
 
+                       "(buy|sell).+(house|home)"
32714
 
+                     ],
32715
 
+
32716
 
+#    Filter with tracker codes in the subject
32717
 
+                     header :regex    "subject"
32718
 
+                     "[[:space:].\-_]{4}#?\[?[[:alnum:]-]+\]?$",
32719
 
+
32720
 
+#    Filter spam with no to/from address set
32721
 
+                     not exists    ["To", "From"],
32722
 
+
32723
 
+#    Filter spam not addressed to me
32724
 
+#        Put here all of your own addresses (and alias) that you expect
32725
 
+#        mail addressed to.  I found a lot of my spam didn't have my
32726
 
+#        name in the TO or CC fields at all -- it must have been in the
32727
 
+#        BCC (which doesn't show in the headers).  I can still get BCC
32728
 
+#        mail from legitimate sources because everyone in my address
32729
 
+#        book is on the WHITELIST above.
32730
 
+
32731
 
+                     not header :contains ["to", "cc"]
32732
 
+                     [
32733
 
+                       "myusername@example.com",
32734
 
+                       "myusername@example.net"
32735
 
+                     ]
32736
 
+
32737
 
+                 )
32738
 
+             )
32739
 
+         { fileinto "INBOX.1_spam"; }
32740
 
+
32741
 
+
32742
 
+
32743
 
+#### Virus Filter
32744
 
+         elsif  header :contains ["subject", "from"]
32745
 
+         [
32746
 
+           "infected file rejected",
32747
 
+           "infected file rejected"
32748
 
+         ]
32749
 
+         { fileinto "INBOX.1_virus"; }
32750
 
+
32751
 
+
32752
 
+#### Telephone Alerts
32753
 
+#        Any message that gets this far should not be spam,
32754
 
+#        and a copy gets sent to my cell-phone as a TEXT message.
32755
 
+
32756
 
+         elsif  header :contains ["to", "cc"]
32757
 
+         [
32758
 
+           "myusername@example.com",
32759
 
+           "myaliasname@example.com"
32760
 
+         ]
32761
 
+         { redirect "2135551234@mobile.example.net"; keep; }
32762
 
+
32763
 
+
32764
 
+
32765
 
+# END OF SCRIPT
32766
 
diff -urN dovecot-1.2.4/dovecot-libsieve/examples/mjohnson.sieve dovecot-1.2.4.debian/dovecot-libsieve/examples/mjohnson.sieve
32767
 
--- dovecot-1.2.4/dovecot-libsieve/examples/mjohnson.sieve      1970-01-01 01:00:00.000000000 +0100
32768
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/examples/mjohnson.sieve       2008-10-04 10:41:25.000000000 +0200
32769
 
@@ -0,0 +1,421 @@
32770
 
+# Example Sieve Script
32771
 
+#  Author: Matthew Johnson
32772
 
+#  URL: http://wiki.fastmail.fm/index.php?title=MatthewJohnson
32773
 
+
32774
 
+##########################################################################
32775
 
+#######  SIEVE SCRIPT by Matthew Johnson - MRJ Solutions, Inc. ###########
32776
 
+#######  Email me at mailto:mattjohnson2005@gmail.com ##
32777
 
+#######  Code Version: 12JUN2004                               ###########
32778
 
+##########################################################################
32779
 
+require ["envelope", "fileinto", "reject", "vacation", "regex", "relational",
32780
 
+         "comparator-i;ascii-numeric"];
32781
 
+#
32782
 
+# todo:
32783
 
+# change to a nested format with
32784
 
+#   allof()s and nots.
32785
 
+# add "in address book" check. ex:"header :is :comparator "i;octet" "X-Spam-Known-Sender" "yes""
32786
 
+# finish reformating lines to <= 75 col (for web edit box)
32787
 
+#   and delete rulers.
32788
 
+# Mine Michael Klose script for ideas.
32789
 
+# Check out the update to the Sieve pages on the Fastmail Wiki.
32790
 
+#
32791
 
+
32792
 
+#---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+
32793
 
+require ["envelope", "fileinto", "reject", "vacation", "regex",
32794
 
+         "relational", "comparator-i;ascii-numeric"];
32795
 
+
32796
 
+
32797
 
+
32798
 
+# BLACKLIST - Mails to discard, drop on the floor.
32799
 
+#   -high spam values except those delivered to me
32800
 
+#   -Chinese content except for low spam values
32801
 
+#   -virus rejected notifications
32802
 
+#   -known spam addresses
32803
 
+#   -newsletters that refuse my removal requests
32804
 
+#   -twit-list
32805
 
+#   -double twit-list
32806
 
+#   -other
32807
 
+
32808
 
+
32809
 
+#---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+
32810
 
+if  anyof
32811
 
+    (
32812
 
+      allof       # combo test one - high spam values except for mail to/from me
32813
 
+      (
32814
 
+        # spam score is greater or equal to 14
32815
 
+        header :value "ge" :comparator "i;ascii-numeric"
32816
 
+                           ["X-Spam-score"] ["14"],
32817
 
+        not header :contains "X-Spam-Score" "-",  
32818
 
+        not header :contains "X-Spam-Score" "0.0",
32819
 
+        not header :contains ["to","from","cc","bcc","received"]
32820
 
+           [
32821
 
+             # do not discard email to me, will file or discard
32822
 
+             # as spam later if needed
32823
 
+             "matt@zeta.net",
32824
 
+             "matthew@bigsc.com",
32825
 
+             "matthew_johnson@bigsmallcompany.com",
32826
 
+             "mmm@spend.com",
32827
 
+             "finger@spend.com",
32828
 
+             "myyaacct@yahoo.com"
32829
 
+           ]
32830
 
+       ), # end allof
32831
 
+      allof       #combo test two - chinese content except for low spam values
32832
 
+      (
32833
 
+        anyof
32834
 
+        (
32835
 
+           header :regex "Subject"  "^=\\?(gb|GB)2312\\?",  # Chinese ecoding at subject
32836
 
+           header :regex "Subject"  "^=\\?big5\\?", # Other kind of  Chinese mail
32837
 
+
32838
 
+           # Chinese content type
32839
 
+           header :contains "Content-Type"
32840
 
+            [
32841
 
+             "GB2312",
32842
 
+             "big5"
32843
 
+            ]
32844
 
+        ), #end anyof
32845
 
+        not anyof
32846
 
+        (
32847
 
+           #We have to check the sign and the value separately: ascii-numeric, defined at
32848
 
+           #header :contains "X-Spam-Score" "-",
32849
 
+           header :value "lt" :comparator "i;ascii-numeric" "X-Spam-Score" "3"
32850
 
+         )  #end not anyof
32851
 
+     ), # end allof - test two
32852
 
+
32853
 
+     # single tests
32854
 
+
32855
 
+     # discard fastmail virus notifications
32856
 
+     header :is ["subject"] ["Infected file rejected"],
32857
 
+
32858
 
+     # black list, invalid addresses receiving a large amount of spam
32859
 
+     # or spam bounces,rejected zeta.net accounts.
32860
 
+     header :contains ["X-Delivered-to"]
32861
 
+
32862
 
+                        ["eagleeye@zeta.net","ealgeeye@zeta.net",
32863
 
+                        "alica.thiele@zeta.net", "2005@theta.com",
32864
 
+                        "jimlovingu2@zeta.net",
32865
 
+                        "alpha@zeta.net",
32866
 
+                        "JoshuaS@zeta.net",
32867
 
+                        "donnaf@zeta.net",
32868
 
+                        "pspinks@zeta.net",
32869
 
+                        "jsherman@zeta.net",
32870
 
+                        "holly@zeta.net",
32871
 
+                        "clabarca@zeta.net",
32872
 
+                        "meghanr@zeta.net",
32873
 
+                        "rtaylor@zeta.net",
32874
 
+                        "lboone@zeta.net",
32875
 
+                        "brower@zeta.net",
32876
 
+                        "jenj@zeta.net",
32877
 
+                        "cbackus@zeta.net",
32878
 
+                        "spengles@zeta.net",
32879
 
+                        "adams@zeta.net",
32880
 
+                        "dsmith@zeta.net",
32881
 
+                        "jwilderman@zeta.net",
32882
 
+                        "TimF@zeta.net",
32883
 
+                        "zd@zeta.net",
32884
 
+                        "louise@zeta.net"]
32885
 
+
32886
 
+     # single 'not' tests
32887
 
+     # ---out for testing---  not header :is :comparator "i;octet" "X-Spam-Known-Sender" "yes"
32888
 
+    ) # end anyof()
32889
 
+{
32890
 
+   discard;
32891
 
+   stop;
32892
 
+}
32893
 
+
32894
 
+
32895
 
+#
32896
 
+# WHITELIST - Keep these mails and put them in the inbox
32897
 
+#             (some kept getting put in Junk Mail)
32898
 
+#             Family, Friends, Current Vendors, Customers
32899
 
+#             Contents of fastmail address book.
32900
 
+#
32901
 
+#---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+
32902
 
+if  anyof (  header :contains ["from","to","cc","bcc"]
32903
 
+                     [ "notification@eBay.com",
32904
 
+                       "MAILER-DAEMON@zeta.net",
32905
 
+                       "USPS_Track_Confirm@usps.com",
32906
 
+                       "credit.services@target.com",
32907
 
+                       "Comcast_Paydirect@comcast.net",
32908
 
+                       "mary@zeta.net",
32909
 
+                       "betty@zeta.net",
32910
 
+                       "andmanymore@zeta.net"
32911
 
+                       ],
32912
 
+            header :is :comparator "i;octet" "X-Spam-Known-Sender" "yes"
32913
 
+          )
32914
 
+{
32915
 
+  fileinto "INBOX";
32916
 
+  stop;
32917
 
+}
32918
 
+
32919
 
+# redirects
32920
 
+if header :contains ["to", "cc"] "mary1@zeta.net"
32921
 
+ {
32922
 
+  redirect "mary@zeta.net";
32923
 
+  stop;
32924
 
+ }
32925
 
+
32926
 
+
32927
 
+#
32928
 
+#   +Spam filtering by score on 3, 5 and 14(above).
32929
 
+#
32930
 
+#
32931
 
+if  header :value "ge" :comparator "i;ascii-numeric" ["X-Spam-score"] ["5"]  {
32932
 
+    fileinto "INBOX.Junk Mail.ge5";
32933
 
+    stop;
32934
 
+#---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+
32935
 
+} elsif  header :value "ge" :comparator "i;ascii-numeric" ["X-Spam-score"] ["3"]  {
32936
 
+    fileinto "INBOX.Junk Mail.ge3";
32937
 
+    stop;
32938
 
+}
32939
 
+
32940
 
+
32941
 
+# Potential Blacklist, start with soft discard, then migrate to full discard above
32942
 
+#
32943
 
+# Blacklist (2nd) During testing, throw into "Junk Mail.discard" until
32944
 
+#                 ready to discard.
32945
 
+#
32946
 
+if anyof
32947
 
+   (
32948
 
+    # rejects for accounts across all domains
32949
 
+    header :contains ["X-Delivered-to"]
32950
 
+                  [
32951
 
+                  "drjoe@","VX@",
32952
 
+                  "alfa@zeta.net",
32953
 
+                  "media@zeta.net",
32954
 
+                  "zeta@zeta.net",
32955
 
+                  "xyz@zeta.net"
32956
 
+                  ],
32957
 
+
32958
 
+    # other criteria - weird message from this account
32959
 
+    header :contains ["from"] ["Charlie Root"],
32960
 
+    # mailers that are always sending spam returns to me
32961
 
+    header :contains ["from"] ["MAILER-DAEMON@aol.com"] ,
32962
 
+    header :contains ["from"] ["MAILER-DAEMON@otenet.gr"] ,
32963
 
+
32964
 
+    # common account names that I don't use in any of my domains and that spammers like
32965
 
+    header :contains ["X-Delivered-to"]
32966
 
+                     [ "biz@","sales@","support@", "service@", "reg@",
32967
 
+                       "registration@", "regisration@", "root@", "webmaster@", "noreply@"
32968
 
+                     ],
32969
 
+    # zeta.net common account names to reject
32970
 
+    header :contains ["X-Delivered-to"] ["info@zeta.net"],
32971
 
+    # bigsc.com  rejects
32972
 
+    header :contains ["X-Delivered-to"] ["info@bigsc.com"],
32973
 
+    # theta.com rejects
32974
 
+    header :contains ["X-Delivered-to"] ["info@theta.com"],
32975
 
+    header :contains ["X-Delivered-to"] ["reg@theta.com"]
32976
 
+#---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+
32977
 
+        # saves for use maybe later
32978
 
+        #   header :contains ["X-Delivered-to"] ["webmaster@zeta.net"],
32979
 
+        #   header :contains ["X-Delivered-to"] ["webmaster@theta.com"],
32980
 
+        #   header :contains ["X-Delivered-to"] ["sales@bs.com"],
32981
 
+        #   header :contains ["X-Delivered-to"] ["sales@theta.com"],
32982
 
+        #   header :contains ["X-Delivered-to"] ["sales@bigsc.com"],
32983
 
+        #   header :contains ["X-Delivered-to"] "root@zeta.net",
32984
 
+
32985
 
+   )   #end  anyof() 2nd blacklist
32986
 
+{
32987
 
+
32988
 
+  fileinto "INBOX.Junk Mail.discard";
32989
 
+  stop;
32990
 
+}
32991
 
+
32992
 
+
32993
 
+#  +Greylist, move to "INBOX.Junk Mail.greylist"
32994
 
+#
32995
 
+#   'Soft' Blacklist  ?Greylist?
32996
 
+#
32997
 
+
32998
 
+#annoying person(s) that send questionable attachments
32999
 
+#  look at occationally
33000
 
+if  header :contains "from" "alex@yahoo.com"
33001
 
+{
33002
 
+  fileinto "INBOX.Junk Mail.greylist";
33003
 
+} elsif  header :contains "subject" "MAILER-DAEMON@fastmail.fm"
33004
 
+                                     #  non-person, but might
33005
 
+                                     # want to look at it while
33006
 
+                                                                    # figuring issues
33007
 
+{
33008
 
+  fileinto "INBOX.Junk Mail.greylist";
33009
 
+  stop;
33010
 
+}
33011
 
+
33012
 
+#   +Spammy domains to filter
33013
 
+#
33014
 
+# domains that are known to be present in spam
33015
 
+#
33016
 
+if  header :contains ["from", "received"] [".ru",".jp", ".kr", ".pt",
33017
 
+                                                            ".pl",".at",".cz",".cn",".lu" ]
33018
 
+{
33019
 
+  fileinto "INBOX.Junk Mail.discard";
33020
 
+  stop;
33021
 
+}
33022
 
+
33023
 
+
33024
 
+#
33025
 
+#  Annoying newsletters that won't unsubscribe me, reject
33026
 
+#
33027
 
+
33028
 
+if anyof (
33029
 
+           #annoying newsletters
33030
 
+           header :contains ["from"] "VistaPrintNews",               # 2003
33031
 
+           header :contains ["from"] "newsletter@briantracyintl.com", # 2003
33032
 
+           header :contains ["from"] "info@yogalist.com",            # 2003
33033
 
+           header :contains ["from"] "The Angela Larson Real Estate Team",
33034
 
+           header :contains ["from"] "Brian Tracy"
33035
 
+         )
33036
 
+#---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+
33037
 
+{
33038
 
+   reject "I HAVE TRIED TO UNSUBSCRIBE; I DO NOT WANT YOUR NEWSLETTER; PLEASE UNSUBSCRIBE ME";
33039
 
+  stop;
33040
 
+}
33041
 
+
33042
 
+
33043
 
+
33044
 
+
33045
 
+#
33046
 
+# Suspected zeta.net user from/to Zeta Institute, NY - reject
33047
 
+#
33048
 
+#
33049
 
+#
33050
 
+if    header :contains ["X-Delivered-to","from"]
33051
 
+          [
33052
 
+          # aaaaNEW_ENTRIES_ABOVE  ###################################
33053
 
+          "neville@zeta.net",
33054
 
+          "animika@zeta.net",
33055
 
+          "linda@zeta.net",
33056
 
+          "jerry@zeta.net",
33057
 
+          "adamS@zeta.net",
33058
 
+          "lkdamon@zeta.net",
33059
 
+          "AdamS@zeta.net",
33060
 
+          "DConnor@zeta.net",
33061
 
+          "LOUISR@zeta.net",
33062
 
+
33063
 
+          # Start of Alpha #############################################
33064
 
+          "Allanv@zeta.net",
33065
 
+          "AmberJ@zeta.net",
33066
 
+          "DANDERSON@zeta.net",
33067
 
+          "Jonas@zeta.net",
33068
 
+          "KarenE@zeta.net",
33069
 
+          "J.R.C.@zeta.net", # check to see if this is working
33070
 
+          "PMackey@zeta.net",
33071
 
+
33072
 
+          "adrienne@zeta.net","alpha@zeta.net","amina@zeta.net",
33073
 
+          "anamika@zeta.net",
33074
 
+          "claborca@zeta.net","communications@zeta.net",
33075
 
+          "cz241@zeta.net",
33076
 
+          "dee@zeta.net",
33077
 
+          "ellenb@zeta.net","evis@zeta.net",
33078
 
+          "frivera@zeta.net",
33079
 
+          "gblack@zeta.net","gbrown@zeta.net","george@zeta.net","grace@zeta.net",
33080
 
+          "happygolucky@zeta.net","hsp@zeta.net",
33081
 
+          "ila@zeta.net",
33082
 
+          "jacqueline_fenatifa@zeta.net","jlengler@zeta.net",
33083
 
+          "joel@zeta.net","jolsen@zeta.net", "jsherman@zeta.net",
33084
 
+          "kronjeklandish@zeta.net","kwilcox@zeta.net","bettyb@zeta.net",
33085
 
+          "laurie@zeta.net","llmansell@zeta.net",
33086
 
+          "louise@zeta.net","lzollo@zeta.net",
33087
 
+          "mcraft@zeta.net","meganB@zeta.net","mwezi@zeta.net",
33088
 
+          "nanwile@zeta.net",
33089
 
+          "zetasound@zeta.net",
33090
 
+          "peter@zeta.net",
33091
 
+          "randi@zeta.net", "rcbackus@zeta.net", "registration@zeta.net",
33092
 
+          "registration@omgea.org",
33093
 
+          "rtaylor@zeta.net",
33094
 
+          "sdonnarumma@zeta.net","stephanR@zeta.net","suzanne@zeta.net","suzzane@zeta.net",
33095
 
+          "taryngaughan_dn@zeta.net"
33096
 
+          # zzzzEND_OF_LIST####
33097
 
+          ]   #end of Xdelivered-to list for possible zeta institute users
33098
 
+
33099
 
+{
33100
 
+  reject text:
33101
 
+      ERROR: Your email has not been delivered.
33102
 
+
33103
 
+      You have reached the mailer at zeta.net
33104
 
+
33105
 
+      Perhaps you want to send to Zeta Institute in DillyDally, NY, USA?
33106
 
+
33107
 
+      Use  USER@zeta.net for them
33108
 
+
33109
 
+      or try registration@zeta.net
33110
 
+      Check the website at  http://www.zeta.net/zeta/contact/
33111
 
+      Call Registration at    1 800 944 1001.
33112
 
+
33113
 
+      or use this information:
33114
 
+
33115
 
+      Zeta Institute
33116
 
+      150 River Drive
33117
 
+      DillyDally, NY 12666
33118
 
+      Registration: 800-900-0000
33119
 
+      Ph: 845-200-0000
33120
 
+      Fax: 845-200-0001
33121
 
+      registration@zeta.net
33122
 
+
33123
 
+      sincerely, POSTMASTER
33124
 
+.
33125
 
+;
33126
 
+  fileinto "Inbox.Junk Mail.ezeta";
33127
 
+  stop;
33128
 
+ }
33129
 
+#---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+
33130
 
+# +Move messages into folders
33131
 
+#
33132
 
+# Process other messages into separate folders
33133
 
+#
33134
 
+ # newsletters and mail lists
33135
 
+if  header :contains  ["subject"]
33136
 
+                      [ "newsletter", "[tc-ieee-", "[icntc",
33137
 
+                        "JUG News", "Xdesksoftware",
33138
 
+                        "announcement"   ]
33139
 
+{
33140
 
+  fileinto "INBOX.Newsletters";
33141
 
+} elsif header :contains ["from","subject"] ["Anthony Robbins"] {
33142
 
+  fileinto "INBOX.Newsletters";
33143
 
+} elsif  header :contains ["from","subject"] ["MN Entrepreneurs","ME!"]  {
33144
 
+  fileinto "INBOX.Newsletters";
33145
 
+} elsif  header :contains ["from","received"] "adc.apple.com" {
33146
 
+  fileinto "INBOX.Newsletters";
33147
 
+} elsif  header :contains "from" "wnewadmn@ieee.org" {
33148
 
+  fileinto "INBOX.Newsletters";
33149
 
+} elsif  header :contains "from" "@lb.bcentral.com" {  # techworthy@lb.bcentral.com
33150
 
+  fileinto "INBOX.Newsletters";
33151
 
+} elsif  header :contains "from" "announcement@netbriefings.com" {  #st paul company
33152
 
+  fileinto "INBOX.Newsletters";
33153
 
+} elsif  header :contains "from" "newsletter@eletters.extremetech.com" {  #semi-annoying rag
33154
 
+  fileinto "INBOX.Newsletters";
33155
 
+#---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+
33156
 
+# my newsletter throw-away addresses
33157
 
+} elsif  header :contains "to" ["microcenter@zeta.net","nmha@zeta.net"] {
33158
 
+  fileinto "INBOX.Newsletters";
33159
 
+
33160
 
+#---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+
33161
 
+#
33162
 
+# Alerts mailbox
33163
 
+} elsif header :contains ["subject", "from"]
33164
 
+                         [
33165
 
+                          "Alert",                         # F-Prot virus alert service, matches:
33166
 
+                                                           # "FRISK Virus Alert"
33167
 
+                                                           #     or use s:FRISK Virus Alert:
33168
 
+                                                           #     or use f:support@f-prot.com
33169
 
+                          "Payment",                       # Alerts from other payments
33170
 
+                          "credit.services@target.com",    # Target Card Payments
33171
 
+                          "notify@quickbase.com"           # Tic Talkers Database changes
33172
 
+                         ]
33173
 
+{
33174
 
+  fileinto "INBOX.Alerts";
33175
 
+  stop;
33176
 
+}
33177
 
+
33178
 
+# +Announcements from Dave Rolm, forward
33179
 
+#
33180
 
+# Perl Announcements from Dave Rolm
33181
 
+if  header :contains "from" "dave@other.org"
33182
 
+{
33183
 
+  fileinto "Inbox";
33184
 
+  keep;
33185
 
+}
33186
 
+#---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+
33187
 
+#######################################################################
33188
 
+#### END OF SIEVE SCRIPT by Matthew Johnson - MRJ Solutions, Inc. #####
33189
 
+################ email me at mailto:mattjohnson2005@gmail.com   #
33190
 
+
33191
 
diff -urN dovecot-1.2.4/dovecot-libsieve/examples/mklose.sieve dovecot-1.2.4.debian/dovecot-libsieve/examples/mklose.sieve
33192
 
--- dovecot-1.2.4/dovecot-libsieve/examples/mklose.sieve        1970-01-01 01:00:00.000000000 +0100
33193
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/examples/mklose.sieve 2008-10-04 10:41:25.000000000 +0200
33194
 
@@ -0,0 +1,303 @@
33195
 
+# Example Sieve Script
33196
 
+#   Author: Michael Klose
33197
 
+#   URL: http://wiki.fastmail.fm/index.php?title=MichaelKloseSieveScript
33198
 
+
33199
 
+require ["fileinto", "reject", "vacation", "regex", "relational", "comparator-i;ascii-numeric"];
33200
 
+
33201
 
+# Experimental
33202
 
+
33203
 
+# End experimental
33204
 
+
33205
 
+
33206
 
+
33207
 
+# ----------------------------------------------
33208
 
+#    Discard messages (high Spam values)
33209
 
+# ----------------------------------------------
33210
 
+
33211
 
+if anyof
33212
 
+    (
33213
 
+     allof
33214
 
+      (
33215
 
+       #Spam score > 17?
33216
 
+       #We have to check the sign and the value separately: ascii-numeric, defined at http://www.ietf.org/rfc/rfc2244.txt, doesn't see minus signs or decimal points ("-" or ".").
33217
 
+       header :value "ge" :comparator "i;ascii-numeric" "X-Spam-Score" "17",
33218
 
+       not header :contains "X-Spam-Score" "-",
33219
 
+
33220
 
+       not header :contains ["to","cc"]
33221
 
+        [
33222
 
+         "@my-domain.de",
33223
 
+         "myemail@myotherdomain.us",
33224
 
+         "myotheremail@myotherdomain.us",
33225
 
+         "myotheremail2@myotherdomain.us"
33226
 
+         # Do not discard stuff going to me - gets filed into Junk later
33227
 
+        ],
33228
 
+       not header :contains "from"
33229
 
+        [
33230
 
+         "lockergnome.com",
33231
 
+         "Excite@info.excite.com" # gets filed into Junk later
33232
 
+        ]
33233
 
+
33234
 
+
33235
 
+      ),
33236
 
+     allof
33237
 
+      (
33238
 
+       header :contains "X-LinkName" "hotmail", # OR anything from Hotmail with low spam
33239
 
+       allof
33240
 
+        (
33241
 
+         header :value "ge" :comparator "i;ascii-numeric" "X-Spam-Score" "7",
33242
 
+         not header :contains "X-Spam-Score" "-"
33243
 
+        )
33244
 
+      ),
33245
 
+
33246
 
+     # Black List
33247
 
+
33248
 
+     header :contains "from"
33249
 
+      [
33250
 
+       "ahbbcom@cncorn.com",
33251
 
+       "Darg. B."
33252
 
+      ],
33253
 
+
33254
 
+     # Chinese Encoding at BEGINNING of Subject
33255
 
+
33256
 
+     allof
33257
 
+      (
33258
 
+       anyof
33259
 
+        (
33260
 
+         header :regex "Subject"  "^=\\?(gb|GB)2312\\?",  # Chinese ecoding at subject
33261
 
+         header :regex "Subject"  "^=\\?big5\\?", # Other kind of Chinese mail
33262
 
+
33263
 
+         # Chinese content type
33264
 
+
33265
 
+         header :contains "Content-Type"
33266
 
+          [
33267
 
+           "GB2312",
33268
 
+           "big5"
33269
 
+          ]
33270
 
+        ),
33271
 
+       not anyof
33272
 
+        (
33273
 
+      #Spam score > -4? <sic> - ascii-numeric ignores the ".9"!.  -Or is this correct?
33274
 
+       #We have to check the sign and the value separately: ascii-numeric, defined at http://www.ietf.org/rfc/rfc2244.txt, doesn't see minus signs or decimal points ("-" or ".").
33275
 
+
33276
 
+         header :contains "X-Spam-Score" "-",
33277
 
+         header :value "lt" :comparator "i;ascii-numeric" "X-Spam-Score" "4"
33278
 
+        )
33279
 
+      )
33280
 
+    )
33281
 
+
33282
 
+{
33283
 
+
33284
 
+
33285
 
+  # discard;
33286
 
+
33287
 
+  if header :contains "X-LinkName" "hotmail"
33288
 
+   { discard; }
33289
 
+  else
33290
 
+   { fileinto "INBOX.Junk.Reject"; }
33291
 
+   # I used to reject this stuff, but I wanted to know what I was rejecting, and this stuck.
33292
 
+  stop;
33293
 
+}
33294
 
+
33295
 
+
33296
 
+
33297
 
+# Addresses that need to be forwarded to a different domain here before spam checking
33298
 
+# ******************************Michael - I don't understand what you're doing here!  -elvey
33299
 
+# REPLY: this here is actually used to forward stuff addressed to my sister (using my domain)
33300
 
+# to her - without using one of the own-domain aliases.
33301
 
+
33302
 
+if header :contains ["to", "cc"]
33303
 
+ [
33304
 
+  "bla@blabla.de",
33305
 
+  "bla2@blabla.us",
33306
 
+  "bla3@blabla.us"
33307
 
+ ]
33308
 
+ {
33309
 
+  redirect "otheremailaddress@something.com";
33310
 
+  redirect "anotheremailadress@something.com";
33311
 
+  stop;
33312
 
+ }
33313
 
+
33314
 
+
33315
 
+# File into a folder before Spam filtering
33316
 
+
33317
 
+if header :contains ["to","cc"]
33318
 
+ [
33319
 
+  "important@mydomain.us",
33320
 
+  "important2@mydomain.us"
33321
 
+ ]
33322
 
+ {
33323
 
+  fileinto "Inbox.Important";
33324
 
+  stop;
33325
 
+ }
33326
 
+
33327
 
+
33328
 
+
33329
 
+# -------------------------------------------
33330
 
+#              Filing rules
33331
 
+# -------------------------------------------
33332
 
+
33333
 
+
33334
 
+# Pre-SPAM
33335
 
+
33336
 
+
33337
 
+if size :over 750K
33338
 
+ {
33339
 
+  fileinto "INBOX.largemail";
33340
 
+  stop;
33341
 
+ }
33342
 
+
33343
 
+
33344
 
+if header :contains "from"
33345
 
+   [
33346
 
+
33347
 
+# White list 1 (with SMS notification)
33348
 
+
33349
 
+    "Fred Bloggs",
33350
 
+    "f.bloggs@hotmail.com",
33351
 
+    "myboss@somecompany.com",
33352
 
+    "Trisha",
33353
 
+    "endofauction@ebay.de" # I want to know about end of auctions
33354
 
+    ]
33355
 
+ {
33356
 
+  fileinto "Inbox";
33357
 
+
33358
 
+  # Send an SMS
33359
 
+  redirect "smsgateway@somegateway.de";
33360
 
+  keep;
33361
 
+
33362
 
+  stop;
33363
 
+ }
33364
 
+
33365
 
+  # Advertising I want to receive, which normally ends up in the SPAM filter
33366
 
+
33367
 
+  if anyof
33368
 
+   (
33369
 
+    header :contains "from"
33370
 
+
33371
 
+     [
33372
 
+
33373
 
+# Advertising whitelist
33374
 
+
33375
 
+      "Mark Libbert",
33376
 
+      "newsletter@snapfish.dom"
33377
 
+     ],
33378
 
+    header :contains "Return-Path" "mailings@gmx.dom"
33379
 
+   )
33380
 
+   { fileinto "INBOX.Ads"; }
33381
 
+  elsif  header :contains "from"
33382
 
+   [
33383
 
+    "newsletter@neuseelandhaus.dom",
33384
 
+    "Lockergnome",
33385
 
+    "CNET News.com"
33386
 
+   ]
33387
 
+   { fileinto "INBOX.Newsletter";
33388
 
+
33389
 
+
33390
 
+
33391
 
+# Spam protection
33392
 
+
33393
 
+
33394
 
+} elsif anyof
33395
 
+   (
33396
 
+
33397
 
+    #Spam assasin
33398
 
+    allof
33399
 
+     (
33400
 
+      header :value "ge" :comparator "i;ascii-numeric" "X-Spam-Score" "6",
33401
 
+      not header :contains "X-Spam-Score" "-",
33402
 
+      not anyof # White list
33403
 
+       (
33404
 
+        header :contains "From"         # Whitelist From addresses
33405
 
+         [
33406
 
+          "CNN Quick News",
33407
 
+          "FastMail.FM Support",
33408
 
+          "lockergnome.com"
33409
 
+         ]
33410
 
+       )
33411
 
+     ),
33412
 
+
33413
 
+    # User defined
33414
 
+
33415
 
+    # Filter out Femalename1234z12@ spam (base64 encoded)
33416
 
+    allof
33417
 
+     (
33418
 
+      header :regex "From" "alpha:{2,}digit:{2,}alpha:+digit:{2,}@",
33419
 
+      header :contains "Content-Type" "multipart/mixed"
33420
 
+     ),
33421
 
+    # Filter our Spam with invalid headers. You can see this because FM adds
33422
 
+    # @fastmail.fm to them. For safty, check that mklose@ @michael-klose mkmail@gmx do
33423
 
+    # not appear
33424
 
+
33425
 
+    # Mklose: addition: The only negative side effect I have seen of the condition below
33426
 
+    # is that it catches the FM newsletters. So far I find them in the spam occasionly
33427
 
+    # but since they are so few, I have never bothered changing this to not catch them.
33428
 
+
33429
 
+    allof
33430
 
+     (
33431
 
+      header :contains "To" "@fastmail.fm", # I do not have a fastmail address   # This doesn't catch BCC's; you should be checking the envelop instead.  -elvey
33432
 
+      not header :contains ["To", "CC", "Reply-To"] ["klose","mkmail@gmx.dom", "chaospower"]
33433
 
+     )
33434
 
+   )
33435
 
+  {
33436
 
+   fileinto "INBOX.Junk";
33437
 
+   stop;
33438
 
+  }
33439
 
+
33440
 
+
33441
 
+# Post Spam-protection
33442
 
+
33443
 
+  elsif  header :contains ["to", "cc"] "gpc@gnu.dom" {
33444
 
+  fileinto "INBOX.GPC";
33445
 
+} elsif  header :contains ["to", "cc"] "alfs\-discuss@linuxfromscratch.dom" {
33446
 
+  fileinto "INBOX.LFS-Support.ALFS";
33447
 
+} elsif  header :contains "subject" "(usagi\-users" {
33448
 
+  fileinto "INBOX.Usagi";
33449
 
+} elsif anyof (header :contains "Subject" "\[eplus-de\]", header :contains "Reply-To" "eplus-de") {
33450
 
+  fileinto "INBOX.E-Plus";
33451
 
+} elsif  header :contains ["to", "cc"] "lfs\-support@linuxfromscratch.dom" {
33452
 
+  fileinto "INBOX.LFS-Support";
33453
 
+} elsif  header :contains ["to", "cc"] "netdev@oss.sgi.dom" {
33454
 
+  fileinto "INBOX.NetDev";
33455
 
+} elsif  header :contains ["to", "cc"] "lfs\-dev@linuxfromscratch.dom" {
33456
 
+  fileinto "INBOX.LFS-DEV";
33457
 
+} elsif  header :contains "from" "GMX Best Price" {
33458
 
+  fileinto "INBOX.Werbung";
33459
 
+} elsif  header :contains "subject" "RHN Errata Alert" {
33460
 
+  fileinto "INBOX.Notifications";
33461
 
+} elsif  header :contains "from"
33462
 
+  [
33463
 
+   "EmailDiscussions.com Mailer",
33464
 
+   "help1@dungorm.dom"
33465
 
+  ] {
33466
 
+  fileinto "INBOX.Notifications";
33467
 
+} elsif  header :contains "subject" "\[Gaim\-commits\]" {
33468
 
+  fileinto "INBOX.Notifications";
33469
 
+} elsif  header :contains "subject" "\[Bug" {
33470
 
+  fileinto "INBOX.Notifications.Bugzilla";
33471
 
+} elsif header :contains "X-LinkName" "hotmail" {
33472
 
+  fileinto "INBOX.Old Hotmail.new";
33473
 
+}
33474
 
+
33475
 
+
33476
 
+# -----------------------------------------------------------------------
33477
 
+#               SMS notifications and forwarding
33478
 
+# -----------------------------------------------------------------------
33479
 
+
33480
 
+if allof
33481
 
+    (
33482
 
+     header :contains "to" ["@mydomain1.de","email@mydomain2.us","email2@somedomain"],
33483
 
+     not header :contains "from"
33484
 
+      [
33485
 
+
33486
 
+# This avoids sending SMS notifications if I am the sender
33487
 
+
33488
 
+       "@mydomain1.de",
33489
 
+       "myotheremail@somedomain.de",
33490
 
+       "myotheremail@someotherdomain.de"
33491
 
+      ]
33492
 
+    )
33493
 
+ {
33494
 
+  redirect "smsgateway@somegateway.com";
33495
 
+  keep;
33496
 
+ }
33497
 
+
33498
 
Binary files dovecot-1.2.4/dovecot-libsieve/examples/mklose.svbin and dovecot-1.2.4.debian/dovecot-libsieve/examples/mklose.svbin differ
33499
 
diff -urN dovecot-1.2.4/dovecot-libsieve/examples/relational.rfc5231.sieve dovecot-1.2.4.debian/dovecot-libsieve/examples/relational.rfc5231.sieve
33500
 
--- dovecot-1.2.4/dovecot-libsieve/examples/relational.rfc5231.sieve    1970-01-01 01:00:00.000000000 +0100
33501
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/examples/relational.rfc5231.sieve     2008-10-04 10:41:25.000000000 +0200
33502
 
@@ -0,0 +1,33 @@
33503
 
+require ["relational", "comparator-i;ascii-numeric", "fileinto"];
33504
 
+
33505
 
+if header :value "lt" :comparator "i;ascii-numeric"
33506
 
+       ["x-priority"] ["3"]
33507
 
+{
33508
 
+       fileinto "Priority";
33509
 
+}
33510
 
+
33511
 
+elsif address :count "gt" :comparator "i;ascii-numeric"
33512
 
+       ["to"] ["5"]
33513
 
+{
33514
 
+       # everything with more than 5 recipients in the "to" field
33515
 
+       # is considered SPAM
33516
 
+       fileinto "SPAM";
33517
 
+}
33518
 
+
33519
 
+elsif address :value "gt" :all :comparator "i;ascii-casemap"
33520
 
+       ["from"] ["M"]
33521
 
+{
33522
 
+       fileinto "From N-Z";
33523
 
+} else {
33524
 
+       fileinto "From A-M";
33525
 
+}
33526
 
+
33527
 
+if allof ( 
33528
 
+       address :count "eq" :comparator "i;ascii-numeric"
33529
 
+               ["to", "cc"] ["1"] ,
33530
 
+       address :all :comparator "i;ascii-casemap"
33531
 
+               ["to", "cc"] ["me@foo.example.com"] )
33532
 
+{
33533
 
+       fileinto "Only me";
33534
 
+}
33535
 
+
33536
 
diff -urN dovecot-1.2.4/dovecot-libsieve/examples/rfc3028.sieve dovecot-1.2.4.debian/dovecot-libsieve/examples/rfc3028.sieve
33537
 
--- dovecot-1.2.4/dovecot-libsieve/examples/rfc3028.sieve       1970-01-01 01:00:00.000000000 +0100
33538
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/examples/rfc3028.sieve        2008-10-04 10:41:25.000000000 +0200
33539
 
@@ -0,0 +1,58 @@
33540
 
+#
33541
 
+# Example Sieve Filter
33542
 
+# Declare any optional features or extension used by the script
33543
 
+#
33544
 
+require ["fileinto", "reject"];
33545
 
+
33546
 
+#
33547
 
+# Reject any large messages (note that the four leading dots get
33548
 
+# "stuffed" to three)
33549
 
+#
33550
 
+if size :over 1M
33551
 
+    {
33552
 
+    reject text:
33553
 
+Please do not send me large attachments.
33554
 
+Put your file on a server and send me the URL.
33555
 
+Thank you.
33556
 
+.... Fred
33557
 
+.
33558
 
+;
33559
 
+    stop;
33560
 
+    }
33561
 
+#
33562
 
+
33563
 
+# Handle messages from known mailing lists
33564
 
+# Move messages from IETF filter discussion list to filter folder
33565
 
+#
33566
 
+if header :is "Sender" "owner-ietf-mta-filters@imc.org"
33567
 
+    {
33568
 
+    fileinto "filter";  # move to "filter" folder
33569
 
+    }
33570
 
+#
33571
 
+# Keep all messages to or from people in my company
33572
 
+#
33573
 
+elsif address :domain :is ["From", "To"] "example.com"
33574
 
+    {
33575
 
+    keep;               # keep in "In" folder
33576
 
+    }
33577
 
+
33578
 
+#
33579
 
+# Try and catch unsolicited email.  If a message is not to me,
33580
 
+# or it contains a subject known to be spam, file it away.
33581
 
+#
33582
 
+elsif anyof (not address :all :contains
33583
 
+         ["To", "Cc", "Bcc"] "me@example.com",
33584
 
+     header :matches "subject"
33585
 
+         ["*make*money*fast*", "*university*dipl*mas*"])
33586
 
+    {
33587
 
+    # If message header does not contain my address,
33588
 
+    # it's from a list.
33589
 
+    fileinto "spam";   # move to "spam" folder
33590
 
+    }
33591
 
+ else
33592
 
+    {
33593
 
+    # Move all other (non-company) mail to "personal"
33594
 
+    # folder.
33595
 
+    fileinto "personal";
33596
 
+    }
33597
 
+
33598
 
diff -urN dovecot-1.2.4/dovecot-libsieve/examples/sanjay.sieve dovecot-1.2.4.debian/dovecot-libsieve/examples/sanjay.sieve
33599
 
--- dovecot-1.2.4/dovecot-libsieve/examples/sanjay.sieve        1970-01-01 01:00:00.000000000 +0100
33600
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/examples/sanjay.sieve 2008-10-04 10:41:25.000000000 +0200
33601
 
@@ -0,0 +1,171 @@
33602
 
+# Example Sieve Script
33603
 
+#   Author: SanjaySheth
33604
 
+#   URL: http://wiki.fastmail.fm/index.php?title=SanjaySieveSpamFilter
33605
 
+
33606
 
+require "fileinto";
33607
 
+
33608
 
+if anyof (
33609
 
+
33610
 
+      # Blacklisted sender domains
33611
 
+      header :contains ["from", "Received", "X-Sender", "Sender",
33612
 
+                        "To","CC","Subject","X-Mail-from"]
33613
 
+             [ "123greetings", "allfreewebsite.com",
33614
 
+               "new-fields.com","atlasrewards","azogle.com",
33615
 
+               "bannerport.net","bettingextreme.com","bigemailoffers.com",
33616
 
+               "BlingMail.com",
33617
 
+               "beyondoffers.net", ".biz ", ".biz]",
33618
 
+               "cavalrymail.com","ciol.com","citywire.co.uk",
33619
 
+               "cosmicclick.com",
33620
 
+               "consumergamblingreport","creativemailoffers.com","creativeoffers.com",
33621
 
+               "daily-promotions.com",
33622
 
+               "dailypromo.","dailypromotions.",
33623
 
+               "dandyoffers","dlbdirect",
33624
 
+               "e54.org",  "email-specials.net","email-ware.com","emailoffersondemand",
33625
 
+               "emailbargain.com","emailofferz","emailrewardz","etoll.net","emailvalues.com",
33626
 
+               "evaluemarketing.com","exitrequest.com",
33627
 
+               "fantastic-bargain.com","fpsamplesmail.com","freelotto",
33628
 
+               "findtv.com", "freddysfabulousfinds.com",
33629
 
+               "genuinerewards.com",
33630
 
+               "hotdailydeal.com","hulamediamail","hy-e.net",
33631
 
+               "inboxbargains.com","idealemail.com",
33632
 
+               "jackpot.com","jpmailer.com",
33633
 
+               "lolita","lund.com.br",
33634
 
+               "mafgroup.com","mailasia.com","mailtonic.net","migada.com","ms83.com",
33635
 
+               "nationaloffers.com","nexdeals.com ",
33636
 
+               "offercatch.com","offermagnet.com","offerservice.net","offertime.com",
33637
 
+               "offersdaily.net","optnetwork.net",
33638
 
+               "ombramarketing.com","on-line-offers.com","outblaze.com",
33639
 
+               "permissionpass","primetimedirect.net","productsontheweb.net",
33640
 
+               "rapid-e.net","recessionspecials", "redmoss","remit2india",
33641
 
+               "sampleoffers.com","savingsmansion.com","sendoutmail.com","simpleoffers.com",
33642
 
+               "specialdailydeals4u.com","Select-Point.net",
33643
 
+               "speedyvalues.com","sportsoffers","sporttime.info","suntekglobal.com",
33644
 
+               "superstorespecials.com", "synapseconnect","sunsetterawnings.com",
33645
 
+               "thefreesamplenews","truemail.net",
33646
 
+               "ub-kool","ultimatesports.info","uniquemailoffers","utopiad.com",
33647
 
+               "unixlovers.net",
33648
 
+               "valuesdirect","virtualoffers.net",
33649
 
+               "wagerzine", "webdpoffrz",
33650
 
+               "yestshirt.com",
33651
 
+               "z-offer.com", "zipido.com"
33652
 
+             ],
33653
 
+
33654
 
+      # Blacklisted ip subnets due to excessive spam from them
33655
 
+      header :contains "Received"
33656
 
+             [ "[4.63.221.224",
33657
 
+               "[24.244.141.112",
33658
 
+               "[61.171.253.177",
33659
 
+               "[63.123.149.", "[63.209.206.", "(63.233.30.73", "[63.251.200.",
33660
 
+               "[64.41.183.","[64.49.250.", "[64.57.188.", "[64.57.221.",
33661
 
+               "[64.62.204.",
33662
 
+               "[64.70.17.", "[64.70.44.", "[64.70.53.",
33663
 
+               "[64.39.27.6", "[64.39.27.7","[64.191.25.","[64.191.36.",
33664
 
+               "[64.191.9.",
33665
 
+               "[64.125.181.", "[64.191.123.", "[64.191.23.", "[64.239.182.",
33666
 
+               "[65.211.3.",
33667
 
+               "[66.46.150.", "[66.62.162.", "[66.118.170.", "[66.129.124.",
33668
 
+               "[66.205.217.", "[66.216.111.", "[66.239.204.",
33669
 
+               "[67.86.69.",
33670
 
+               "[80.34.206.", "[80.80.98.",
33671
 
+               "[81.72.233.13",
33672
 
+               "[128.242.120.",
33673
 
+               "[157.238.18",
33674
 
+               "[168.234.195.18]",
33675
 
+               "[193.253.198.57",
33676
 
+               "[194.25.83.1",
33677
 
+               "[200.24.129.", "[200.161.203.",
33678
 
+               "[202.164.182.76]","[202.57.69.116",
33679
 
+               "[203.19.220.","[203.22.104.","[203.22.105.",
33680
 
+               "[204.188.52.",
33681
 
+               "[205.153.154.203",
33682
 
+               "[206.26.195.", "[206.154.33.","[206.169.178",
33683
 
+               "[207.142.3.",
33684
 
+               "[208.46.5.","[208.187.",
33685
 
+               "[209.164.27.","[209.236.",
33686
 
+               "[210.90.75.129]",
33687
 
+               "[211.101.138.199","[211.185.7.125]","[211.239.231.",
33688
 
+               "[212.240.95.",
33689
 
+               "[213.47.250.139", "[213.225.61.",
33690
 
+               "[216.22.79.","[216.39.115.","[216.99.240.",
33691
 
+               "[216.126.32.", "[216.187.123.","[217.36.124.53",
33692
 
+               "[218.145.25","[218.52.71.103","[218.158.136.115",
33693
 
+               "[218.160.42.74", "[218.242.112.4]"
33694
 
+             ],
33695
 
+
33696
 
+      # Blacklisted SpamAssassin flags
33697
 
+      header :contains ["SPAM", "X-Spam-hits"]
33698
 
+             ["ADDRESSES_ON_CD","ACT_NOW","ADULT_SITE", "ALL_CAP_PORN",
33699
 
+              "AMATEUR_PORN", "AS_SEEN_ON",
33700
 
+              "BAD_CREDIT", "BALANCE_FOR_LONG_20K", "BARELY_LEGAL", "BEEN_TURNED_DOWN",
33701
 
+              "BANG_GUARANTEE", "BANG_MONEY","BASE64_ENC_TEXT",
33702
 
+              "BAYES_99","BAYES_90",
33703
 
+              "BE_BOSS", "BEST_PORN", "BULK_EMAIL",
33704
 
+              "CASINO", "CONSOLIDATE_DEBT", "COPY_ACCURATELY", "COPY_DVD",
33705
 
+              "DIET", "DO_IT_TODAY","DOMAIN_4U2",
33706
 
+              "EMAIL_MARKETING","EMAIL_ROT13", "EXPECT_TO_EARN","EARN_MONEY",
33707
 
+              "FIND_ANYTHING", "FORGED_AOL_RCVD",
33708
 
+              "FORGED_HOTMAIL_RCVD", "FORGED_YAHOO_RCVD",
33709
 
+              "FORGED_RCVD_TRAIL", "FORGED_JUNO_RCVD",
33710
 
+              "FORGED_MUA_",
33711
 
+              "FREE_MONEY","FREE_PORN",
33712
 
+              "GENTLE_FEROCITY", "GET_PAID", "GUARANTEED_STUFF", "GUARANTEED_100_PERCENT",
33713
 
+              "HAIR_LOSS", "HIDDEN_ASSETS", "HGH,", "HOME_EMPLOYMENT","HOT_NASTY","HTTP_ESCAPED_HOST",
33714
 
+              "HTTP_USERNAME_USED","HTML_FONT_INVISIBLE",
33715
 
+              "IMPOTENCE","INVALID_MSGID","INVESTMENT",
33716
 
+              "LESBIAN","LIVE_PORN","LOSE_POUNDS",
33717
 
+              "MARKETING_PARTNERS", "MORTGAGE_OBFU", "MORTGAGE_RATES",
33718
 
+              "NIGERIAN_SCAM", "NIGERIAN_TRANSACTION_1", "NIGERIAN_BODY", "NUMERIC_HTTP_ADDR",
33719
 
+              "NO_MX_FOR_FROM","NO_DNS_FOR_FROM",
33720
 
+              "OBFUSCATING_COMMENT", "ONLINE_PHARMACY",
33721
 
+              "PENIS_ENLARGE",
33722
 
+              "PREST_NON_ACCREDITED", "PURE_PROFIT","PORN_4",
33723
 
+              "RCVD_IN_DSBL", "RCVD_IN_OSIRUSOFT_COM","RCVD_IN_BL_SPAMCOP_NET", "RCVD_IN_SBL",
33724
 
+              "RCVD_IN_MULTIHOP_DSBL", "RCVD_IN_RELAYS_ORDB_ORG", "RCVD_IN_UNCONFIRMED_DSBL",
33725
 
+              "RCVD_FAKE_HELO_DOTCOM", "RCVD_IN_RFCI", "RCVD_IN_NJABL","RCVD_IN_SORBS",
33726
 
+              "REFINANCE", "REVERSE_AGING",
33727
 
+              "SAVE_ON_INSURANCE","SPAM_REDIRECTOR", "STOCK_ALERT", "STOCK_PICK", "STRONG_BUY",
33728
 
+              "SEE_FOR_YOURSELF", "SUPPLIES_LIMITED",
33729
 
+              "THE_BEST_RATE","TONER",
33730
 
+              "UNSECURED_CREDIT",
33731
 
+              "VACATION_SCAM", "VIAGRA", "VJESTIKA",
33732
 
+              "WHILE_SUPPLIES", "WORK_AT_HOME",
33733
 
+              "X_OSIRU_DUL", "X_OSIRU_SPAMWARE_SITE", "X_OSIRU_SPAM_SRC"
33734
 
+             ],
33735
 
+
33736
 
+
33737
 
+      # Blacklisted subjects
33738
 
+
33739
 
+      header :contains ["From","Subject"]
33740
 
+             [" penis ",
33741
 
+              "ADV:", "adult dvd", "adult movie", "adultdirect", "adultemail",
33742
 
+              "background check", "bankrupt", "boobs", "business opportunity","big@boss.com",
33743
 
+              "casino", "cash guarantee",
33744
 
+              "debt free", "diet bread", "ebay secrets", "erection",
33745
 
+              "financial freedom", "free credit",
33746
 
+              "gambl", "gov grants", "jackpot",
33747
 
+              "life insurance", "lottery", "lotto",
33748
 
+              "mortgage", "nude", "OTCBB",
33749
 
+              "penis", "porn", "promotion", "proven System",
33750
 
+              " rape ",
33751
 
+              " sex ", "skin resurfacing", "special offer",
33752
 
+              "ultimate software", "viagra", "V1AGRA", "vivatrim",
33753
 
+              "win money","work from home", "xxx"
33754
 
+             ],
33755
 
+
33756
 
+      # often spam emails to multiple addresses with same name & different domain
33757
 
+      header :matches ["To","CC"]
33758
 
+             ["*fastmail*fastmail*fastmail*fastmail*fastmail*"],
33759
 
+
33760
 
+      # Almost all emails from these domains is spam (at least for me)
33761
 
+      header :contains ["from", "received"]
33762
 
+                       [".ru ",".jp ", ".kr ", ".pt ",".pl ",".at ",".cz ",
33763
 
+                        ".ru>",".jp>", ".kr>", ".pt>", ".pl>",".at>",".cz>"],
33764
 
+
33765
 
+      # Really high SpamAssassin scores (15.0+)
33766
 
+      header :matches ["X-Spam-score","X-Remote-Spam-score"] [
33767
 
+          "1?.?", "2?.?", "3?.?", "4?.?", "5?.?", "6?.?"     # 10.0 to 69.9
33768
 
+      ]
33769
 
+) {
33770
 
+      fileinto "INBOX.Spam.discard";
33771
 
+      stop;
33772
 
+}
33773
 
diff -urN dovecot-1.2.4/dovecot-libsieve/examples/sieve_examples.sieve dovecot-1.2.4.debian/dovecot-libsieve/examples/sieve_examples.sieve
33774
 
--- dovecot-1.2.4/dovecot-libsieve/examples/sieve_examples.sieve        1970-01-01 01:00:00.000000000 +0100
33775
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/examples/sieve_examples.sieve 2008-10-04 10:41:25.000000000 +0200
33776
 
@@ -0,0 +1,73 @@
33777
 
+# Example Sieve Script
33778
 
+#   Author: unknown
33779
 
+#   URL: http://wiki.fastmail.fm/index.php?title=MoreSieveExamples
33780
 
+
33781
 
+require ["fileinto", "reject"];
33782
 
+
33783
 
+###BYPASSES###
33784
 
+
33785
 
+if anyof (
33786
 
+              header :contains ["From"] "friend1",
33787
 
+              header :contains ["From"] "friend12",
33788
 
+              header :contains ["From"] "friend3",
33789
 
+              header :contains ["From"] "friendsdomanin",
33790
 
+              header :contains ["Subject"] "elephant"  ##a safeword
33791
 
+         )
33792
 
+             {
33793
 
+                   fileinto "INBOX";
33794
 
+                   stop;
33795
 
+             }
33796
 
+
33797
 
+###BIG MESSAGE PROTECTION
33798
 
+if size :over 5000K {
33799
 
+         reject "Message over 5MB size limit.  Please contact me before sending this.";
33800
 
+}
33801
 
+
33802
 
+##SPAM FILTERING##
33803
 
+if header :contains ["X-Spam"] "high" {
33804
 
+      discard;
33805
 
+      stop;
33806
 
+}
33807
 
+if header :contains ["X-Spam-Flag"] "HIGH" {
33808
 
+      discard;
33809
 
+      stop;
33810
 
+}
33811
 
+if header :contains ["X-Spam"] "spam" {
33812
 
+      fileinto "INBOX.spam";  #emails forwarded from my unviersity account get SA tagged like this
33813
 
+      stop;
33814
 
+}
33815
 
+if header :contains ["X-Spam-Flag"] "YES" {
33816
 
+      fileinto "INBOX.spam";
33817
 
+      stop;
33818
 
+}
33819
 
+
33820
 
+####LOCAL SPAM RULES#######
33821
 
+if header :contains ["From"]  "bannerport" { discard; stop; }  ##keyword filters for when SA doesn't quite catch them
33822
 
+if header :contains ["To"]  "MATT NOONE" { discard; stop; }
33823
 
+###AUTO management rules###
33824
 
+
33825
 
+####Student Digest stuff#### ###   Examples of boolean OR rules
33826
 
+if anyof (
33827
 
+            header :contains ["X-BeenThere"] "student-digest@list.xxx.edu",
33828
 
+            header :contains ["X-BeenThere"] "firstyear-digest@list.xxx.edu",
33829
 
+            header :contains ["X-BeenThere"] "secondyear-digest@list.xxx.edu",
33830
 
+            header :contains ["X-BeenThere"] "thirdyear-digest@list.xxx.edu",
33831
 
+            header :contains ["X-BeenThere"] "fourthyear-digest@list.xxx.edu"
33832
 
+         )
33833
 
+         {
33834
 
+            fileinto "INBOX.lists.digests";
33835
 
+            stop;
33836
 
+         }
33837
 
+if allof (   ###A Boolean AND rule
33838
 
+            header :contains ["From"] "buddy1",
33839
 
+            header :contains ["To"]   "myotheraddress"
33840
 
+         )
33841
 
+         {
33842
 
+            fileinto "INBOX.scc.annoy";
33843
 
+            stop;
33844
 
+         }
33845
 
+
33846
 
+#other local rules
33847
 
+if header :contains ["Subject"]  "helmreich" { fileinto "INBOX.lists.helmreich"; stop; }
33848
 
+if header :contains ["Subject"]  "helmcomm" { fileinto "INBOX.lists.helmreich"; stop; }
33849
 
+if header :contains ["Subject"]  "packeteer" { fileinto "INBOX.lists"; stop; }
33850
 
Binary files dovecot-1.2.4/dovecot-libsieve/examples/sieve_examples.svbin and dovecot-1.2.4.debian/dovecot-libsieve/examples/sieve_examples.svbin differ
33851
 
diff -urN dovecot-1.2.4/dovecot-libsieve/examples/subaddress.rfc5233.sieve dovecot-1.2.4.debian/dovecot-libsieve/examples/subaddress.rfc5233.sieve
33852
 
--- dovecot-1.2.4/dovecot-libsieve/examples/subaddress.rfc5233.sieve    1970-01-01 01:00:00.000000000 +0100
33853
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/examples/subaddress.rfc5233.sieve     2008-10-04 10:41:25.000000000 +0200
33854
 
@@ -0,0 +1,23 @@
33855
 
+require ["envelope", "subaddress", "fileinto"];
33856
 
+
33857
 
+# In this example the same user account receives mail for both
33858
 
+# "ken@example.com" and "postmaster@example.com"
33859
 
+
33860
 
+# File all messages to postmaster into a single mailbox,
33861
 
+# ignoring the :detail part.
33862
 
+if envelope :user "to" "postmaster" {
33863
 
+       fileinto "inbox.postmaster";
33864
 
+       stop;
33865
 
+}
33866
 
+
33867
 
+# File mailing list messages (subscribed as "ken+mta-filters").
33868
 
+if envelope :detail "to" "mta-filters" {
33869
 
+       fileinto "inbox.ietf-mta-filters";
33870
 
+}
33871
 
+
33872
 
+# Redirect all mail sent to "ken+foo".
33873
 
+if envelope :detail "to" "foo" {
33874
 
+       redirect "ken@example.net";
33875
 
+}
33876
 
+
33877
 
+
33878
 
Binary files dovecot-1.2.4/dovecot-libsieve/examples/subaddress.rfc5233.svbin and dovecot-1.2.4.debian/dovecot-libsieve/examples/subaddress.rfc5233.svbin differ
33879
 
diff -urN dovecot-1.2.4/dovecot-libsieve/examples/vacation.sieve dovecot-1.2.4.debian/dovecot-libsieve/examples/vacation.sieve
33880
 
--- dovecot-1.2.4/dovecot-libsieve/examples/vacation.sieve      1970-01-01 01:00:00.000000000 +0100
33881
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/examples/vacation.sieve       2008-10-04 10:41:25.000000000 +0200
33882
 
@@ -0,0 +1,23 @@
33883
 
+require ["fileinto","reject", "vacation"];
33884
 
+if allof (header :contains  "X-Spam-Flag" "YES") 
33885
 
+{
33886
 
+    discard ;
33887
 
+}
33888
 
+
33889
 
+elsif allof (header :contains "subject" "<quation>") 
33890
 
+{
33891
 
+vacation 
33892
 
+:addresses "<name@domain.ru>"
33893
 
+:subject "<Answear>" 
33894
 
+:mime "MIME-Version: 1.0
33895
 
+Content-Type: text/html; charset=KOI8-R
33896
 
+Content-Transfer-Encoding: 7bit
33897
 
+<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">
33898
 
+<HTML><HEAD><META http-equiv=Content-Type content=\"text/html; charset=windows-KOI8-R\">
33899
 
+</HEAD><BODY>123</BODY></HTML>";
33900
 
+ discard ;
33901
 
+}
33902
 
+else 
33903
 
+{
33904
 
+     keep;
33905
 
+}
33906
 
Binary files dovecot-1.2.4/dovecot-libsieve/examples/vacation.svbin and dovecot-1.2.4.debian/dovecot-libsieve/examples/vacation.svbin differ
33907
 
diff -urN dovecot-1.2.4/dovecot-libsieve/examples/vivil.sieve dovecot-1.2.4.debian/dovecot-libsieve/examples/vivil.sieve
33908
 
--- dovecot-1.2.4/dovecot-libsieve/examples/vivil.sieve 1970-01-01 01:00:00.000000000 +0100
33909
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/examples/vivil.sieve  2008-10-04 10:41:25.000000000 +0200
33910
 
@@ -0,0 +1,94 @@
33911
 
+# Example Sieve Script
33912
 
+#   Author: Vivil
33913
 
+#   URL: http://wiki.fastmail.fm/index.php?title=Vivil
33914
 
+#   Removed unused notify require
33915
 
+
33916
 
+# *************************************************************************
33917
 
+require ["envelope", "fileinto", "reject", "vacation", "regex", "relational", 
33918
 
+"comparator-i;ascii-numeric"];
33919
 
+
33920
 
+
33921
 
+if size :over 2048K {
33922
 
+  reject "Message not delivered; size over limit accepted by recipient";
33923
 
+  stop;  
33924
 
+}
33925
 
+
33926
 
+#because of the use of elsif below, none of the "stop;"'s below are needed, but they're good 'defensive programming'. Only the one above is actually needed.
33927
 
+
33928
 
+redirect "login@gmail.dom";
33929
 
+
33930
 
+if header :contains ["from","cc"]
33931
 
+[
33932
 
+  "from-begin@beginbeginbeginbeginbeginbeginbeginbeginbegin.fr",
33933
 
+  "sex.com newsletter",
33934
 
+  "ad@gator.com",
33935
 
+  "newsletter@takecareof.com",
33936
 
+  "from-end@endendendendendendendendendendendendendendendend.fr"
33937
 
+]
33938
 
+{
33939
 
+  discard;
33940
 
+  stop;
33941
 
+}
33942
 
+
33943
 
+elsif header :contains ["from"]
33944
 
+[
33945
 
+  "mygirlfriend-who-use-incredimail@foo.dom"
33946
 
+]
33947
 
+{
33948
 
+  fileinto "INBOX.PRIORITY";
33949
 
+  stop;
33950
 
+}
33951
 
+
33952
 
+#use of "to" field detection next lines is ONLY USEFUL FOR DOMAIN NAME OWNERS if you forward your mail to your fastmail account, some virus/spam send mail to well known addresses as info@willemijns.dom i never use...
33953
 
+
33954
 
+elsif header :contains ["to","cc"]
33955
 
+[
33956
 
+  "to-begin@beginbeginbeginbeginbeginbeginbeginbeginbegin.fr",
33957
 
+  "FTPsebastien@willemijns.dom",
33958
 
+  "info@willemijns.dom",
33959
 
+  "webmaster@willemijns.dom",
33960
 
+  "to-end@endendendendendendendendendendendendendendendend.fr"
33961
 
+]
33962
 
+{
33963
 
+  discard;
33964
 
+  stop;
33965
 
+}
33966
 
+
33967
 
+elsif header :contains ["subject"]
33968
 
+[
33969
 
+  "subject-begin@beginbeginbeginbeginbeginbeginbeginbeginbegin.fr",
33970
 
+  "Undeliverable mail: Registration is accepted",
33971
 
+  "subject-end@endendendendendendendendendendendendendendendend.fr"
33972
 
+]
33973
 
+{
33974
 
+  discard;
33975
 
+  stop;
33976
 
+}
33977
 
+elsif header :value "ge" :comparator "i;ascii-numeric" ["X-Spam-score"] ["6"]  {
33978
 
+  fileinto "INBOX.Junk Mail";
33979
 
+  stop;
33980
 
+}
33981
 
+elsif header :contains "from" "reflector@launay.dom" {
33982
 
+  fileinto "INBOX.TEST";
33983
 
+  stop;
33984
 
+}
33985
 
+elsif header :contains "from" "do-not-reply@franconews.dom" {
33986
 
+  fileinto "INBOX.TEST";
33987
 
+  stop;
33988
 
+}
33989
 
+elsif header :contains "from" "devnull@news.telefonica.dom" {
33990
 
+  fileinto "INBOX.TEST";
33991
 
+  stop;
33992
 
+}
33993
 
+elsif header :contains ["to"] ["sebastien@willemijns.dom"] {
33994
 
+  fileinto "INBOX.PRIORITY";
33995
 
+  stop;
33996
 
+}
33997
 
+elsif header :contains ["to"] ["seb@willemijns.dom"] {
33998
 
+  fileinto "INBOX.PRIORITY";
33999
 
+  stop;
34000
 
+}
34001
 
+else {
34002
 
+  fileinto "INBOX";
34003
 
+}
34004
 
+# ********************************************************************
34005
 
Binary files dovecot-1.2.4/dovecot-libsieve/examples/vivil.svbin and dovecot-1.2.4.debian/dovecot-libsieve/examples/vivil.svbin differ
34006
 
diff -urN dovecot-1.2.4/dovecot-libsieve/INSTALL dovecot-1.2.4.debian/dovecot-libsieve/INSTALL
34007
 
--- dovecot-1.2.4/dovecot-libsieve/INSTALL      1970-01-01 01:00:00.000000000 +0100
34008
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/INSTALL       2009-07-05 18:23:47.000000000 +0200
34009
 
@@ -0,0 +1,125 @@
34010
 
+Compiling
34011
 
+---------
34012
 
+
34013
 
+First of all you'll need to have pre-built Dovecot 1.2 sources available. It's 
34014
 
+also not a good idea to build the plugin against self-compiled Dovecot sources, 
34015
 
+but then actually use a prebuilt binary package of Dovecot. That might work if 
34016
 
+the Dovecot versions are the same, but it's not guaranteed. You can also use 
34017
 
+installed Dovecot headers to compile this package, but then command line tools 
34018
 
+like sievec and sieved will not be compiled. This is also true for the test 
34019
 
+suite. 
34020
 
+
34021
 
+This package is compiled and configured as follows:
34022
 
+
34023
 
+./configure --with-dovecot=../dovecot-1.2
34024
 
+make
34025
 
+sudo make install
34026
 
+
34027
 
+The --with-dovecot parameter points to your Dovecot sources or, in case you are 
34028
 
+compiling against the headers, to the directory where the dovecot-config file is 
34029
 
+installed.
34030
 
+
34031
 
+If you downloaded this package through Mercurial, you need to execute 
34032
 
+./autogen.sh first to build the automake/autoconf structure. This requires
34033
 
+autotools and libtool to be installed. 
34034
 
+
34035
 
+Configuring
34036
 
+-----------
34037
 
+
34038
 
+Configuration is currently mostly identical to the cmusieve module. However, the 
34039
 
+name of the module is 'sieve' and not 'cmusieve'. For a detailed description on 
34040
 
+installing the cmusieve plugin for deliver refer to the dovecot wiki:
34041
 
+
34042
 
+http://wiki.dovecot.org/LDA/Sieve
34043
 
+
34044
 
+The following options for the plugin section of the Dovecot config file are new
34045
 
+when compared to the old CMU Sieve:
34046
 
+
34047
 
+  sieve_extensions = 
34048
 
+
34049
 
+    Use this setting to specify which Sieve language extensions are available 
34050
 
+    to users. By default, all supported extensions are available, but some 
34051
 
+    system administrators may want to disable certain Sieve extensions. 
34052
 
+
34053
 
+  sieve_before = 
34054
 
+  sieve_after =
34055
 
+
34056
 
+    This Sieve implementation allows executing multiple Sieve scripts 
34057
 
+    sequentially. These two options are used to specify what scripts need to
34058
 
+    be executed before and after the user's script (as specified by the sieve
34059
 
+    option). These settings allow specifying only one path each. However, if 
34060
 
+    the path leads to a directory, all the Sieve scripts contained therein are 
34061
 
+    executed. The order of execution is determined by the file names, using 
34062
 
+    a normal 8bit per-character comparison.
34063
 
+
34064
 
+    After one script terminates, the next script is executed if an implicit or 
34065
 
+    explicit "keep" is in effect. Thus, to end all script execution, a script 
34066
 
+    must not execute keep and it must cancel the implicit keep, e.g. by
34067
 
+    executing `discard; stop;'. Keep in mind that `fileinto "INBOX"' is not 
34068
 
+    the same as a keep action in this context (only for the last script).
34069
 
+
34070
 
+    Just as for executing a single script the normal way, this implementation 
34071
 
+    takes care never to duplicate deliveries, forwards or responses. When 
34072
 
+    vacation actions are executed multiple times in different scripts, the 
34073
 
+    usual error is not triggered: the subsequent duplicate vacation actions 
34074
 
+    are simply discarded.
34075
 
+
34076
 
+    Apart from the keep action, all actions triggered in a script in the
34077
 
+    sequence are executed before continuing to the next script. This means 
34078
 
+    that when a script in the sequence encounters an error, actions from
34079
 
+    preceeding scripts are not affected. The sequence is broken however, 
34080
 
+    meaning that the script execution of the offending script is aborted and
34081
 
+    no further scripts are executed. An implicit keep is executed in stead.
34082
 
+
34083
 
+  sieve_subaddress_sep = +
34084
 
+
34085
 
+    This setting specifies what separator is used between the :user and :detail 
34086
 
+    address parts introduced by the subaddress extension. This may also be a 
34087
 
+    sequence of characters (e.g. '--'). The current implementation looks for
34088
 
+    the separator from the left of the localpart and uses the first one 
34089
 
+    encountered. The :user part is left of the separator and the :detail part 
34090
 
+    is right. 
34091
 
+    
34092
 
+For example:
34093
 
+
34094
 
+# ...
34095
 
+
34096
 
+protocol lda {
34097
 
+  postmaster_address = postmaster@example.com
34098
 
+
34099
 
+  mail_plugins = sieve
34100
 
+
34101
 
+  # ... 
34102
 
+}
34103
 
+
34104
 
+plugin {
34105
 
+   # The user's own script
34106
 
+   sieve = ~/.dovecot.sieve
34107
 
+
34108
 
+   # Global script if user has none
34109
 
+   #   If this is omitted, Sieve processing is skipped when the user has no 
34110
 
+   #   script of his own. This includes multiscript
34111
 
+   sieve_global_path = /etc/dovecot/sieve.global/default.sieve
34112
 
+
34113
 
+   # Scripts executed before the user's script.
34114
 
+   #   E.g. handling messages marked as dangerous
34115
 
+   sieve_before = /etc/dovecot/sieve.global/discard-virusses.sieve
34116
 
+
34117
 
+   # Scripts executed after the user's script (if keep is still in effect)
34118
 
+   #   E.g. default mail filing rules.  
34119
 
+   sieve_after = /etc/dovecot/sieve.d/
34120
 
+}
34121
 
+
34122
 
+Test Suite
34123
 
+----------
34124
 
+
34125
 
+This package includes a test suite to verify the basic processing of the Sieve
34126
 
+interpreter on your particular platform. Note that the test suite is not 
34127
 
+available when this package is compiled against the Dovecot headers only. The 
34128
 
+test suite executes a list of test cases and halts when one of them fails. If it 
34129
 
+executes all test cases successfully, the test suite finishes. You can execute 
34130
 
+the test suite using `make test`. 
34131
 
+
34132
 
+A failing test case is always a bug and a report is greatly appreciated.
34133
 
+
34134
 
+
34135
 
diff -urN dovecot-1.2.4/dovecot-libsieve/install-sh dovecot-1.2.4.debian/dovecot-libsieve/install-sh
34136
 
--- dovecot-1.2.4/dovecot-libsieve/install-sh   1970-01-01 01:00:00.000000000 +0100
34137
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/install-sh    2008-07-18 12:31:10.000000000 +0200
34138
 
@@ -0,0 +1,519 @@
34139
 
+#!/bin/sh
34140
 
+# install - install a program, script, or datafile
34141
 
+
34142
 
+scriptversion=2006-12-25.00
34143
 
+
34144
 
+# This originates from X11R5 (mit/util/scripts/install.sh), which was
34145
 
+# later released in X11R6 (xc/config/util/install.sh) with the
34146
 
+# following copyright and license.
34147
 
+#
34148
 
+# Copyright (C) 1994 X Consortium
34149
 
+#
34150
 
+# Permission is hereby granted, free of charge, to any person obtaining a copy
34151
 
+# of this software and associated documentation files (the "Software"), to
34152
 
+# deal in the Software without restriction, including without limitation the
34153
 
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
34154
 
+# sell copies of the Software, and to permit persons to whom the Software is
34155
 
+# furnished to do so, subject to the following conditions:
34156
 
+#
34157
 
+# The above copyright notice and this permission notice shall be included in
34158
 
+# all copies or substantial portions of the Software.
34159
 
+#
34160
 
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
34161
 
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
34162
 
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
34163
 
+# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
34164
 
+# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
34165
 
+# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34166
 
+#
34167
 
+# Except as contained in this notice, the name of the X Consortium shall not
34168
 
+# be used in advertising or otherwise to promote the sale, use or other deal-
34169
 
+# ings in this Software without prior written authorization from the X Consor-
34170
 
+# tium.
34171
 
+#
34172
 
+#
34173
 
+# FSF changes to this file are in the public domain.
34174
 
+#
34175
 
+# Calling this script install-sh is preferred over install.sh, to prevent
34176
 
+# `make' implicit rules from creating a file called install from it
34177
 
+# when there is no Makefile.
34178
 
+#
34179
 
+# This script is compatible with the BSD install script, but was written
34180
 
+# from scratch.
34181
 
+
34182
 
+nl='
34183
 
+'
34184
 
+IFS=" ""       $nl"
34185
 
+
34186
 
+# set DOITPROG to echo to test this script
34187
 
+
34188
 
+# Don't use :- since 4.3BSD and earlier shells don't like it.
34189
 
+doit=${DOITPROG-}
34190
 
+if test -z "$doit"; then
34191
 
+  doit_exec=exec
34192
 
+else
34193
 
+  doit_exec=$doit
34194
 
+fi
34195
 
+
34196
 
+# Put in absolute file names if you don't have them in your path;
34197
 
+# or use environment vars.
34198
 
+
34199
 
+chgrpprog=${CHGRPPROG-chgrp}
34200
 
+chmodprog=${CHMODPROG-chmod}
34201
 
+chownprog=${CHOWNPROG-chown}
34202
 
+cmpprog=${CMPPROG-cmp}
34203
 
+cpprog=${CPPROG-cp}
34204
 
+mkdirprog=${MKDIRPROG-mkdir}
34205
 
+mvprog=${MVPROG-mv}
34206
 
+rmprog=${RMPROG-rm}
34207
 
+stripprog=${STRIPPROG-strip}
34208
 
+
34209
 
+posix_glob='?'
34210
 
+initialize_posix_glob='
34211
 
+  test "$posix_glob" != "?" || {
34212
 
+    if (set -f) 2>/dev/null; then
34213
 
+      posix_glob=
34214
 
+    else
34215
 
+      posix_glob=:
34216
 
+    fi
34217
 
+  }
34218
 
+'
34219
 
+
34220
 
+posix_mkdir=
34221
 
+
34222
 
+# Desired mode of installed file.
34223
 
+mode=0755
34224
 
+
34225
 
+chgrpcmd=
34226
 
+chmodcmd=$chmodprog
34227
 
+chowncmd=
34228
 
+mvcmd=$mvprog
34229
 
+rmcmd="$rmprog -f"
34230
 
+stripcmd=
34231
 
+
34232
 
+src=
34233
 
+dst=
34234
 
+dir_arg=
34235
 
+dst_arg=
34236
 
+
34237
 
+copy_on_change=false
34238
 
+no_target_directory=
34239
 
+
34240
 
+usage="\
34241
 
+Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
34242
 
+   or: $0 [OPTION]... SRCFILES... DIRECTORY
34243
 
+   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
34244
 
+   or: $0 [OPTION]... -d DIRECTORIES...
34245
 
+
34246
 
+In the 1st form, copy SRCFILE to DSTFILE.
34247
 
+In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
34248
 
+In the 4th, create DIRECTORIES.
34249
 
+
34250
 
+Options:
34251
 
+     --help     display this help and exit.
34252
 
+     --version  display version info and exit.
34253
 
+
34254
 
+  -c            (ignored)
34255
 
+  -C            install only if different (preserve the last data modification time)
34256
 
+  -d            create directories instead of installing files.
34257
 
+  -g GROUP      $chgrpprog installed files to GROUP.
34258
 
+  -m MODE       $chmodprog installed files to MODE.
34259
 
+  -o USER       $chownprog installed files to USER.
34260
 
+  -s            $stripprog installed files.
34261
 
+  -t DIRECTORY  install into DIRECTORY.
34262
 
+  -T            report an error if DSTFILE is a directory.
34263
 
+
34264
 
+Environment variables override the default commands:
34265
 
+  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
34266
 
+  RMPROG STRIPPROG
34267
 
+"
34268
 
+
34269
 
+while test $# -ne 0; do
34270
 
+  case $1 in
34271
 
+    -c) ;;
34272
 
+
34273
 
+    -C) copy_on_change=true;;
34274
 
+
34275
 
+    -d) dir_arg=true;;
34276
 
+
34277
 
+    -g) chgrpcmd="$chgrpprog $2"
34278
 
+       shift;;
34279
 
+
34280
 
+    --help) echo "$usage"; exit $?;;
34281
 
+
34282
 
+    -m) mode=$2
34283
 
+       case $mode in
34284
 
+         *' '* | *'    '* | *'
34285
 
+'*       | *'*'* | *'?'* | *'['*)
34286
 
+           echo "$0: invalid mode: $mode" >&2
34287
 
+           exit 1;;
34288
 
+       esac
34289
 
+       shift;;
34290
 
+
34291
 
+    -o) chowncmd="$chownprog $2"
34292
 
+       shift;;
34293
 
+
34294
 
+    -s) stripcmd=$stripprog;;
34295
 
+
34296
 
+    -t) dst_arg=$2
34297
 
+       shift;;
34298
 
+
34299
 
+    -T) no_target_directory=true;;
34300
 
+
34301
 
+    --version) echo "$0 $scriptversion"; exit $?;;
34302
 
+
34303
 
+    --)        shift
34304
 
+       break;;
34305
 
+
34306
 
+    -*)        echo "$0: invalid option: $1" >&2
34307
 
+       exit 1;;
34308
 
+
34309
 
+    *)  break;;
34310
 
+  esac
34311
 
+  shift
34312
 
+done
34313
 
+
34314
 
+if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
34315
 
+  # When -d is used, all remaining arguments are directories to create.
34316
 
+  # When -t is used, the destination is already specified.
34317
 
+  # Otherwise, the last argument is the destination.  Remove it from $@.
34318
 
+  for arg
34319
 
+  do
34320
 
+    if test -n "$dst_arg"; then
34321
 
+      # $@ is not empty: it contains at least $arg.
34322
 
+      set fnord "$@" "$dst_arg"
34323
 
+      shift # fnord
34324
 
+    fi
34325
 
+    shift # arg
34326
 
+    dst_arg=$arg
34327
 
+  done
34328
 
+fi
34329
 
+
34330
 
+if test $# -eq 0; then
34331
 
+  if test -z "$dir_arg"; then
34332
 
+    echo "$0: no input file specified." >&2
34333
 
+    exit 1
34334
 
+  fi
34335
 
+  # It's OK to call `install-sh -d' without argument.
34336
 
+  # This can happen when creating conditional directories.
34337
 
+  exit 0
34338
 
+fi
34339
 
+
34340
 
+if test -z "$dir_arg"; then
34341
 
+  trap '(exit $?); exit' 1 2 13 15
34342
 
+
34343
 
+  # Set umask so as not to create temps with too-generous modes.
34344
 
+  # However, 'strip' requires both read and write access to temps.
34345
 
+  case $mode in
34346
 
+    # Optimize common cases.
34347
 
+    *644) cp_umask=133;;
34348
 
+    *755) cp_umask=22;;
34349
 
+
34350
 
+    *[0-7])
34351
 
+      if test -z "$stripcmd"; then
34352
 
+       u_plus_rw=
34353
 
+      else
34354
 
+       u_plus_rw='% 200'
34355
 
+      fi
34356
 
+      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
34357
 
+    *)
34358
 
+      if test -z "$stripcmd"; then
34359
 
+       u_plus_rw=
34360
 
+      else
34361
 
+       u_plus_rw=,u+rw
34362
 
+      fi
34363
 
+      cp_umask=$mode$u_plus_rw;;
34364
 
+  esac
34365
 
+fi
34366
 
+
34367
 
+for src
34368
 
+do
34369
 
+  # Protect names starting with `-'.
34370
 
+  case $src in
34371
 
+    -*) src=./$src;;
34372
 
+  esac
34373
 
+
34374
 
+  if test -n "$dir_arg"; then
34375
 
+    dst=$src
34376
 
+    dstdir=$dst
34377
 
+    test -d "$dstdir"
34378
 
+    dstdir_status=$?
34379
 
+  else
34380
 
+
34381
 
+    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
34382
 
+    # might cause directories to be created, which would be especially bad
34383
 
+    # if $src (and thus $dsttmp) contains '*'.
34384
 
+    if test ! -f "$src" && test ! -d "$src"; then
34385
 
+      echo "$0: $src does not exist." >&2
34386
 
+      exit 1
34387
 
+    fi
34388
 
+
34389
 
+    if test -z "$dst_arg"; then
34390
 
+      echo "$0: no destination specified." >&2
34391
 
+      exit 1
34392
 
+    fi
34393
 
+
34394
 
+    dst=$dst_arg
34395
 
+    # Protect names starting with `-'.
34396
 
+    case $dst in
34397
 
+      -*) dst=./$dst;;
34398
 
+    esac
34399
 
+
34400
 
+    # If destination is a directory, append the input filename; won't work
34401
 
+    # if double slashes aren't ignored.
34402
 
+    if test -d "$dst"; then
34403
 
+      if test -n "$no_target_directory"; then
34404
 
+       echo "$0: $dst_arg: Is a directory" >&2
34405
 
+       exit 1
34406
 
+      fi
34407
 
+      dstdir=$dst
34408
 
+      dst=$dstdir/`basename "$src"`
34409
 
+      dstdir_status=0
34410
 
+    else
34411
 
+      # Prefer dirname, but fall back on a substitute if dirname fails.
34412
 
+      dstdir=`
34413
 
+       (dirname "$dst") 2>/dev/null ||
34414
 
+       expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
34415
 
+            X"$dst" : 'X\(//\)[^/]' \| \
34416
 
+            X"$dst" : 'X\(//\)$' \| \
34417
 
+            X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
34418
 
+       echo X"$dst" |
34419
 
+           sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
34420
 
+                  s//\1/
34421
 
+                  q
34422
 
+                }
34423
 
+                /^X\(\/\/\)[^/].*/{
34424
 
+                  s//\1/
34425
 
+                  q
34426
 
+                }
34427
 
+                /^X\(\/\/\)$/{
34428
 
+                  s//\1/
34429
 
+                  q
34430
 
+                }
34431
 
+                /^X\(\/\).*/{
34432
 
+                  s//\1/
34433
 
+                  q
34434
 
+                }
34435
 
+                s/.*/./; q'
34436
 
+      `
34437
 
+
34438
 
+      test -d "$dstdir"
34439
 
+      dstdir_status=$?
34440
 
+    fi
34441
 
+  fi
34442
 
+
34443
 
+  obsolete_mkdir_used=false
34444
 
+
34445
 
+  if test $dstdir_status != 0; then
34446
 
+    case $posix_mkdir in
34447
 
+      '')
34448
 
+       # Create intermediate dirs using mode 755 as modified by the umask.
34449
 
+       # This is like FreeBSD 'install' as of 1997-10-28.
34450
 
+       umask=`umask`
34451
 
+       case $stripcmd.$umask in
34452
 
+         # Optimize common cases.
34453
 
+         *[2367][2367]) mkdir_umask=$umask;;
34454
 
+         .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
34455
 
+
34456
 
+         *[0-7])
34457
 
+           mkdir_umask=`expr $umask + 22 \
34458
 
+             - $umask % 100 % 40 + $umask % 20 \
34459
 
+             - $umask % 10 % 4 + $umask % 2
34460
 
+           `;;
34461
 
+         *) mkdir_umask=$umask,go-w;;
34462
 
+       esac
34463
 
+
34464
 
+       # With -d, create the new directory with the user-specified mode.
34465
 
+       # Otherwise, rely on $mkdir_umask.
34466
 
+       if test -n "$dir_arg"; then
34467
 
+         mkdir_mode=-m$mode
34468
 
+       else
34469
 
+         mkdir_mode=
34470
 
+       fi
34471
 
+
34472
 
+       posix_mkdir=false
34473
 
+       case $umask in
34474
 
+         *[123567][0-7][0-7])
34475
 
+           # POSIX mkdir -p sets u+wx bits regardless of umask, which
34476
 
+           # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
34477
 
+           ;;
34478
 
+         *)
34479
 
+           tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
34480
 
+           trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
34481
 
+
34482
 
+           if (umask $mkdir_umask &&
34483
 
+               exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
34484
 
+           then
34485
 
+             if test -z "$dir_arg" || {
34486
 
+                  # Check for POSIX incompatibilities with -m.
34487
 
+                  # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
34488
 
+                  # other-writeable bit of parent directory when it shouldn't.
34489
 
+                  # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
34490
 
+                  ls_ld_tmpdir=`ls -ld "$tmpdir"`
34491
 
+                  case $ls_ld_tmpdir in
34492
 
+                    d????-?r-*) different_mode=700;;
34493
 
+                    d????-?--*) different_mode=755;;
34494
 
+                    *) false;;
34495
 
+                  esac &&
34496
 
+                  $mkdirprog -m$different_mode -p -- "$tmpdir" && {
34497
 
+                    ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
34498
 
+                    test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
34499
 
+                  }
34500
 
+                }
34501
 
+             then posix_mkdir=:
34502
 
+             fi
34503
 
+             rmdir "$tmpdir/d" "$tmpdir"
34504
 
+           else
34505
 
+             # Remove any dirs left behind by ancient mkdir implementations.
34506
 
+             rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
34507
 
+           fi
34508
 
+           trap '' 0;;
34509
 
+       esac;;
34510
 
+    esac
34511
 
+
34512
 
+    if
34513
 
+      $posix_mkdir && (
34514
 
+       umask $mkdir_umask &&
34515
 
+       $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
34516
 
+      )
34517
 
+    then :
34518
 
+    else
34519
 
+
34520
 
+      # The umask is ridiculous, or mkdir does not conform to POSIX,
34521
 
+      # or it failed possibly due to a race condition.  Create the
34522
 
+      # directory the slow way, step by step, checking for races as we go.
34523
 
+
34524
 
+      case $dstdir in
34525
 
+       /*) prefix='/';;
34526
 
+       -*) prefix='./';;
34527
 
+       *)  prefix='';;
34528
 
+      esac
34529
 
+
34530
 
+      eval "$initialize_posix_glob"
34531
 
+
34532
 
+      oIFS=$IFS
34533
 
+      IFS=/
34534
 
+      $posix_glob set -f
34535
 
+      set fnord $dstdir
34536
 
+      shift
34537
 
+      $posix_glob set +f
34538
 
+      IFS=$oIFS
34539
 
+
34540
 
+      prefixes=
34541
 
+
34542
 
+      for d
34543
 
+      do
34544
 
+       test -z "$d" && continue
34545
 
+
34546
 
+       prefix=$prefix$d
34547
 
+       if test -d "$prefix"; then
34548
 
+         prefixes=
34549
 
+       else
34550
 
+         if $posix_mkdir; then
34551
 
+           (umask=$mkdir_umask &&
34552
 
+            $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
34553
 
+           # Don't fail if two instances are running concurrently.
34554
 
+           test -d "$prefix" || exit 1
34555
 
+         else
34556
 
+           case $prefix in
34557
 
+             *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
34558
 
+             *) qprefix=$prefix;;
34559
 
+           esac
34560
 
+           prefixes="$prefixes '$qprefix'"
34561
 
+         fi
34562
 
+       fi
34563
 
+       prefix=$prefix/
34564
 
+      done
34565
 
+
34566
 
+      if test -n "$prefixes"; then
34567
 
+       # Don't fail if two instances are running concurrently.
34568
 
+       (umask $mkdir_umask &&
34569
 
+        eval "\$doit_exec \$mkdirprog $prefixes") ||
34570
 
+         test -d "$dstdir" || exit 1
34571
 
+       obsolete_mkdir_used=true
34572
 
+      fi
34573
 
+    fi
34574
 
+  fi
34575
 
+
34576
 
+  if test -n "$dir_arg"; then
34577
 
+    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
34578
 
+    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
34579
 
+    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
34580
 
+      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
34581
 
+  else
34582
 
+
34583
 
+    # Make a couple of temp file names in the proper directory.
34584
 
+    dsttmp=$dstdir/_inst.$$_
34585
 
+    rmtmp=$dstdir/_rm.$$_
34586
 
+
34587
 
+    # Trap to clean up those temp files at exit.
34588
 
+    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
34589
 
+
34590
 
+    # Copy the file name to the temp name.
34591
 
+    (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
34592
 
+
34593
 
+    # and set any options; do chmod last to preserve setuid bits.
34594
 
+    #
34595
 
+    # If any of these fail, we abort the whole thing.  If we want to
34596
 
+    # ignore errors from any of these, just make sure not to ignore
34597
 
+    # errors from the above "$doit $cpprog $src $dsttmp" command.
34598
 
+    #
34599
 
+    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
34600
 
+    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
34601
 
+    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
34602
 
+    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
34603
 
+
34604
 
+    # If -C, don't bother to copy if it wouldn't change the file.
34605
 
+    if $copy_on_change &&
34606
 
+       old=`LC_ALL=C ls -dlL "$dst"    2>/dev/null` &&
34607
 
+       new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
34608
 
+
34609
 
+       eval "$initialize_posix_glob" &&
34610
 
+       $posix_glob set -f &&
34611
 
+       set X $old && old=:$2:$4:$5:$6 &&
34612
 
+       set X $new && new=:$2:$4:$5:$6 &&
34613
 
+       $posix_glob set +f &&
34614
 
+
34615
 
+       test "$old" = "$new" &&
34616
 
+       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
34617
 
+    then
34618
 
+      rm -f "$dsttmp"
34619
 
+    else
34620
 
+      # Rename the file to the real destination.
34621
 
+      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
34622
 
+
34623
 
+      # The rename failed, perhaps because mv can't rename something else
34624
 
+      # to itself, or perhaps because mv is so ancient that it does not
34625
 
+      # support -f.
34626
 
+      {
34627
 
+       # Now remove or move aside any old file at destination location.
34628
 
+       # We try this two ways since rm can't unlink itself on some
34629
 
+       # systems and the destination file might be busy for other
34630
 
+       # reasons.  In this case, the final cleanup might fail but the new
34631
 
+       # file should still install successfully.
34632
 
+       {
34633
 
+         test ! -f "$dst" ||
34634
 
+         $doit $rmcmd -f "$dst" 2>/dev/null ||
34635
 
+         { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
34636
 
+           { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
34637
 
+         } ||
34638
 
+         { echo "$0: cannot unlink or rename $dst" >&2
34639
 
+           (exit 1); exit 1
34640
 
+         }
34641
 
+       } &&
34642
 
+
34643
 
+       # Now rename the file to the real destination.
34644
 
+       $doit $mvcmd "$dsttmp" "$dst"
34645
 
+      }
34646
 
+    fi || exit 1
34647
 
+
34648
 
+    trap '' 0
34649
 
+  fi
34650
 
+done
34651
 
+
34652
 
+# Local variables:
34653
 
+# eval: (add-hook 'write-file-hooks 'time-stamp)
34654
 
+# time-stamp-start: "scriptversion="
34655
 
+# time-stamp-format: "%:y-%02m-%02d.%02H"
34656
 
+# time-stamp-end: "$"
34657
 
+# End:
34658
 
diff -urN dovecot-1.2.4/dovecot-libsieve/ltmain.sh dovecot-1.2.4.debian/dovecot-libsieve/ltmain.sh
34659
 
--- dovecot-1.2.4/dovecot-libsieve/ltmain.sh    1970-01-01 01:00:00.000000000 +0100
34660
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/ltmain.sh     2009-09-02 07:31:47.000000000 +0200
34661
 
@@ -0,0 +1,8413 @@
34662
 
+# Generated from ltmain.m4sh.
34663
 
+
34664
 
+# ltmain.sh (GNU libtool) 2.2.6
34665
 
+# Written by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
34666
 
+
34667
 
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007 2008 Free Software Foundation, Inc.
34668
 
+# This is free software; see the source for copying conditions.  There is NO
34669
 
+# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
34670
 
+
34671
 
+# GNU Libtool is free software; you can redistribute it and/or modify
34672
 
+# it under the terms of the GNU General Public License as published by
34673
 
+# the Free Software Foundation; either version 2 of the License, or
34674
 
+# (at your option) any later version.
34675
 
+#
34676
 
+# As a special exception to the GNU General Public License,
34677
 
+# if you distribute this file as part of a program or library that
34678
 
+# is built using GNU Libtool, you may include this file under the
34679
 
+# same distribution terms that you use for the rest of that program.
34680
 
+#
34681
 
+# GNU Libtool is distributed in the hope that it will be useful, but
34682
 
+# WITHOUT ANY WARRANTY; without even the implied warranty of
34683
 
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
34684
 
+# General Public License for more details.
34685
 
+#
34686
 
+# You should have received a copy of the GNU General Public License
34687
 
+# along with GNU Libtool; see the file COPYING.  If not, a copy
34688
 
+# can be downloaded from http://www.gnu.org/licenses/gpl.html,
34689
 
+# or obtained by writing to the Free Software Foundation, Inc.,
34690
 
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
34691
 
+
34692
 
+# Usage: $progname [OPTION]... [MODE-ARG]...
34693
 
+#
34694
 
+# Provide generalized library-building support services.
34695
 
+#
34696
 
+#     --config             show all configuration variables
34697
 
+#     --debug              enable verbose shell tracing
34698
 
+# -n, --dry-run            display commands without modifying any files
34699
 
+#     --features           display basic configuration information and exit
34700
 
+#     --mode=MODE          use operation mode MODE
34701
 
+#     --preserve-dup-deps  don't remove duplicate dependency libraries
34702
 
+#     --quiet, --silent    don't print informational messages
34703
 
+#     --tag=TAG            use configuration variables from tag TAG
34704
 
+# -v, --verbose            print informational messages (default)
34705
 
+#     --version            print version information
34706
 
+# -h, --help               print short or long help message
34707
 
+#
34708
 
+# MODE must be one of the following:
34709
 
+#
34710
 
+#       clean              remove files from the build directory
34711
 
+#       compile            compile a source file into a libtool object
34712
 
+#       execute            automatically set library path, then run a program
34713
 
+#       finish             complete the installation of libtool libraries
34714
 
+#       install            install libraries or executables
34715
 
+#       link               create a library or an executable
34716
 
+#       uninstall          remove libraries from an installed directory
34717
 
+#
34718
 
+# MODE-ARGS vary depending on the MODE.
34719
 
+# Try `$progname --help --mode=MODE' for a more detailed description of MODE.
34720
 
+#
34721
 
+# When reporting a bug, please describe a test case to reproduce it and
34722
 
+# include the following information:
34723
 
+#
34724
 
+#       host-triplet:  $host
34725
 
+#       shell:         $SHELL
34726
 
+#       compiler:              $LTCC
34727
 
+#       compiler flags:                $LTCFLAGS
34728
 
+#       linker:                $LD (gnu? $with_gnu_ld)
34729
 
+#       $progname:             (GNU libtool) 2.2.6 Debian-2.2.6a-4
34730
 
+#       automake:              $automake_version
34731
 
+#       autoconf:              $autoconf_version
34732
 
+#
34733
 
+# Report bugs to <bug-libtool@gnu.org>.
34734
 
+
34735
 
+PROGRAM=ltmain.sh
34736
 
+PACKAGE=libtool
34737
 
+VERSION="2.2.6 Debian-2.2.6a-4"
34738
 
+TIMESTAMP=""
34739
 
+package_revision=1.3012
34740
 
+
34741
 
+# Be Bourne compatible
34742
 
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
34743
 
+  emulate sh
34744
 
+  NULLCMD=:
34745
 
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
34746
 
+  # is contrary to our usage.  Disable this feature.
34747
 
+  alias -g '${1+"$@"}'='"$@"'
34748
 
+  setopt NO_GLOB_SUBST
34749
 
+else
34750
 
+  case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
34751
 
+fi
34752
 
+BIN_SH=xpg4; export BIN_SH # for Tru64
34753
 
+DUALCASE=1; export DUALCASE # for MKS sh
34754
 
+
34755
 
+# NLS nuisances: We save the old values to restore during execute mode.
34756
 
+# Only set LANG and LC_ALL to C if already set.
34757
 
+# These must not be set unconditionally because not all systems understand
34758
 
+# e.g. LANG=C (notably SCO).
34759
 
+lt_user_locale=
34760
 
+lt_safe_locale=
34761
 
+for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
34762
 
+do
34763
 
+  eval "if test \"\${$lt_var+set}\" = set; then
34764
 
+          save_$lt_var=\$$lt_var
34765
 
+          $lt_var=C
34766
 
+         export $lt_var
34767
 
+         lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\"
34768
 
+         lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\"
34769
 
+       fi"
34770
 
+done
34771
 
+
34772
 
+$lt_unset CDPATH
34773
 
+
34774
 
+
34775
 
+
34776
 
+
34777
 
+
34778
 
+: ${CP="cp -f"}
34779
 
+: ${ECHO="echo"}
34780
 
+: ${EGREP="/bin/grep -E"}
34781
 
+: ${FGREP="/bin/grep -F"}
34782
 
+: ${GREP="/bin/grep"}
34783
 
+: ${LN_S="ln -s"}
34784
 
+: ${MAKE="make"}
34785
 
+: ${MKDIR="mkdir"}
34786
 
+: ${MV="mv -f"}
34787
 
+: ${RM="rm -f"}
34788
 
+: ${SED="/bin/sed"}
34789
 
+: ${SHELL="${CONFIG_SHELL-/bin/sh}"}
34790
 
+: ${Xsed="$SED -e 1s/^X//"}
34791
 
+
34792
 
+# Global variables:
34793
 
+EXIT_SUCCESS=0
34794
 
+EXIT_FAILURE=1
34795
 
+EXIT_MISMATCH=63  # $? = 63 is used to indicate version mismatch to missing.
34796
 
+EXIT_SKIP=77     # $? = 77 is used to indicate a skipped test to automake.
34797
 
+
34798
 
+exit_status=$EXIT_SUCCESS
34799
 
+
34800
 
+# Make sure IFS has a sensible default
34801
 
+lt_nl='
34802
 
+'
34803
 
+IFS="  $lt_nl"
34804
 
+
34805
 
+dirname="s,/[^/]*$,,"
34806
 
+basename="s,^.*/,,"
34807
 
+
34808
 
+# func_dirname_and_basename file append nondir_replacement
34809
 
+# perform func_basename and func_dirname in a single function
34810
 
+# call:
34811
 
+#   dirname:  Compute the dirname of FILE.  If nonempty,
34812
 
+#             add APPEND to the result, otherwise set result
34813
 
+#             to NONDIR_REPLACEMENT.
34814
 
+#             value returned in "$func_dirname_result"
34815
 
+#   basename: Compute filename of FILE.
34816
 
+#             value retuned in "$func_basename_result"
34817
 
+# Implementation must be kept synchronized with func_dirname
34818
 
+# and func_basename. For efficiency, we do not delegate to
34819
 
+# those functions but instead duplicate the functionality here.
34820
 
+func_dirname_and_basename ()
34821
 
+{
34822
 
+  # Extract subdirectory from the argument.
34823
 
+  func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"`
34824
 
+  if test "X$func_dirname_result" = "X${1}"; then
34825
 
+    func_dirname_result="${3}"
34826
 
+  else
34827
 
+    func_dirname_result="$func_dirname_result${2}"
34828
 
+  fi
34829
 
+  func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"`
34830
 
+}
34831
 
+
34832
 
+# Generated shell functions inserted here.
34833
 
+
34834
 
+# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh
34835
 
+# is ksh but when the shell is invoked as "sh" and the current value of
34836
 
+# the _XPG environment variable is not equal to 1 (one), the special
34837
 
+# positional parameter $0, within a function call, is the name of the
34838
 
+# function.
34839
 
+progpath="$0"
34840
 
+
34841
 
+# The name of this program:
34842
 
+# In the unlikely event $progname began with a '-', it would play havoc with
34843
 
+# func_echo (imagine progname=-n), so we prepend ./ in that case:
34844
 
+func_dirname_and_basename "$progpath"
34845
 
+progname=$func_basename_result
34846
 
+case $progname in
34847
 
+  -*) progname=./$progname ;;
34848
 
+esac
34849
 
+
34850
 
+# Make sure we have an absolute path for reexecution:
34851
 
+case $progpath in
34852
 
+  [\\/]*|[A-Za-z]:\\*) ;;
34853
 
+  *[\\/]*)
34854
 
+     progdir=$func_dirname_result
34855
 
+     progdir=`cd "$progdir" && pwd`
34856
 
+     progpath="$progdir/$progname"
34857
 
+     ;;
34858
 
+  *)
34859
 
+     save_IFS="$IFS"
34860
 
+     IFS=:
34861
 
+     for progdir in $PATH; do
34862
 
+       IFS="$save_IFS"
34863
 
+       test -x "$progdir/$progname" && break
34864
 
+     done
34865
 
+     IFS="$save_IFS"
34866
 
+     test -n "$progdir" || progdir=`pwd`
34867
 
+     progpath="$progdir/$progname"
34868
 
+     ;;
34869
 
+esac
34870
 
+
34871
 
+# Sed substitution that helps us do robust quoting.  It backslashifies
34872
 
+# metacharacters that are still active within double-quoted strings.
34873
 
+Xsed="${SED}"' -e 1s/^X//'
34874
 
+sed_quote_subst='s/\([`"$\\]\)/\\\1/g'
34875
 
+
34876
 
+# Same as above, but do not quote variable references.
34877
 
+double_quote_subst='s/\(["`\\]\)/\\\1/g'
34878
 
+
34879
 
+# Re-`\' parameter expansions in output of double_quote_subst that were
34880
 
+# `\'-ed in input to the same.  If an odd number of `\' preceded a '$'
34881
 
+# in input to double_quote_subst, that '$' was protected from expansion.
34882
 
+# Since each input `\' is now two `\'s, look for any number of runs of
34883
 
+# four `\'s followed by two `\'s and then a '$'.  `\' that '$'.
34884
 
+bs='\\'
34885
 
+bs2='\\\\'
34886
 
+bs4='\\\\\\\\'
34887
 
+dollar='\$'
34888
 
+sed_double_backslash="\
34889
 
+  s/$bs4/&\\
34890
 
+/g
34891
 
+  s/^$bs2$dollar/$bs&/
34892
 
+  s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g
34893
 
+  s/\n//g"
34894
 
+
34895
 
+# Standard options:
34896
 
+opt_dry_run=false
34897
 
+opt_help=false
34898
 
+opt_quiet=false
34899
 
+opt_verbose=false
34900
 
+opt_warning=:
34901
 
+
34902
 
+# func_echo arg...
34903
 
+# Echo program name prefixed message, along with the current mode
34904
 
+# name if it has been set yet.
34905
 
+func_echo ()
34906
 
+{
34907
 
+    $ECHO "$progname${mode+: }$mode: $*"
34908
 
+}
34909
 
+
34910
 
+# func_verbose arg...
34911
 
+# Echo program name prefixed message in verbose mode only.
34912
 
+func_verbose ()
34913
 
+{
34914
 
+    $opt_verbose && func_echo ${1+"$@"}
34915
 
+
34916
 
+    # A bug in bash halts the script if the last line of a function
34917
 
+    # fails when set -e is in force, so we need another command to
34918
 
+    # work around that:
34919
 
+    :
34920
 
+}
34921
 
+
34922
 
+# func_error arg...
34923
 
+# Echo program name prefixed message to standard error.
34924
 
+func_error ()
34925
 
+{
34926
 
+    $ECHO "$progname${mode+: }$mode: "${1+"$@"} 1>&2
34927
 
+}
34928
 
+
34929
 
+# func_warning arg...
34930
 
+# Echo program name prefixed warning message to standard error.
34931
 
+func_warning ()
34932
 
+{
34933
 
+    $opt_warning && $ECHO "$progname${mode+: }$mode: warning: "${1+"$@"} 1>&2
34934
 
+
34935
 
+    # bash bug again:
34936
 
+    :
34937
 
+}
34938
 
+
34939
 
+# func_fatal_error arg...
34940
 
+# Echo program name prefixed message to standard error, and exit.
34941
 
+func_fatal_error ()
34942
 
+{
34943
 
+    func_error ${1+"$@"}
34944
 
+    exit $EXIT_FAILURE
34945
 
+}
34946
 
+
34947
 
+# func_fatal_help arg...
34948
 
+# Echo program name prefixed message to standard error, followed by
34949
 
+# a help hint, and exit.
34950
 
+func_fatal_help ()
34951
 
+{
34952
 
+    func_error ${1+"$@"}
34953
 
+    func_fatal_error "$help"
34954
 
+}
34955
 
+help="Try \`$progname --help' for more information."  ## default
34956
 
+
34957
 
+
34958
 
+# func_grep expression filename
34959
 
+# Check whether EXPRESSION matches any line of FILENAME, without output.
34960
 
+func_grep ()
34961
 
+{
34962
 
+    $GREP "$1" "$2" >/dev/null 2>&1
34963
 
+}
34964
 
+
34965
 
+
34966
 
+# func_mkdir_p directory-path
34967
 
+# Make sure the entire path to DIRECTORY-PATH is available.
34968
 
+func_mkdir_p ()
34969
 
+{
34970
 
+    my_directory_path="$1"
34971
 
+    my_dir_list=
34972
 
+
34973
 
+    if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then
34974
 
+
34975
 
+      # Protect directory names starting with `-'
34976
 
+      case $my_directory_path in
34977
 
+        -*) my_directory_path="./$my_directory_path" ;;
34978
 
+      esac
34979
 
+
34980
 
+      # While some portion of DIR does not yet exist...
34981
 
+      while test ! -d "$my_directory_path"; do
34982
 
+        # ...make a list in topmost first order.  Use a colon delimited
34983
 
+       # list incase some portion of path contains whitespace.
34984
 
+        my_dir_list="$my_directory_path:$my_dir_list"
34985
 
+
34986
 
+        # If the last portion added has no slash in it, the list is done
34987
 
+        case $my_directory_path in */*) ;; *) break ;; esac
34988
 
+
34989
 
+        # ...otherwise throw away the child directory and loop
34990
 
+        my_directory_path=`$ECHO "X$my_directory_path" | $Xsed -e "$dirname"`
34991
 
+      done
34992
 
+      my_dir_list=`$ECHO "X$my_dir_list" | $Xsed -e 's,:*$,,'`
34993
 
+
34994
 
+      save_mkdir_p_IFS="$IFS"; IFS=':'
34995
 
+      for my_dir in $my_dir_list; do
34996
 
+       IFS="$save_mkdir_p_IFS"
34997
 
+        # mkdir can fail with a `File exist' error if two processes
34998
 
+        # try to create one of the directories concurrently.  Don't
34999
 
+        # stop in that case!
35000
 
+        $MKDIR "$my_dir" 2>/dev/null || :
35001
 
+      done
35002
 
+      IFS="$save_mkdir_p_IFS"
35003
 
+
35004
 
+      # Bail out if we (or some other process) failed to create a directory.
35005
 
+      test -d "$my_directory_path" || \
35006
 
+        func_fatal_error "Failed to create \`$1'"
35007
 
+    fi
35008
 
+}
35009
 
+
35010
 
+
35011
 
+# func_mktempdir [string]
35012
 
+# Make a temporary directory that won't clash with other running
35013
 
+# libtool processes, and avoids race conditions if possible.  If
35014
 
+# given, STRING is the basename for that directory.
35015
 
+func_mktempdir ()
35016
 
+{
35017
 
+    my_template="${TMPDIR-/tmp}/${1-$progname}"
35018
 
+
35019
 
+    if test "$opt_dry_run" = ":"; then
35020
 
+      # Return a directory name, but don't create it in dry-run mode
35021
 
+      my_tmpdir="${my_template}-$$"
35022
 
+    else
35023
 
+
35024
 
+      # If mktemp works, use that first and foremost
35025
 
+      my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null`
35026
 
+
35027
 
+      if test ! -d "$my_tmpdir"; then
35028
 
+        # Failing that, at least try and use $RANDOM to avoid a race
35029
 
+        my_tmpdir="${my_template}-${RANDOM-0}$$"
35030
 
+
35031
 
+        save_mktempdir_umask=`umask`
35032
 
+        umask 0077
35033
 
+        $MKDIR "$my_tmpdir"
35034
 
+        umask $save_mktempdir_umask
35035
 
+      fi
35036
 
+
35037
 
+      # If we're not in dry-run mode, bomb out on failure
35038
 
+      test -d "$my_tmpdir" || \
35039
 
+        func_fatal_error "cannot create temporary directory \`$my_tmpdir'"
35040
 
+    fi
35041
 
+
35042
 
+    $ECHO "X$my_tmpdir" | $Xsed
35043
 
+}
35044
 
+
35045
 
+
35046
 
+# func_quote_for_eval arg
35047
 
+# Aesthetically quote ARG to be evaled later.
35048
 
+# This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT
35049
 
+# is double-quoted, suitable for a subsequent eval, whereas
35050
 
+# FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters
35051
 
+# which are still active within double quotes backslashified.
35052
 
+func_quote_for_eval ()
35053
 
+{
35054
 
+    case $1 in
35055
 
+      *[\\\`\"\$]*)
35056
 
+       func_quote_for_eval_unquoted_result=`$ECHO "X$1" | $Xsed -e "$sed_quote_subst"` ;;
35057
 
+      *)
35058
 
+        func_quote_for_eval_unquoted_result="$1" ;;
35059
 
+    esac
35060
 
+
35061
 
+    case $func_quote_for_eval_unquoted_result in
35062
 
+      # Double-quote args containing shell metacharacters to delay
35063
 
+      # word splitting, command substitution and and variable
35064
 
+      # expansion for a subsequent eval.
35065
 
+      # Many Bourne shells cannot handle close brackets correctly
35066
 
+      # in scan sets, so we specify it separately.
35067
 
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \    ]*|*]*|"")
35068
 
+        func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\""
35069
 
+        ;;
35070
 
+      *)
35071
 
+        func_quote_for_eval_result="$func_quote_for_eval_unquoted_result"
35072
 
+    esac
35073
 
+}
35074
 
+
35075
 
+
35076
 
+# func_quote_for_expand arg
35077
 
+# Aesthetically quote ARG to be evaled later; same as above,
35078
 
+# but do not quote variable references.
35079
 
+func_quote_for_expand ()
35080
 
+{
35081
 
+    case $1 in
35082
 
+      *[\\\`\"]*)
35083
 
+       my_arg=`$ECHO "X$1" | $Xsed \
35084
 
+           -e "$double_quote_subst" -e "$sed_double_backslash"` ;;
35085
 
+      *)
35086
 
+        my_arg="$1" ;;
35087
 
+    esac
35088
 
+
35089
 
+    case $my_arg in
35090
 
+      # Double-quote args containing shell metacharacters to delay
35091
 
+      # word splitting and command substitution for a subsequent eval.
35092
 
+      # Many Bourne shells cannot handle close brackets correctly
35093
 
+      # in scan sets, so we specify it separately.
35094
 
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \    ]*|*]*|"")
35095
 
+        my_arg="\"$my_arg\""
35096
 
+        ;;
35097
 
+    esac
35098
 
+
35099
 
+    func_quote_for_expand_result="$my_arg"
35100
 
+}
35101
 
+
35102
 
+
35103
 
+# func_show_eval cmd [fail_exp]
35104
 
+# Unless opt_silent is true, then output CMD.  Then, if opt_dryrun is
35105
 
+# not true, evaluate CMD.  If the evaluation of CMD fails, and FAIL_EXP
35106
 
+# is given, then evaluate it.
35107
 
+func_show_eval ()
35108
 
+{
35109
 
+    my_cmd="$1"
35110
 
+    my_fail_exp="${2-:}"
35111
 
+
35112
 
+    ${opt_silent-false} || {
35113
 
+      func_quote_for_expand "$my_cmd"
35114
 
+      eval "func_echo $func_quote_for_expand_result"
35115
 
+    }
35116
 
+
35117
 
+    if ${opt_dry_run-false}; then :; else
35118
 
+      eval "$my_cmd"
35119
 
+      my_status=$?
35120
 
+      if test "$my_status" -eq 0; then :; else
35121
 
+       eval "(exit $my_status); $my_fail_exp"
35122
 
+      fi
35123
 
+    fi
35124
 
+}
35125
 
+
35126
 
+
35127
 
+# func_show_eval_locale cmd [fail_exp]
35128
 
+# Unless opt_silent is true, then output CMD.  Then, if opt_dryrun is
35129
 
+# not true, evaluate CMD.  If the evaluation of CMD fails, and FAIL_EXP
35130
 
+# is given, then evaluate it.  Use the saved locale for evaluation.
35131
 
+func_show_eval_locale ()
35132
 
+{
35133
 
+    my_cmd="$1"
35134
 
+    my_fail_exp="${2-:}"
35135
 
+
35136
 
+    ${opt_silent-false} || {
35137
 
+      func_quote_for_expand "$my_cmd"
35138
 
+      eval "func_echo $func_quote_for_expand_result"
35139
 
+    }
35140
 
+
35141
 
+    if ${opt_dry_run-false}; then :; else
35142
 
+      eval "$lt_user_locale
35143
 
+           $my_cmd"
35144
 
+      my_status=$?
35145
 
+      eval "$lt_safe_locale"
35146
 
+      if test "$my_status" -eq 0; then :; else
35147
 
+       eval "(exit $my_status); $my_fail_exp"
35148
 
+      fi
35149
 
+    fi
35150
 
+}
35151
 
+
35152
 
+
35153
 
+
35154
 
+
35155
 
+
35156
 
+# func_version
35157
 
+# Echo version message to standard output and exit.
35158
 
+func_version ()
35159
 
+{
35160
 
+    $SED -n '/^# '$PROGRAM' (GNU /,/# warranty; / {
35161
 
+        s/^# //
35162
 
+       s/^# *$//
35163
 
+        s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/
35164
 
+        p
35165
 
+     }' < "$progpath"
35166
 
+     exit $?
35167
 
+}
35168
 
+
35169
 
+# func_usage
35170
 
+# Echo short help message to standard output and exit.
35171
 
+func_usage ()
35172
 
+{
35173
 
+    $SED -n '/^# Usage:/,/# -h/ {
35174
 
+        s/^# //
35175
 
+       s/^# *$//
35176
 
+       s/\$progname/'$progname'/
35177
 
+       p
35178
 
+    }' < "$progpath"
35179
 
+    $ECHO
35180
 
+    $ECHO "run \`$progname --help | more' for full usage"
35181
 
+    exit $?
35182
 
+}
35183
 
+
35184
 
+# func_help
35185
 
+# Echo long help message to standard output and exit.
35186
 
+func_help ()
35187
 
+{
35188
 
+    $SED -n '/^# Usage:/,/# Report bugs to/ {
35189
 
+        s/^# //
35190
 
+       s/^# *$//
35191
 
+       s*\$progname*'$progname'*
35192
 
+       s*\$host*'"$host"'*
35193
 
+       s*\$SHELL*'"$SHELL"'*
35194
 
+       s*\$LTCC*'"$LTCC"'*
35195
 
+       s*\$LTCFLAGS*'"$LTCFLAGS"'*
35196
 
+       s*\$LD*'"$LD"'*
35197
 
+       s/\$with_gnu_ld/'"$with_gnu_ld"'/
35198
 
+       s/\$automake_version/'"`(automake --version) 2>/dev/null |$SED 1q`"'/
35199
 
+       s/\$autoconf_version/'"`(autoconf --version) 2>/dev/null |$SED 1q`"'/
35200
 
+       p
35201
 
+     }' < "$progpath"
35202
 
+    exit $?
35203
 
+}
35204
 
+
35205
 
+# func_missing_arg argname
35206
 
+# Echo program name prefixed message to standard error and set global
35207
 
+# exit_cmd.
35208
 
+func_missing_arg ()
35209
 
+{
35210
 
+    func_error "missing argument for $1"
35211
 
+    exit_cmd=exit
35212
 
+}
35213
 
+
35214
 
+exit_cmd=:
35215
 
+
35216
 
+
35217
 
+
35218
 
+
35219
 
+
35220
 
+# Check that we have a working $ECHO.
35221
 
+if test "X$1" = X--no-reexec; then
35222
 
+  # Discard the --no-reexec flag, and continue.
35223
 
+  shift
35224
 
+elif test "X$1" = X--fallback-echo; then
35225
 
+  # Avoid inline document here, it may be left over
35226
 
+  :
35227
 
+elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t'; then
35228
 
+  # Yippee, $ECHO works!
35229
 
+  :
35230
 
+else
35231
 
+  # Restart under the correct shell, and then maybe $ECHO will work.
35232
 
+  exec $SHELL "$progpath" --no-reexec ${1+"$@"}
35233
 
+fi
35234
 
+
35235
 
+if test "X$1" = X--fallback-echo; then
35236
 
+  # used as fallback echo
35237
 
+  shift
35238
 
+  cat <<EOF
35239
 
+$*
35240
 
+EOF
35241
 
+  exit $EXIT_SUCCESS
35242
 
+fi
35243
 
+
35244
 
+magic="%%%MAGIC variable%%%"
35245
 
+magic_exe="%%%MAGIC EXE variable%%%"
35246
 
+
35247
 
+# Global variables.
35248
 
+# $mode is unset
35249
 
+nonopt=
35250
 
+execute_dlfiles=
35251
 
+preserve_args=
35252
 
+lo2o="s/\\.lo\$/.${objext}/"
35253
 
+o2lo="s/\\.${objext}\$/.lo/"
35254
 
+extracted_archives=
35255
 
+extracted_serial=0
35256
 
+
35257
 
+opt_dry_run=false
35258
 
+opt_duplicate_deps=false
35259
 
+opt_silent=false
35260
 
+opt_debug=:
35261
 
+
35262
 
+# If this variable is set in any of the actions, the command in it
35263
 
+# will be execed at the end.  This prevents here-documents from being
35264
 
+# left over by shells.
35265
 
+exec_cmd=
35266
 
+
35267
 
+# func_fatal_configuration arg...
35268
 
+# Echo program name prefixed message to standard error, followed by
35269
 
+# a configuration failure hint, and exit.
35270
 
+func_fatal_configuration ()
35271
 
+{
35272
 
+    func_error ${1+"$@"}
35273
 
+    func_error "See the $PACKAGE documentation for more information."
35274
 
+    func_fatal_error "Fatal configuration error."
35275
 
+}
35276
 
+
35277
 
+
35278
 
+# func_config
35279
 
+# Display the configuration for all the tags in this script.
35280
 
+func_config ()
35281
 
+{
35282
 
+    re_begincf='^# ### BEGIN LIBTOOL'
35283
 
+    re_endcf='^# ### END LIBTOOL'
35284
 
+
35285
 
+    # Default configuration.
35286
 
+    $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath"
35287
 
+
35288
 
+    # Now print the configurations for the tags.
35289
 
+    for tagname in $taglist; do
35290
 
+      $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath"
35291
 
+    done
35292
 
+
35293
 
+    exit $?
35294
 
+}
35295
 
+
35296
 
+# func_features
35297
 
+# Display the features supported by this script.
35298
 
+func_features ()
35299
 
+{
35300
 
+    $ECHO "host: $host"
35301
 
+    if test "$build_libtool_libs" = yes; then
35302
 
+      $ECHO "enable shared libraries"
35303
 
+    else
35304
 
+      $ECHO "disable shared libraries"
35305
 
+    fi
35306
 
+    if test "$build_old_libs" = yes; then
35307
 
+      $ECHO "enable static libraries"
35308
 
+    else
35309
 
+      $ECHO "disable static libraries"
35310
 
+    fi
35311
 
+
35312
 
+    exit $?
35313
 
+}
35314
 
+
35315
 
+# func_enable_tag tagname
35316
 
+# Verify that TAGNAME is valid, and either flag an error and exit, or
35317
 
+# enable the TAGNAME tag.  We also add TAGNAME to the global $taglist
35318
 
+# variable here.
35319
 
+func_enable_tag ()
35320
 
+{
35321
 
+  # Global variable:
35322
 
+  tagname="$1"
35323
 
+
35324
 
+  re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$"
35325
 
+  re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$"
35326
 
+  sed_extractcf="/$re_begincf/,/$re_endcf/p"
35327
 
+
35328
 
+  # Validate tagname.
35329
 
+  case $tagname in
35330
 
+    *[!-_A-Za-z0-9,/]*)
35331
 
+      func_fatal_error "invalid tag name: $tagname"
35332
 
+      ;;
35333
 
+  esac
35334
 
+
35335
 
+  # Don't test for the "default" C tag, as we know it's
35336
 
+  # there but not specially marked.
35337
 
+  case $tagname in
35338
 
+    CC) ;;
35339
 
+    *)
35340
 
+      if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then
35341
 
+       taglist="$taglist $tagname"
35342
 
+
35343
 
+       # Evaluate the configuration.  Be careful to quote the path
35344
 
+       # and the sed script, to avoid splitting on whitespace, but
35345
 
+       # also don't use non-portable quotes within backquotes within
35346
 
+       # quotes we have to do it in 2 steps:
35347
 
+       extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"`
35348
 
+       eval "$extractedcf"
35349
 
+      else
35350
 
+       func_error "ignoring unknown tag $tagname"
35351
 
+      fi
35352
 
+      ;;
35353
 
+  esac
35354
 
+}
35355
 
+
35356
 
+# Parse options once, thoroughly.  This comes as soon as possible in
35357
 
+# the script to make things like `libtool --version' happen quickly.
35358
 
+{
35359
 
+
35360
 
+  # Shorthand for --mode=foo, only valid as the first argument
35361
 
+  case $1 in
35362
 
+  clean|clea|cle|cl)
35363
 
+    shift; set dummy --mode clean ${1+"$@"}; shift
35364
 
+    ;;
35365
 
+  compile|compil|compi|comp|com|co|c)
35366
 
+    shift; set dummy --mode compile ${1+"$@"}; shift
35367
 
+    ;;
35368
 
+  execute|execut|execu|exec|exe|ex|e)
35369
 
+    shift; set dummy --mode execute ${1+"$@"}; shift
35370
 
+    ;;
35371
 
+  finish|finis|fini|fin|fi|f)
35372
 
+    shift; set dummy --mode finish ${1+"$@"}; shift
35373
 
+    ;;
35374
 
+  install|instal|insta|inst|ins|in|i)
35375
 
+    shift; set dummy --mode install ${1+"$@"}; shift
35376
 
+    ;;
35377
 
+  link|lin|li|l)
35378
 
+    shift; set dummy --mode link ${1+"$@"}; shift
35379
 
+    ;;
35380
 
+  uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u)
35381
 
+    shift; set dummy --mode uninstall ${1+"$@"}; shift
35382
 
+    ;;
35383
 
+  esac
35384
 
+
35385
 
+  # Parse non-mode specific arguments:
35386
 
+  while test "$#" -gt 0; do
35387
 
+    opt="$1"
35388
 
+    shift
35389
 
+
35390
 
+    case $opt in
35391
 
+      --config)                func_config                                     ;;
35392
 
+
35393
 
+      --debug)         preserve_args="$preserve_args $opt"
35394
 
+                       func_echo "enabling shell trace mode"
35395
 
+                       opt_debug='set -x'
35396
 
+                       $opt_debug
35397
 
+                       ;;
35398
 
+
35399
 
+      -dlopen)         test "$#" -eq 0 && func_missing_arg "$opt" && break
35400
 
+                       execute_dlfiles="$execute_dlfiles $1"
35401
 
+                       shift
35402
 
+                       ;;
35403
 
+
35404
 
+      --dry-run | -n)  opt_dry_run=:                                   ;;
35405
 
+      --features)       func_features                                  ;;
35406
 
+      --finish)                mode="finish"                                   ;;
35407
 
+
35408
 
+      --mode)          test "$#" -eq 0 && func_missing_arg "$opt" && break
35409
 
+                       case $1 in
35410
 
+                         # Valid mode arguments:
35411
 
+                         clean)        ;;
35412
 
+                         compile)      ;;
35413
 
+                         execute)      ;;
35414
 
+                         finish)       ;;
35415
 
+                         install)      ;;
35416
 
+                         link)         ;;
35417
 
+                         relink)       ;;
35418
 
+                         uninstall)    ;;
35419
 
+
35420
 
+                         # Catch anything else as an error
35421
 
+                         *) func_error "invalid argument for $opt"
35422
 
+                            exit_cmd=exit
35423
 
+                            break
35424
 
+                            ;;
35425
 
+                       esac
35426
 
+
35427
 
+                       mode="$1"
35428
 
+                       shift
35429
 
+                       ;;
35430
 
+
35431
 
+      --preserve-dup-deps)
35432
 
+                       opt_duplicate_deps=:                            ;;
35433
 
+
35434
 
+      --quiet|--silent)        preserve_args="$preserve_args $opt"
35435
 
+                       opt_silent=:
35436
 
+                       ;;
35437
 
+
35438
 
+      --verbose| -v)   preserve_args="$preserve_args $opt"
35439
 
+                       opt_silent=false
35440
 
+                       ;;
35441
 
+
35442
 
+      --tag)           test "$#" -eq 0 && func_missing_arg "$opt" && break
35443
 
+                       preserve_args="$preserve_args $opt $1"
35444
 
+                       func_enable_tag "$1"    # tagname is set here
35445
 
+                       shift
35446
 
+                       ;;
35447
 
+
35448
 
+      # Separate optargs to long options:
35449
 
+      -dlopen=*|--mode=*|--tag=*)
35450
 
+                       func_opt_split "$opt"
35451
 
+                       set dummy "$func_opt_split_opt" "$func_opt_split_arg" ${1+"$@"}
35452
 
+                       shift
35453
 
+                       ;;
35454
 
+
35455
 
+      -\?|-h)          func_usage                                      ;;
35456
 
+      --help)          opt_help=:                                      ;;
35457
 
+      --version)       func_version                                    ;;
35458
 
+
35459
 
+      -*)              func_fatal_help "unrecognized option \`$opt'"   ;;
35460
 
+
35461
 
+      *)               nonopt="$opt"
35462
 
+                       break
35463
 
+                       ;;
35464
 
+    esac
35465
 
+  done
35466
 
+
35467
 
+
35468
 
+  case $host in
35469
 
+    *cygwin* | *mingw* | *pw32* | *cegcc*)
35470
 
+      # don't eliminate duplications in $postdeps and $predeps
35471
 
+      opt_duplicate_compiler_generated_deps=:
35472
 
+      ;;
35473
 
+    *)
35474
 
+      opt_duplicate_compiler_generated_deps=$opt_duplicate_deps
35475
 
+      ;;
35476
 
+  esac
35477
 
+
35478
 
+  # Having warned about all mis-specified options, bail out if
35479
 
+  # anything was wrong.
35480
 
+  $exit_cmd $EXIT_FAILURE
35481
 
+}
35482
 
+
35483
 
+# func_check_version_match
35484
 
+# Ensure that we are using m4 macros, and libtool script from the same
35485
 
+# release of libtool.
35486
 
+func_check_version_match ()
35487
 
+{
35488
 
+  if test "$package_revision" != "$macro_revision"; then
35489
 
+    if test "$VERSION" != "$macro_version"; then
35490
 
+      if test -z "$macro_version"; then
35491
 
+        cat >&2 <<_LT_EOF
35492
 
+$progname: Version mismatch error.  This is $PACKAGE $VERSION, but the
35493
 
+$progname: definition of this LT_INIT comes from an older release.
35494
 
+$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
35495
 
+$progname: and run autoconf again.
35496
 
+_LT_EOF
35497
 
+      else
35498
 
+        cat >&2 <<_LT_EOF
35499
 
+$progname: Version mismatch error.  This is $PACKAGE $VERSION, but the
35500
 
+$progname: definition of this LT_INIT comes from $PACKAGE $macro_version.
35501
 
+$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
35502
 
+$progname: and run autoconf again.
35503
 
+_LT_EOF
35504
 
+      fi
35505
 
+    else
35506
 
+      cat >&2 <<_LT_EOF
35507
 
+$progname: Version mismatch error.  This is $PACKAGE $VERSION, revision $package_revision,
35508
 
+$progname: but the definition of this LT_INIT comes from revision $macro_revision.
35509
 
+$progname: You should recreate aclocal.m4 with macros from revision $package_revision
35510
 
+$progname: of $PACKAGE $VERSION and run autoconf again.
35511
 
+_LT_EOF
35512
 
+    fi
35513
 
+
35514
 
+    exit $EXIT_MISMATCH
35515
 
+  fi
35516
 
+}
35517
 
+
35518
 
+
35519
 
+## ----------- ##
35520
 
+##    Main.    ##
35521
 
+## ----------- ##
35522
 
+
35523
 
+$opt_help || {
35524
 
+  # Sanity checks first:
35525
 
+  func_check_version_match
35526
 
+
35527
 
+  if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then
35528
 
+    func_fatal_configuration "not configured to build any kind of library"
35529
 
+  fi
35530
 
+
35531
 
+  test -z "$mode" && func_fatal_error "error: you must specify a MODE."
35532
 
+
35533
 
+
35534
 
+  # Darwin sucks
35535
 
+  eval std_shrext=\"$shrext_cmds\"
35536
 
+
35537
 
+
35538
 
+  # Only execute mode is allowed to have -dlopen flags.
35539
 
+  if test -n "$execute_dlfiles" && test "$mode" != execute; then
35540
 
+    func_error "unrecognized option \`-dlopen'"
35541
 
+    $ECHO "$help" 1>&2
35542
 
+    exit $EXIT_FAILURE
35543
 
+  fi
35544
 
+
35545
 
+  # Change the help message to a mode-specific one.
35546
 
+  generic_help="$help"
35547
 
+  help="Try \`$progname --help --mode=$mode' for more information."
35548
 
+}
35549
 
+
35550
 
+
35551
 
+# func_lalib_p file
35552
 
+# True iff FILE is a libtool `.la' library or `.lo' object file.
35553
 
+# This function is only a basic sanity check; it will hardly flush out
35554
 
+# determined imposters.
35555
 
+func_lalib_p ()
35556
 
+{
35557
 
+    test -f "$1" &&
35558
 
+      $SED -e 4q "$1" 2>/dev/null \
35559
 
+        | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1
35560
 
+}
35561
 
+
35562
 
+# func_lalib_unsafe_p file
35563
 
+# True iff FILE is a libtool `.la' library or `.lo' object file.
35564
 
+# This function implements the same check as func_lalib_p without
35565
 
+# resorting to external programs.  To this end, it redirects stdin and
35566
 
+# closes it afterwards, without saving the original file descriptor.
35567
 
+# As a safety measure, use it only where a negative result would be
35568
 
+# fatal anyway.  Works if `file' does not exist.
35569
 
+func_lalib_unsafe_p ()
35570
 
+{
35571
 
+    lalib_p=no
35572
 
+    if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then
35573
 
+       for lalib_p_l in 1 2 3 4
35574
 
+       do
35575
 
+           read lalib_p_line
35576
 
+           case "$lalib_p_line" in
35577
 
+               \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;;
35578
 
+           esac
35579
 
+       done
35580
 
+       exec 0<&5 5<&-
35581
 
+    fi
35582
 
+    test "$lalib_p" = yes
35583
 
+}
35584
 
+
35585
 
+# func_ltwrapper_script_p file
35586
 
+# True iff FILE is a libtool wrapper script
35587
 
+# This function is only a basic sanity check; it will hardly flush out
35588
 
+# determined imposters.
35589
 
+func_ltwrapper_script_p ()
35590
 
+{
35591
 
+    func_lalib_p "$1"
35592
 
+}
35593
 
+
35594
 
+# func_ltwrapper_executable_p file
35595
 
+# True iff FILE is a libtool wrapper executable
35596
 
+# This function is only a basic sanity check; it will hardly flush out
35597
 
+# determined imposters.
35598
 
+func_ltwrapper_executable_p ()
35599
 
+{
35600
 
+    func_ltwrapper_exec_suffix=
35601
 
+    case $1 in
35602
 
+    *.exe) ;;
35603
 
+    *) func_ltwrapper_exec_suffix=.exe ;;
35604
 
+    esac
35605
 
+    $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1
35606
 
+}
35607
 
+
35608
 
+# func_ltwrapper_scriptname file
35609
 
+# Assumes file is an ltwrapper_executable
35610
 
+# uses $file to determine the appropriate filename for a
35611
 
+# temporary ltwrapper_script.
35612
 
+func_ltwrapper_scriptname ()
35613
 
+{
35614
 
+    func_ltwrapper_scriptname_result=""
35615
 
+    if func_ltwrapper_executable_p "$1"; then
35616
 
+       func_dirname_and_basename "$1" "" "."
35617
 
+       func_stripname '' '.exe' "$func_basename_result"
35618
 
+       func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper"
35619
 
+    fi
35620
 
+}
35621
 
+
35622
 
+# func_ltwrapper_p file
35623
 
+# True iff FILE is a libtool wrapper script or wrapper executable
35624
 
+# This function is only a basic sanity check; it will hardly flush out
35625
 
+# determined imposters.
35626
 
+func_ltwrapper_p ()
35627
 
+{
35628
 
+    func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1"
35629
 
+}
35630
 
+
35631
 
+
35632
 
+# func_execute_cmds commands fail_cmd
35633
 
+# Execute tilde-delimited COMMANDS.
35634
 
+# If FAIL_CMD is given, eval that upon failure.
35635
 
+# FAIL_CMD may read-access the current command in variable CMD!
35636
 
+func_execute_cmds ()
35637
 
+{
35638
 
+    $opt_debug
35639
 
+    save_ifs=$IFS; IFS='~'
35640
 
+    for cmd in $1; do
35641
 
+      IFS=$save_ifs
35642
 
+      eval cmd=\"$cmd\"
35643
 
+      func_show_eval "$cmd" "${2-:}"
35644
 
+    done
35645
 
+    IFS=$save_ifs
35646
 
+}
35647
 
+
35648
 
+
35649
 
+# func_source file
35650
 
+# Source FILE, adding directory component if necessary.
35651
 
+# Note that it is not necessary on cygwin/mingw to append a dot to
35652
 
+# FILE even if both FILE and FILE.exe exist: automatic-append-.exe
35653
 
+# behavior happens only for exec(3), not for open(2)!  Also, sourcing
35654
 
+# `FILE.' does not work on cygwin managed mounts.
35655
 
+func_source ()
35656
 
+{
35657
 
+    $opt_debug
35658
 
+    case $1 in
35659
 
+    */* | *\\*)        . "$1" ;;
35660
 
+    *)         . "./$1" ;;
35661
 
+    esac
35662
 
+}
35663
 
+
35664
 
+
35665
 
+# func_infer_tag arg
35666
 
+# Infer tagged configuration to use if any are available and
35667
 
+# if one wasn't chosen via the "--tag" command line option.
35668
 
+# Only attempt this if the compiler in the base compile
35669
 
+# command doesn't match the default compiler.
35670
 
+# arg is usually of the form 'gcc ...'
35671
 
+func_infer_tag ()
35672
 
+{
35673
 
+    $opt_debug
35674
 
+    if test -n "$available_tags" && test -z "$tagname"; then
35675
 
+      CC_quoted=
35676
 
+      for arg in $CC; do
35677
 
+        func_quote_for_eval "$arg"
35678
 
+       CC_quoted="$CC_quoted $func_quote_for_eval_result"
35679
 
+      done
35680
 
+      case $@ in
35681
 
+      # Blanks in the command may have been stripped by the calling shell,
35682
 
+      # but not from the CC environment variable when configure was run.
35683
 
+      " $CC "* | "$CC "* | " `$ECHO $CC` "* | "`$ECHO $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$ECHO $CC_quoted` "* | "`$ECHO $CC_quoted` "*) ;;
35684
 
+      # Blanks at the start of $base_compile will cause this to fail
35685
 
+      # if we don't check for them as well.
35686
 
+      *)
35687
 
+       for z in $available_tags; do
35688
 
+         if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then
35689
 
+           # Evaluate the configuration.
35690
 
+           eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`"
35691
 
+           CC_quoted=
35692
 
+           for arg in $CC; do
35693
 
+             # Double-quote args containing other shell metacharacters.
35694
 
+             func_quote_for_eval "$arg"
35695
 
+             CC_quoted="$CC_quoted $func_quote_for_eval_result"
35696
 
+           done
35697
 
+           case "$@ " in
35698
 
+             " $CC "* | "$CC "* | " `$ECHO $CC` "* | "`$ECHO $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$ECHO $CC_quoted` "* | "`$ECHO $CC_quoted` "*)
35699
 
+             # The compiler in the base compile command matches
35700
 
+             # the one in the tagged configuration.
35701
 
+             # Assume this is the tagged configuration we want.
35702
 
+             tagname=$z
35703
 
+             break
35704
 
+             ;;
35705
 
+           esac
35706
 
+         fi
35707
 
+       done
35708
 
+       # If $tagname still isn't set, then no tagged configuration
35709
 
+       # was found and let the user know that the "--tag" command
35710
 
+       # line option must be used.
35711
 
+       if test -z "$tagname"; then
35712
 
+         func_echo "unable to infer tagged configuration"
35713
 
+         func_fatal_error "specify a tag with \`--tag'"
35714
 
+#      else
35715
 
+#        func_verbose "using $tagname tagged configuration"
35716
 
+       fi
35717
 
+       ;;
35718
 
+      esac
35719
 
+    fi
35720
 
+}
35721
 
+
35722
 
+
35723
 
+
35724
 
+# func_write_libtool_object output_name pic_name nonpic_name
35725
 
+# Create a libtool object file (analogous to a ".la" file),
35726
 
+# but don't create it if we're doing a dry run.
35727
 
+func_write_libtool_object ()
35728
 
+{
35729
 
+    write_libobj=${1}
35730
 
+    if test "$build_libtool_libs" = yes; then
35731
 
+      write_lobj=\'${2}\'
35732
 
+    else
35733
 
+      write_lobj=none
35734
 
+    fi
35735
 
+
35736
 
+    if test "$build_old_libs" = yes; then
35737
 
+      write_oldobj=\'${3}\'
35738
 
+    else
35739
 
+      write_oldobj=none
35740
 
+    fi
35741
 
+
35742
 
+    $opt_dry_run || {
35743
 
+      cat >${write_libobj}T <<EOF
35744
 
+# $write_libobj - a libtool object file
35745
 
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
35746
 
+#
35747
 
+# Please DO NOT delete this file!
35748
 
+# It is necessary for linking the library.
35749
 
+
35750
 
+# Name of the PIC object.
35751
 
+pic_object=$write_lobj
35752
 
+
35753
 
+# Name of the non-PIC object
35754
 
+non_pic_object=$write_oldobj
35755
 
+
35756
 
+EOF
35757
 
+      $MV "${write_libobj}T" "${write_libobj}"
35758
 
+    }
35759
 
+}
35760
 
+
35761
 
+# func_mode_compile arg...
35762
 
+func_mode_compile ()
35763
 
+{
35764
 
+    $opt_debug
35765
 
+    # Get the compilation command and the source file.
35766
 
+    base_compile=
35767
 
+    srcfile="$nonopt"  #  always keep a non-empty value in "srcfile"
35768
 
+    suppress_opt=yes
35769
 
+    suppress_output=
35770
 
+    arg_mode=normal
35771
 
+    libobj=
35772
 
+    later=
35773
 
+    pie_flag=
35774
 
+
35775
 
+    for arg
35776
 
+    do
35777
 
+      case $arg_mode in
35778
 
+      arg  )
35779
 
+       # do not "continue".  Instead, add this to base_compile
35780
 
+       lastarg="$arg"
35781
 
+       arg_mode=normal
35782
 
+       ;;
35783
 
+
35784
 
+      target )
35785
 
+       libobj="$arg"
35786
 
+       arg_mode=normal
35787
 
+       continue
35788
 
+       ;;
35789
 
+
35790
 
+      normal )
35791
 
+       # Accept any command-line options.
35792
 
+       case $arg in
35793
 
+       -o)
35794
 
+         test -n "$libobj" && \
35795
 
+           func_fatal_error "you cannot specify \`-o' more than once"
35796
 
+         arg_mode=target
35797
 
+         continue
35798
 
+         ;;
35799
 
+
35800
 
+       -pie | -fpie | -fPIE)
35801
 
+          pie_flag="$pie_flag $arg"
35802
 
+         continue
35803
 
+         ;;
35804
 
+
35805
 
+       -shared | -static | -prefer-pic | -prefer-non-pic)
35806
 
+         later="$later $arg"
35807
 
+         continue
35808
 
+         ;;
35809
 
+
35810
 
+       -no-suppress)
35811
 
+         suppress_opt=no
35812
 
+         continue
35813
 
+         ;;
35814
 
+
35815
 
+       -Xcompiler)
35816
 
+         arg_mode=arg  #  the next one goes into the "base_compile" arg list
35817
 
+         continue      #  The current "srcfile" will either be retained or
35818
 
+         ;;            #  replaced later.  I would guess that would be a bug.
35819
 
+
35820
 
+       -Wc,*)
35821
 
+         func_stripname '-Wc,' '' "$arg"
35822
 
+         args=$func_stripname_result
35823
 
+         lastarg=
35824
 
+         save_ifs="$IFS"; IFS=','
35825
 
+         for arg in $args; do
35826
 
+           IFS="$save_ifs"
35827
 
+           func_quote_for_eval "$arg"
35828
 
+           lastarg="$lastarg $func_quote_for_eval_result"
35829
 
+         done
35830
 
+         IFS="$save_ifs"
35831
 
+         func_stripname ' ' '' "$lastarg"
35832
 
+         lastarg=$func_stripname_result
35833
 
+
35834
 
+         # Add the arguments to base_compile.
35835
 
+         base_compile="$base_compile $lastarg"
35836
 
+         continue
35837
 
+         ;;
35838
 
+
35839
 
+       *)
35840
 
+         # Accept the current argument as the source file.
35841
 
+         # The previous "srcfile" becomes the current argument.
35842
 
+         #
35843
 
+         lastarg="$srcfile"
35844
 
+         srcfile="$arg"
35845
 
+         ;;
35846
 
+       esac  #  case $arg
35847
 
+       ;;
35848
 
+      esac    #  case $arg_mode
35849
 
+
35850
 
+      # Aesthetically quote the previous argument.
35851
 
+      func_quote_for_eval "$lastarg"
35852
 
+      base_compile="$base_compile $func_quote_for_eval_result"
35853
 
+    done # for arg
35854
 
+
35855
 
+    case $arg_mode in
35856
 
+    arg)
35857
 
+      func_fatal_error "you must specify an argument for -Xcompile"
35858
 
+      ;;
35859
 
+    target)
35860
 
+      func_fatal_error "you must specify a target with \`-o'"
35861
 
+      ;;
35862
 
+    *)
35863
 
+      # Get the name of the library object.
35864
 
+      test -z "$libobj" && {
35865
 
+       func_basename "$srcfile"
35866
 
+       libobj="$func_basename_result"
35867
 
+      }
35868
 
+      ;;
35869
 
+    esac
35870
 
+
35871
 
+    # Recognize several different file suffixes.
35872
 
+    # If the user specifies -o file.o, it is replaced with file.lo
35873
 
+    case $libobj in
35874
 
+    *.[cCFSifmso] | \
35875
 
+    *.ada | *.adb | *.ads | *.asm | \
35876
 
+    *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \
35877
 
+    *.[fF][09]? | *.for | *.java | *.obj | *.sx)
35878
 
+      func_xform "$libobj"
35879
 
+      libobj=$func_xform_result
35880
 
+      ;;
35881
 
+    esac
35882
 
+
35883
 
+    case $libobj in
35884
 
+    *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;;
35885
 
+    *)
35886
 
+      func_fatal_error "cannot determine name of library object from \`$libobj'"
35887
 
+      ;;
35888
 
+    esac
35889
 
+
35890
 
+    func_infer_tag $base_compile
35891
 
+
35892
 
+    for arg in $later; do
35893
 
+      case $arg in
35894
 
+      -shared)
35895
 
+       test "$build_libtool_libs" != yes && \
35896
 
+         func_fatal_configuration "can not build a shared library"
35897
 
+       build_old_libs=no
35898
 
+       continue
35899
 
+       ;;
35900
 
+
35901
 
+      -static)
35902
 
+       build_libtool_libs=no
35903
 
+       build_old_libs=yes
35904
 
+       continue
35905
 
+       ;;
35906
 
+
35907
 
+      -prefer-pic)
35908
 
+       pic_mode=yes
35909
 
+       continue
35910
 
+       ;;
35911
 
+
35912
 
+      -prefer-non-pic)
35913
 
+       pic_mode=no
35914
 
+       continue
35915
 
+       ;;
35916
 
+      esac
35917
 
+    done
35918
 
+
35919
 
+    func_quote_for_eval "$libobj"
35920
 
+    test "X$libobj" != "X$func_quote_for_eval_result" \
35921
 
+      && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"'   &()|`$[]' \
35922
 
+      && func_warning "libobj name \`$libobj' may not contain shell special characters."
35923
 
+    func_dirname_and_basename "$obj" "/" ""
35924
 
+    objname="$func_basename_result"
35925
 
+    xdir="$func_dirname_result"
35926
 
+    lobj=${xdir}$objdir/$objname
35927
 
+
35928
 
+    test -z "$base_compile" && \
35929
 
+      func_fatal_help "you must specify a compilation command"
35930
 
+
35931
 
+    # Delete any leftover library objects.
35932
 
+    if test "$build_old_libs" = yes; then
35933
 
+      removelist="$obj $lobj $libobj ${libobj}T"
35934
 
+    else
35935
 
+      removelist="$lobj $libobj ${libobj}T"
35936
 
+    fi
35937
 
+
35938
 
+    # On Cygwin there's no "real" PIC flag so we must build both object types
35939
 
+    case $host_os in
35940
 
+    cygwin* | mingw* | pw32* | os2* | cegcc*)
35941
 
+      pic_mode=default
35942
 
+      ;;
35943
 
+    esac
35944
 
+    if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then
35945
 
+      # non-PIC code in shared libraries is not supported
35946
 
+      pic_mode=default
35947
 
+    fi
35948
 
+
35949
 
+    # Calculate the filename of the output object if compiler does
35950
 
+    # not support -o with -c
35951
 
+    if test "$compiler_c_o" = no; then
35952
 
+      output_obj=`$ECHO "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext}
35953
 
+      lockfile="$output_obj.lock"
35954
 
+    else
35955
 
+      output_obj=
35956
 
+      need_locks=no
35957
 
+      lockfile=
35958
 
+    fi
35959
 
+
35960
 
+    # Lock this critical section if it is needed
35961
 
+    # We use this script file to make the link, it avoids creating a new file
35962
 
+    if test "$need_locks" = yes; then
35963
 
+      until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do
35964
 
+       func_echo "Waiting for $lockfile to be removed"
35965
 
+       sleep 2
35966
 
+      done
35967
 
+    elif test "$need_locks" = warn; then
35968
 
+      if test -f "$lockfile"; then
35969
 
+       $ECHO "\
35970
 
+*** ERROR, $lockfile exists and contains:
35971
 
+`cat $lockfile 2>/dev/null`
35972
 
+
35973
 
+This indicates that another process is trying to use the same
35974
 
+temporary object file, and libtool could not work around it because
35975
 
+your compiler does not support \`-c' and \`-o' together.  If you
35976
 
+repeat this compilation, it may succeed, by chance, but you had better
35977
 
+avoid parallel builds (make -j) in this platform, or get a better
35978
 
+compiler."
35979
 
+
35980
 
+       $opt_dry_run || $RM $removelist
35981
 
+       exit $EXIT_FAILURE
35982
 
+      fi
35983
 
+      removelist="$removelist $output_obj"
35984
 
+      $ECHO "$srcfile" > "$lockfile"
35985
 
+    fi
35986
 
+
35987
 
+    $opt_dry_run || $RM $removelist
35988
 
+    removelist="$removelist $lockfile"
35989
 
+    trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15
35990
 
+
35991
 
+    if test -n "$fix_srcfile_path"; then
35992
 
+      eval srcfile=\"$fix_srcfile_path\"
35993
 
+    fi
35994
 
+    func_quote_for_eval "$srcfile"
35995
 
+    qsrcfile=$func_quote_for_eval_result
35996
 
+
35997
 
+    # Only build a PIC object if we are building libtool libraries.
35998
 
+    if test "$build_libtool_libs" = yes; then
35999
 
+      # Without this assignment, base_compile gets emptied.
36000
 
+      fbsd_hideous_sh_bug=$base_compile
36001
 
+
36002
 
+      if test "$pic_mode" != no; then
36003
 
+       command="$base_compile $qsrcfile $pic_flag"
36004
 
+      else
36005
 
+       # Don't build PIC code
36006
 
+       command="$base_compile $qsrcfile"
36007
 
+      fi
36008
 
+
36009
 
+      func_mkdir_p "$xdir$objdir"
36010
 
+
36011
 
+      if test -z "$output_obj"; then
36012
 
+       # Place PIC objects in $objdir
36013
 
+       command="$command -o $lobj"
36014
 
+      fi
36015
 
+
36016
 
+      func_show_eval_locale "$command" \
36017
 
+          'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE'
36018
 
+
36019
 
+      if test "$need_locks" = warn &&
36020
 
+        test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
36021
 
+       $ECHO "\
36022
 
+*** ERROR, $lockfile contains:
36023
 
+`cat $lockfile 2>/dev/null`
36024
 
+
36025
 
+but it should contain:
36026
 
+$srcfile
36027
 
+
36028
 
+This indicates that another process is trying to use the same
36029
 
+temporary object file, and libtool could not work around it because
36030
 
+your compiler does not support \`-c' and \`-o' together.  If you
36031
 
+repeat this compilation, it may succeed, by chance, but you had better
36032
 
+avoid parallel builds (make -j) in this platform, or get a better
36033
 
+compiler."
36034
 
+
36035
 
+       $opt_dry_run || $RM $removelist
36036
 
+       exit $EXIT_FAILURE
36037
 
+      fi
36038
 
+
36039
 
+      # Just move the object if needed, then go on to compile the next one
36040
 
+      if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then
36041
 
+       func_show_eval '$MV "$output_obj" "$lobj"' \
36042
 
+         'error=$?; $opt_dry_run || $RM $removelist; exit $error'
36043
 
+      fi
36044
 
+
36045
 
+      # Allow error messages only from the first compilation.
36046
 
+      if test "$suppress_opt" = yes; then
36047
 
+       suppress_output=' >/dev/null 2>&1'
36048
 
+      fi
36049
 
+    fi
36050
 
+
36051
 
+    # Only build a position-dependent object if we build old libraries.
36052
 
+    if test "$build_old_libs" = yes; then
36053
 
+      if test "$pic_mode" != yes; then
36054
 
+       # Don't build PIC code
36055
 
+       command="$base_compile $qsrcfile$pie_flag"
36056
 
+      else
36057
 
+       command="$base_compile $qsrcfile $pic_flag"
36058
 
+      fi
36059
 
+      if test "$compiler_c_o" = yes; then
36060
 
+       command="$command -o $obj"
36061
 
+      fi
36062
 
+
36063
 
+      # Suppress compiler output if we already did a PIC compilation.
36064
 
+      command="$command$suppress_output"
36065
 
+      func_show_eval_locale "$command" \
36066
 
+        '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE'
36067
 
+
36068
 
+      if test "$need_locks" = warn &&
36069
 
+        test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
36070
 
+       $ECHO "\
36071
 
+*** ERROR, $lockfile contains:
36072
 
+`cat $lockfile 2>/dev/null`
36073
 
+
36074
 
+but it should contain:
36075
 
+$srcfile
36076
 
+
36077
 
+This indicates that another process is trying to use the same
36078
 
+temporary object file, and libtool could not work around it because
36079
 
+your compiler does not support \`-c' and \`-o' together.  If you
36080
 
+repeat this compilation, it may succeed, by chance, but you had better
36081
 
+avoid parallel builds (make -j) in this platform, or get a better
36082
 
+compiler."
36083
 
+
36084
 
+       $opt_dry_run || $RM $removelist
36085
 
+       exit $EXIT_FAILURE
36086
 
+      fi
36087
 
+
36088
 
+      # Just move the object if needed
36089
 
+      if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then
36090
 
+       func_show_eval '$MV "$output_obj" "$obj"' \
36091
 
+         'error=$?; $opt_dry_run || $RM $removelist; exit $error'
36092
 
+      fi
36093
 
+    fi
36094
 
+
36095
 
+    $opt_dry_run || {
36096
 
+      func_write_libtool_object "$libobj" "$objdir/$objname" "$objname"
36097
 
+
36098
 
+      # Unlock the critical section if it was locked
36099
 
+      if test "$need_locks" != no; then
36100
 
+       removelist=$lockfile
36101
 
+        $RM "$lockfile"
36102
 
+      fi
36103
 
+    }
36104
 
+
36105
 
+    exit $EXIT_SUCCESS
36106
 
+}
36107
 
+
36108
 
+$opt_help || {
36109
 
+test "$mode" = compile && func_mode_compile ${1+"$@"}
36110
 
+}
36111
 
+
36112
 
+func_mode_help ()
36113
 
+{
36114
 
+    # We need to display help for each of the modes.
36115
 
+    case $mode in
36116
 
+      "")
36117
 
+        # Generic help is extracted from the usage comments
36118
 
+        # at the start of this file.
36119
 
+        func_help
36120
 
+        ;;
36121
 
+
36122
 
+      clean)
36123
 
+        $ECHO \
36124
 
+"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE...
36125
 
+
36126
 
+Remove files from the build directory.
36127
 
+
36128
 
+RM is the name of the program to use to delete files associated with each FILE
36129
 
+(typically \`/bin/rm').  RM-OPTIONS are options (such as \`-f') to be passed
36130
 
+to RM.
36131
 
+
36132
 
+If FILE is a libtool library, object or program, all the files associated
36133
 
+with it are deleted. Otherwise, only FILE itself is deleted using RM."
36134
 
+        ;;
36135
 
+
36136
 
+      compile)
36137
 
+      $ECHO \
36138
 
+"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE
36139
 
+
36140
 
+Compile a source file into a libtool library object.
36141
 
+
36142
 
+This mode accepts the following additional options:
36143
 
+
36144
 
+  -o OUTPUT-FILE    set the output file name to OUTPUT-FILE
36145
 
+  -no-suppress      do not suppress compiler output for multiple passes
36146
 
+  -prefer-pic       try to building PIC objects only
36147
 
+  -prefer-non-pic   try to building non-PIC objects only
36148
 
+  -shared           do not build a \`.o' file suitable for static linking
36149
 
+  -static           only build a \`.o' file suitable for static linking
36150
 
+
36151
 
+COMPILE-COMMAND is a command to be used in creating a \`standard' object file
36152
 
+from the given SOURCEFILE.
36153
 
+
36154
 
+The output file name is determined by removing the directory component from
36155
 
+SOURCEFILE, then substituting the C source code suffix \`.c' with the
36156
 
+library object suffix, \`.lo'."
36157
 
+        ;;
36158
 
+
36159
 
+      execute)
36160
 
+        $ECHO \
36161
 
+"Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]...
36162
 
+
36163
 
+Automatically set library path, then run a program.
36164
 
+
36165
 
+This mode accepts the following additional options:
36166
 
+
36167
 
+  -dlopen FILE      add the directory containing FILE to the library path
36168
 
+
36169
 
+This mode sets the library path environment variable according to \`-dlopen'
36170
 
+flags.
36171
 
+
36172
 
+If any of the ARGS are libtool executable wrappers, then they are translated
36173
 
+into their corresponding uninstalled binary, and any of their required library
36174
 
+directories are added to the library path.
36175
 
+
36176
 
+Then, COMMAND is executed, with ARGS as arguments."
36177
 
+        ;;
36178
 
+
36179
 
+      finish)
36180
 
+        $ECHO \
36181
 
+"Usage: $progname [OPTION]... --mode=finish [LIBDIR]...
36182
 
+
36183
 
+Complete the installation of libtool libraries.
36184
 
+
36185
 
+Each LIBDIR is a directory that contains libtool libraries.
36186
 
+
36187
 
+The commands that this mode executes may require superuser privileges.  Use
36188
 
+the \`--dry-run' option if you just want to see what would be executed."
36189
 
+        ;;
36190
 
+
36191
 
+      install)
36192
 
+        $ECHO \
36193
 
+"Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND...
36194
 
+
36195
 
+Install executables or libraries.
36196
 
+
36197
 
+INSTALL-COMMAND is the installation command.  The first component should be
36198
 
+either the \`install' or \`cp' program.
36199
 
+
36200
 
+The following components of INSTALL-COMMAND are treated specially:
36201
 
+
36202
 
+  -inst-prefix PREFIX-DIR  Use PREFIX-DIR as a staging area for installation
36203
 
+
36204
 
+The rest of the components are interpreted as arguments to that command (only
36205
 
+BSD-compatible install options are recognized)."
36206
 
+        ;;
36207
 
+
36208
 
+      link)
36209
 
+        $ECHO \
36210
 
+"Usage: $progname [OPTION]... --mode=link LINK-COMMAND...
36211
 
+
36212
 
+Link object files or libraries together to form another library, or to
36213
 
+create an executable program.
36214
 
+
36215
 
+LINK-COMMAND is a command using the C compiler that you would use to create
36216
 
+a program from several object files.
36217
 
+
36218
 
+The following components of LINK-COMMAND are treated specially:
36219
 
+
36220
 
+  -all-static       do not do any dynamic linking at all
36221
 
+  -avoid-version    do not add a version suffix if possible
36222
 
+  -dlopen FILE      \`-dlpreopen' FILE if it cannot be dlopened at runtime
36223
 
+  -dlpreopen FILE   link in FILE and add its symbols to lt_preloaded_symbols
36224
 
+  -export-dynamic   allow symbols from OUTPUT-FILE to be resolved with dlsym(3)
36225
 
+  -export-symbols SYMFILE
36226
 
+                    try to export only the symbols listed in SYMFILE
36227
 
+  -export-symbols-regex REGEX
36228
 
+                    try to export only the symbols matching REGEX
36229
 
+  -LLIBDIR          search LIBDIR for required installed libraries
36230
 
+  -lNAME            OUTPUT-FILE requires the installed library libNAME
36231
 
+  -module           build a library that can dlopened
36232
 
+  -no-fast-install  disable the fast-install mode
36233
 
+  -no-install       link a not-installable executable
36234
 
+  -no-undefined     declare that a library does not refer to external symbols
36235
 
+  -o OUTPUT-FILE    create OUTPUT-FILE from the specified objects
36236
 
+  -objectlist FILE  Use a list of object files found in FILE to specify objects
36237
 
+  -precious-files-regex REGEX
36238
 
+                    don't remove output files matching REGEX
36239
 
+  -release RELEASE  specify package release information
36240
 
+  -rpath LIBDIR     the created library will eventually be installed in LIBDIR
36241
 
+  -R[ ]LIBDIR       add LIBDIR to the runtime path of programs and libraries
36242
 
+  -shared           only do dynamic linking of libtool libraries
36243
 
+  -shrext SUFFIX    override the standard shared library file extension
36244
 
+  -static           do not do any dynamic linking of uninstalled libtool libraries
36245
 
+  -static-libtool-libs
36246
 
+                    do not do any dynamic linking of libtool libraries
36247
 
+  -version-info CURRENT[:REVISION[:AGE]]
36248
 
+                    specify library version info [each variable defaults to 0]
36249
 
+  -weak LIBNAME     declare that the target provides the LIBNAME interface
36250
 
+
36251
 
+All other options (arguments beginning with \`-') are ignored.
36252
 
+
36253
 
+Every other argument is treated as a filename.  Files ending in \`.la' are
36254
 
+treated as uninstalled libtool libraries, other files are standard or library
36255
 
+object files.
36256
 
+
36257
 
+If the OUTPUT-FILE ends in \`.la', then a libtool library is created,
36258
 
+only library objects (\`.lo' files) may be specified, and \`-rpath' is
36259
 
+required, except when creating a convenience library.
36260
 
+
36261
 
+If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created
36262
 
+using \`ar' and \`ranlib', or on Windows using \`lib'.
36263
 
+
36264
 
+If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file
36265
 
+is created, otherwise an executable program is created."
36266
 
+        ;;
36267
 
+
36268
 
+      uninstall)
36269
 
+        $ECHO \
36270
 
+"Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE...
36271
 
+
36272
 
+Remove libraries from an installation directory.
36273
 
+
36274
 
+RM is the name of the program to use to delete files associated with each FILE
36275
 
+(typically \`/bin/rm').  RM-OPTIONS are options (such as \`-f') to be passed
36276
 
+to RM.
36277
 
+
36278
 
+If FILE is a libtool library, all the files associated with it are deleted.
36279
 
+Otherwise, only FILE itself is deleted using RM."
36280
 
+        ;;
36281
 
+
36282
 
+      *)
36283
 
+        func_fatal_help "invalid operation mode \`$mode'"
36284
 
+        ;;
36285
 
+    esac
36286
 
+
36287
 
+    $ECHO
36288
 
+    $ECHO "Try \`$progname --help' for more information about other modes."
36289
 
+
36290
 
+    exit $?
36291
 
+}
36292
 
+
36293
 
+  # Now that we've collected a possible --mode arg, show help if necessary
36294
 
+  $opt_help && func_mode_help
36295
 
+
36296
 
+
36297
 
+# func_mode_execute arg...
36298
 
+func_mode_execute ()
36299
 
+{
36300
 
+    $opt_debug
36301
 
+    # The first argument is the command name.
36302
 
+    cmd="$nonopt"
36303
 
+    test -z "$cmd" && \
36304
 
+      func_fatal_help "you must specify a COMMAND"
36305
 
+
36306
 
+    # Handle -dlopen flags immediately.
36307
 
+    for file in $execute_dlfiles; do
36308
 
+      test -f "$file" \
36309
 
+       || func_fatal_help "\`$file' is not a file"
36310
 
+
36311
 
+      dir=
36312
 
+      case $file in
36313
 
+      *.la)
36314
 
+       # Check to see that this really is a libtool archive.
36315
 
+       func_lalib_unsafe_p "$file" \
36316
 
+         || func_fatal_help "\`$lib' is not a valid libtool archive"
36317
 
+
36318
 
+       # Read the libtool library.
36319
 
+       dlname=
36320
 
+       library_names=
36321
 
+       func_source "$file"
36322
 
+
36323
 
+       # Skip this library if it cannot be dlopened.
36324
 
+       if test -z "$dlname"; then
36325
 
+         # Warn if it was a shared library.
36326
 
+         test -n "$library_names" && \
36327
 
+           func_warning "\`$file' was not linked with \`-export-dynamic'"
36328
 
+         continue
36329
 
+       fi
36330
 
+
36331
 
+       func_dirname "$file" "" "."
36332
 
+       dir="$func_dirname_result"
36333
 
+
36334
 
+       if test -f "$dir/$objdir/$dlname"; then
36335
 
+         dir="$dir/$objdir"
36336
 
+       else
36337
 
+         if test ! -f "$dir/$dlname"; then
36338
 
+           func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'"
36339
 
+         fi
36340
 
+       fi
36341
 
+       ;;
36342
 
+
36343
 
+      *.lo)
36344
 
+       # Just add the directory containing the .lo file.
36345
 
+       func_dirname "$file" "" "."
36346
 
+       dir="$func_dirname_result"
36347
 
+       ;;
36348
 
+
36349
 
+      *)
36350
 
+       func_warning "\`-dlopen' is ignored for non-libtool libraries and objects"
36351
 
+       continue
36352
 
+       ;;
36353
 
+      esac
36354
 
+
36355
 
+      # Get the absolute pathname.
36356
 
+      absdir=`cd "$dir" && pwd`
36357
 
+      test -n "$absdir" && dir="$absdir"
36358
 
+
36359
 
+      # Now add the directory to shlibpath_var.
36360
 
+      if eval "test -z \"\$$shlibpath_var\""; then
36361
 
+       eval "$shlibpath_var=\"\$dir\""
36362
 
+      else
36363
 
+       eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\""
36364
 
+      fi
36365
 
+    done
36366
 
+
36367
 
+    # This variable tells wrapper scripts just to set shlibpath_var
36368
 
+    # rather than running their programs.
36369
 
+    libtool_execute_magic="$magic"
36370
 
+
36371
 
+    # Check if any of the arguments is a wrapper script.
36372
 
+    args=
36373
 
+    for file
36374
 
+    do
36375
 
+      case $file in
36376
 
+      -*) ;;
36377
 
+      *)
36378
 
+       # Do a test to see if this is really a libtool program.
36379
 
+       if func_ltwrapper_script_p "$file"; then
36380
 
+         func_source "$file"
36381
 
+         # Transform arg to wrapped name.
36382
 
+         file="$progdir/$program"
36383
 
+       elif func_ltwrapper_executable_p "$file"; then
36384
 
+         func_ltwrapper_scriptname "$file"
36385
 
+         func_source "$func_ltwrapper_scriptname_result"
36386
 
+         # Transform arg to wrapped name.
36387
 
+         file="$progdir/$program"
36388
 
+       fi
36389
 
+       ;;
36390
 
+      esac
36391
 
+      # Quote arguments (to preserve shell metacharacters).
36392
 
+      func_quote_for_eval "$file"
36393
 
+      args="$args $func_quote_for_eval_result"
36394
 
+    done
36395
 
+
36396
 
+    if test "X$opt_dry_run" = Xfalse; then
36397
 
+      if test -n "$shlibpath_var"; then
36398
 
+       # Export the shlibpath_var.
36399
 
+       eval "export $shlibpath_var"
36400
 
+      fi
36401
 
+
36402
 
+      # Restore saved environment variables
36403
 
+      for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
36404
 
+      do
36405
 
+       eval "if test \"\${save_$lt_var+set}\" = set; then
36406
 
+                $lt_var=\$save_$lt_var; export $lt_var
36407
 
+             else
36408
 
+               $lt_unset $lt_var
36409
 
+             fi"
36410
 
+      done
36411
 
+
36412
 
+      # Now prepare to actually exec the command.
36413
 
+      exec_cmd="\$cmd$args"
36414
 
+    else
36415
 
+      # Display what would be done.
36416
 
+      if test -n "$shlibpath_var"; then
36417
 
+       eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\""
36418
 
+       $ECHO "export $shlibpath_var"
36419
 
+      fi
36420
 
+      $ECHO "$cmd$args"
36421
 
+      exit $EXIT_SUCCESS
36422
 
+    fi
36423
 
+}
36424
 
+
36425
 
+test "$mode" = execute && func_mode_execute ${1+"$@"}
36426
 
+
36427
 
+
36428
 
+# func_mode_finish arg...
36429
 
+func_mode_finish ()
36430
 
+{
36431
 
+    $opt_debug
36432
 
+    libdirs="$nonopt"
36433
 
+    admincmds=
36434
 
+
36435
 
+    if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
36436
 
+      for dir
36437
 
+      do
36438
 
+       libdirs="$libdirs $dir"
36439
 
+      done
36440
 
+
36441
 
+      for libdir in $libdirs; do
36442
 
+       if test -n "$finish_cmds"; then
36443
 
+         # Do each command in the finish commands.
36444
 
+         func_execute_cmds "$finish_cmds" 'admincmds="$admincmds
36445
 
+'"$cmd"'"'
36446
 
+       fi
36447
 
+       if test -n "$finish_eval"; then
36448
 
+         # Do the single finish_eval.
36449
 
+         eval cmds=\"$finish_eval\"
36450
 
+         $opt_dry_run || eval "$cmds" || admincmds="$admincmds
36451
 
+       $cmds"
36452
 
+       fi
36453
 
+      done
36454
 
+    fi
36455
 
+
36456
 
+    # Exit here if they wanted silent mode.
36457
 
+    $opt_silent && exit $EXIT_SUCCESS
36458
 
+
36459
 
+    $ECHO "X----------------------------------------------------------------------" | $Xsed
36460
 
+    $ECHO "Libraries have been installed in:"
36461
 
+    for libdir in $libdirs; do
36462
 
+      $ECHO "   $libdir"
36463
 
+    done
36464
 
+    $ECHO
36465
 
+    $ECHO "If you ever happen to want to link against installed libraries"
36466
 
+    $ECHO "in a given directory, LIBDIR, you must either use libtool, and"
36467
 
+    $ECHO "specify the full pathname of the library, or use the \`-LLIBDIR'"
36468
 
+    $ECHO "flag during linking and do at least one of the following:"
36469
 
+    if test -n "$shlibpath_var"; then
36470
 
+      $ECHO "   - add LIBDIR to the \`$shlibpath_var' environment variable"
36471
 
+      $ECHO "     during execution"
36472
 
+    fi
36473
 
+    if test -n "$runpath_var"; then
36474
 
+      $ECHO "   - add LIBDIR to the \`$runpath_var' environment variable"
36475
 
+      $ECHO "     during linking"
36476
 
+    fi
36477
 
+    if test -n "$hardcode_libdir_flag_spec"; then
36478
 
+      libdir=LIBDIR
36479
 
+      eval flag=\"$hardcode_libdir_flag_spec\"
36480
 
+
36481
 
+      $ECHO "   - use the \`$flag' linker flag"
36482
 
+    fi
36483
 
+    if test -n "$admincmds"; then
36484
 
+      $ECHO "   - have your system administrator run these commands:$admincmds"
36485
 
+    fi
36486
 
+    if test -f /etc/ld.so.conf; then
36487
 
+      $ECHO "   - have your system administrator add LIBDIR to \`/etc/ld.so.conf'"
36488
 
+    fi
36489
 
+    $ECHO
36490
 
+
36491
 
+    $ECHO "See any operating system documentation about shared libraries for"
36492
 
+    case $host in
36493
 
+      solaris2.[6789]|solaris2.1[0-9])
36494
 
+        $ECHO "more information, such as the ld(1), crle(1) and ld.so(8) manual"
36495
 
+       $ECHO "pages."
36496
 
+       ;;
36497
 
+      *)
36498
 
+        $ECHO "more information, such as the ld(1) and ld.so(8) manual pages."
36499
 
+        ;;
36500
 
+    esac
36501
 
+    $ECHO "X----------------------------------------------------------------------" | $Xsed
36502
 
+    exit $EXIT_SUCCESS
36503
 
+}
36504
 
+
36505
 
+test "$mode" = finish && func_mode_finish ${1+"$@"}
36506
 
+
36507
 
+
36508
 
+# func_mode_install arg...
36509
 
+func_mode_install ()
36510
 
+{
36511
 
+    $opt_debug
36512
 
+    # There may be an optional sh(1) argument at the beginning of
36513
 
+    # install_prog (especially on Windows NT).
36514
 
+    if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh ||
36515
 
+       # Allow the use of GNU shtool's install command.
36516
 
+       $ECHO "X$nonopt" | $GREP shtool >/dev/null; then
36517
 
+      # Aesthetically quote it.
36518
 
+      func_quote_for_eval "$nonopt"
36519
 
+      install_prog="$func_quote_for_eval_result "
36520
 
+      arg=$1
36521
 
+      shift
36522
 
+    else
36523
 
+      install_prog=
36524
 
+      arg=$nonopt
36525
 
+    fi
36526
 
+
36527
 
+    # The real first argument should be the name of the installation program.
36528
 
+    # Aesthetically quote it.
36529
 
+    func_quote_for_eval "$arg"
36530
 
+    install_prog="$install_prog$func_quote_for_eval_result"
36531
 
+
36532
 
+    # We need to accept at least all the BSD install flags.
36533
 
+    dest=
36534
 
+    files=
36535
 
+    opts=
36536
 
+    prev=
36537
 
+    install_type=
36538
 
+    isdir=no
36539
 
+    stripme=
36540
 
+    for arg
36541
 
+    do
36542
 
+      if test -n "$dest"; then
36543
 
+       files="$files $dest"
36544
 
+       dest=$arg
36545
 
+       continue
36546
 
+      fi
36547
 
+
36548
 
+      case $arg in
36549
 
+      -d) isdir=yes ;;
36550
 
+      -f)
36551
 
+       case " $install_prog " in
36552
 
+       *[\\\ /]cp\ *) ;;
36553
 
+       *) prev=$arg ;;
36554
 
+       esac
36555
 
+       ;;
36556
 
+      -g | -m | -o)
36557
 
+       prev=$arg
36558
 
+       ;;
36559
 
+      -s)
36560
 
+       stripme=" -s"
36561
 
+       continue
36562
 
+       ;;
36563
 
+      -*)
36564
 
+       ;;
36565
 
+      *)
36566
 
+       # If the previous option needed an argument, then skip it.
36567
 
+       if test -n "$prev"; then
36568
 
+         prev=
36569
 
+       else
36570
 
+         dest=$arg
36571
 
+         continue
36572
 
+       fi
36573
 
+       ;;
36574
 
+      esac
36575
 
+
36576
 
+      # Aesthetically quote the argument.
36577
 
+      func_quote_for_eval "$arg"
36578
 
+      install_prog="$install_prog $func_quote_for_eval_result"
36579
 
+    done
36580
 
+
36581
 
+    test -z "$install_prog" && \
36582
 
+      func_fatal_help "you must specify an install program"
36583
 
+
36584
 
+    test -n "$prev" && \
36585
 
+      func_fatal_help "the \`$prev' option requires an argument"
36586
 
+
36587
 
+    if test -z "$files"; then
36588
 
+      if test -z "$dest"; then
36589
 
+       func_fatal_help "no file or destination specified"
36590
 
+      else
36591
 
+       func_fatal_help "you must specify a destination"
36592
 
+      fi
36593
 
+    fi
36594
 
+
36595
 
+    # Strip any trailing slash from the destination.
36596
 
+    func_stripname '' '/' "$dest"
36597
 
+    dest=$func_stripname_result
36598
 
+
36599
 
+    # Check to see that the destination is a directory.
36600
 
+    test -d "$dest" && isdir=yes
36601
 
+    if test "$isdir" = yes; then
36602
 
+      destdir="$dest"
36603
 
+      destname=
36604
 
+    else
36605
 
+      func_dirname_and_basename "$dest" "" "."
36606
 
+      destdir="$func_dirname_result"
36607
 
+      destname="$func_basename_result"
36608
 
+
36609
 
+      # Not a directory, so check to see that there is only one file specified.
36610
 
+      set dummy $files; shift
36611
 
+      test "$#" -gt 1 && \
36612
 
+       func_fatal_help "\`$dest' is not a directory"
36613
 
+    fi
36614
 
+    case $destdir in
36615
 
+    [\\/]* | [A-Za-z]:[\\/]*) ;;
36616
 
+    *)
36617
 
+      for file in $files; do
36618
 
+       case $file in
36619
 
+       *.lo) ;;
36620
 
+       *)
36621
 
+         func_fatal_help "\`$destdir' must be an absolute directory name"
36622
 
+         ;;
36623
 
+       esac
36624
 
+      done
36625
 
+      ;;
36626
 
+    esac
36627
 
+
36628
 
+    # This variable tells wrapper scripts just to set variables rather
36629
 
+    # than running their programs.
36630
 
+    libtool_install_magic="$magic"
36631
 
+
36632
 
+    staticlibs=
36633
 
+    future_libdirs=
36634
 
+    current_libdirs=
36635
 
+    for file in $files; do
36636
 
+
36637
 
+      # Do each installation.
36638
 
+      case $file in
36639
 
+      *.$libext)
36640
 
+       # Do the static libraries later.
36641
 
+       staticlibs="$staticlibs $file"
36642
 
+       ;;
36643
 
+
36644
 
+      *.la)
36645
 
+       # Check to see that this really is a libtool archive.
36646
 
+       func_lalib_unsafe_p "$file" \
36647
 
+         || func_fatal_help "\`$file' is not a valid libtool archive"
36648
 
+
36649
 
+       library_names=
36650
 
+       old_library=
36651
 
+       relink_command=
36652
 
+       func_source "$file"
36653
 
+
36654
 
+       # Add the libdir to current_libdirs if it is the destination.
36655
 
+       if test "X$destdir" = "X$libdir"; then
36656
 
+         case "$current_libdirs " in
36657
 
+         *" $libdir "*) ;;
36658
 
+         *) current_libdirs="$current_libdirs $libdir" ;;
36659
 
+         esac
36660
 
+       else
36661
 
+         # Note the libdir as a future libdir.
36662
 
+         case "$future_libdirs " in
36663
 
+         *" $libdir "*) ;;
36664
 
+         *) future_libdirs="$future_libdirs $libdir" ;;
36665
 
+         esac
36666
 
+       fi
36667
 
+
36668
 
+       func_dirname "$file" "/" ""
36669
 
+       dir="$func_dirname_result"
36670
 
+       dir="$dir$objdir"
36671
 
+
36672
 
+       if test -n "$relink_command"; then
36673
 
+         # Determine the prefix the user has applied to our future dir.
36674
 
+         inst_prefix_dir=`$ECHO "X$destdir" | $Xsed -e "s%$libdir\$%%"`
36675
 
+
36676
 
+         # Don't allow the user to place us outside of our expected
36677
 
+         # location b/c this prevents finding dependent libraries that
36678
 
+         # are installed to the same prefix.
36679
 
+         # At present, this check doesn't affect windows .dll's that
36680
 
+         # are installed into $libdir/../bin (currently, that works fine)
36681
 
+         # but it's something to keep an eye on.
36682
 
+         test "$inst_prefix_dir" = "$destdir" && \
36683
 
+           func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir"
36684
 
+
36685
 
+         if test -n "$inst_prefix_dir"; then
36686
 
+           # Stick the inst_prefix_dir data into the link command.
36687
 
+           relink_command=`$ECHO "X$relink_command" | $Xsed -e "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"`
36688
 
+         else
36689
 
+           relink_command=`$ECHO "X$relink_command" | $Xsed -e "s%@inst_prefix_dir@%%"`
36690
 
+         fi
36691
 
+
36692
 
+         func_warning "relinking \`$file'"
36693
 
+         func_show_eval "$relink_command" \
36694
 
+           'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"'
36695
 
+       fi
36696
 
+
36697
 
+       # See the names of the shared library.
36698
 
+       set dummy $library_names; shift
36699
 
+       if test -n "$1"; then
36700
 
+         realname="$1"
36701
 
+         shift
36702
 
+
36703
 
+         srcname="$realname"
36704
 
+         test -n "$relink_command" && srcname="$realname"T
36705
 
+
36706
 
+         # Install the shared library and build the symlinks.
36707
 
+         func_show_eval "$install_prog $dir/$srcname $destdir/$realname" \
36708
 
+             'exit $?'
36709
 
+         tstripme="$stripme"
36710
 
+         case $host_os in
36711
 
+         cygwin* | mingw* | pw32* | cegcc*)
36712
 
+           case $realname in
36713
 
+           *.dll.a)
36714
 
+             tstripme=""
36715
 
+             ;;
36716
 
+           esac
36717
 
+           ;;
36718
 
+         esac
36719
 
+         if test -n "$tstripme" && test -n "$striplib"; then
36720
 
+           func_show_eval "$striplib $destdir/$realname" 'exit $?'
36721
 
+         fi
36722
 
+
36723
 
+         if test "$#" -gt 0; then
36724
 
+           # Delete the old symlinks, and create new ones.
36725
 
+           # Try `ln -sf' first, because the `ln' binary might depend on
36726
 
+           # the symlink we replace!  Solaris /bin/ln does not understand -f,
36727
 
+           # so we also need to try rm && ln -s.
36728
 
+           for linkname
36729
 
+           do
36730
 
+             test "$linkname" != "$realname" \
36731
 
+               && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })"
36732
 
+           done
36733
 
+         fi
36734
 
+
36735
 
+         # Do each command in the postinstall commands.
36736
 
+         lib="$destdir/$realname"
36737
 
+         func_execute_cmds "$postinstall_cmds" 'exit $?'
36738
 
+       fi
36739
 
+
36740
 
+       # Install the pseudo-library for information purposes.
36741
 
+       func_basename "$file"
36742
 
+       name="$func_basename_result"
36743
 
+       instname="$dir/$name"i
36744
 
+       func_show_eval "$install_prog $instname $destdir/$name" 'exit $?'
36745
 
+
36746
 
+       # Maybe install the static library, too.
36747
 
+       test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library"
36748
 
+       ;;
36749
 
+
36750
 
+      *.lo)
36751
 
+       # Install (i.e. copy) a libtool object.
36752
 
+
36753
 
+       # Figure out destination file name, if it wasn't already specified.
36754
 
+       if test -n "$destname"; then
36755
 
+         destfile="$destdir/$destname"
36756
 
+       else
36757
 
+         func_basename "$file"
36758
 
+         destfile="$func_basename_result"
36759
 
+         destfile="$destdir/$destfile"
36760
 
+       fi
36761
 
+
36762
 
+       # Deduce the name of the destination old-style object file.
36763
 
+       case $destfile in
36764
 
+       *.lo)
36765
 
+         func_lo2o "$destfile"
36766
 
+         staticdest=$func_lo2o_result
36767
 
+         ;;
36768
 
+       *.$objext)
36769
 
+         staticdest="$destfile"
36770
 
+         destfile=
36771
 
+         ;;
36772
 
+       *)
36773
 
+         func_fatal_help "cannot copy a libtool object to \`$destfile'"
36774
 
+         ;;
36775
 
+       esac
36776
 
+
36777
 
+       # Install the libtool object if requested.
36778
 
+       test -n "$destfile" && \
36779
 
+         func_show_eval "$install_prog $file $destfile" 'exit $?'
36780
 
+
36781
 
+       # Install the old object if enabled.
36782
 
+       if test "$build_old_libs" = yes; then
36783
 
+         # Deduce the name of the old-style object file.
36784
 
+         func_lo2o "$file"
36785
 
+         staticobj=$func_lo2o_result
36786
 
+         func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?'
36787
 
+       fi
36788
 
+       exit $EXIT_SUCCESS
36789
 
+       ;;
36790
 
+
36791
 
+      *)
36792
 
+       # Figure out destination file name, if it wasn't already specified.
36793
 
+       if test -n "$destname"; then
36794
 
+         destfile="$destdir/$destname"
36795
 
+       else
36796
 
+         func_basename "$file"
36797
 
+         destfile="$func_basename_result"
36798
 
+         destfile="$destdir/$destfile"
36799
 
+       fi
36800
 
+
36801
 
+       # If the file is missing, and there is a .exe on the end, strip it
36802
 
+       # because it is most likely a libtool script we actually want to
36803
 
+       # install
36804
 
+       stripped_ext=""
36805
 
+       case $file in
36806
 
+         *.exe)
36807
 
+           if test ! -f "$file"; then
36808
 
+             func_stripname '' '.exe' "$file"
36809
 
+             file=$func_stripname_result
36810
 
+             stripped_ext=".exe"
36811
 
+           fi
36812
 
+           ;;
36813
 
+       esac
36814
 
+
36815
 
+       # Do a test to see if this is really a libtool program.
36816
 
+       case $host in
36817
 
+       *cygwin* | *mingw*)
36818
 
+           if func_ltwrapper_executable_p "$file"; then
36819
 
+             func_ltwrapper_scriptname "$file"
36820
 
+             wrapper=$func_ltwrapper_scriptname_result
36821
 
+           else
36822
 
+             func_stripname '' '.exe' "$file"
36823
 
+             wrapper=$func_stripname_result
36824
 
+           fi
36825
 
+           ;;
36826
 
+       *)
36827
 
+           wrapper=$file
36828
 
+           ;;
36829
 
+       esac
36830
 
+       if func_ltwrapper_script_p "$wrapper"; then
36831
 
+         notinst_deplibs=
36832
 
+         relink_command=
36833
 
+
36834
 
+         func_source "$wrapper"
36835
 
+
36836
 
+         # Check the variables that should have been set.
36837
 
+         test -z "$generated_by_libtool_version" && \
36838
 
+           func_fatal_error "invalid libtool wrapper script \`$wrapper'"
36839
 
+
36840
 
+         finalize=yes
36841
 
+         for lib in $notinst_deplibs; do
36842
 
+           # Check to see that each library is installed.
36843
 
+           libdir=
36844
 
+           if test -f "$lib"; then
36845
 
+             func_source "$lib"
36846
 
+           fi
36847
 
+           libfile="$libdir/"`$ECHO "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test
36848
 
+           if test -n "$libdir" && test ! -f "$libfile"; then
36849
 
+             func_warning "\`$lib' has not been installed in \`$libdir'"
36850
 
+             finalize=no
36851
 
+           fi
36852
 
+         done
36853
 
+
36854
 
+         relink_command=
36855
 
+         func_source "$wrapper"
36856
 
+
36857
 
+         outputname=
36858
 
+         if test "$fast_install" = no && test -n "$relink_command"; then
36859
 
+           $opt_dry_run || {
36860
 
+             if test "$finalize" = yes; then
36861
 
+               tmpdir=`func_mktempdir`
36862
 
+               func_basename "$file$stripped_ext"
36863
 
+               file="$func_basename_result"
36864
 
+               outputname="$tmpdir/$file"
36865
 
+               # Replace the output file specification.
36866
 
+               relink_command=`$ECHO "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'`
36867
 
+
36868
 
+               $opt_silent || {
36869
 
+                 func_quote_for_expand "$relink_command"
36870
 
+                 eval "func_echo $func_quote_for_expand_result"
36871
 
+               }
36872
 
+               if eval "$relink_command"; then :
36873
 
+                 else
36874
 
+                 func_error "error: relink \`$file' with the above command before installing it"
36875
 
+                 $opt_dry_run || ${RM}r "$tmpdir"
36876
 
+                 continue
36877
 
+               fi
36878
 
+               file="$outputname"
36879
 
+             else
36880
 
+               func_warning "cannot relink \`$file'"
36881
 
+             fi
36882
 
+           }
36883
 
+         else
36884
 
+           # Install the binary that we compiled earlier.
36885
 
+           file=`$ECHO "X$file$stripped_ext" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"`
36886
 
+         fi
36887
 
+       fi
36888
 
+
36889
 
+       # remove .exe since cygwin /usr/bin/install will append another
36890
 
+       # one anyway
36891
 
+       case $install_prog,$host in
36892
 
+       */usr/bin/install*,*cygwin*)
36893
 
+         case $file:$destfile in
36894
 
+         *.exe:*.exe)
36895
 
+           # this is ok
36896
 
+           ;;
36897
 
+         *.exe:*)
36898
 
+           destfile=$destfile.exe
36899
 
+           ;;
36900
 
+         *:*.exe)
36901
 
+           func_stripname '' '.exe' "$destfile"
36902
 
+           destfile=$func_stripname_result
36903
 
+           ;;
36904
 
+         esac
36905
 
+         ;;
36906
 
+       esac
36907
 
+       func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?'
36908
 
+       $opt_dry_run || if test -n "$outputname"; then
36909
 
+         ${RM}r "$tmpdir"
36910
 
+       fi
36911
 
+       ;;
36912
 
+      esac
36913
 
+    done
36914
 
+
36915
 
+    for file in $staticlibs; do
36916
 
+      func_basename "$file"
36917
 
+      name="$func_basename_result"
36918
 
+
36919
 
+      # Set up the ranlib parameters.
36920
 
+      oldlib="$destdir/$name"
36921
 
+
36922
 
+      func_show_eval "$install_prog \$file \$oldlib" 'exit $?'
36923
 
+
36924
 
+      if test -n "$stripme" && test -n "$old_striplib"; then
36925
 
+       func_show_eval "$old_striplib $oldlib" 'exit $?'
36926
 
+      fi
36927
 
+
36928
 
+      # Do each command in the postinstall commands.
36929
 
+      func_execute_cmds "$old_postinstall_cmds" 'exit $?'
36930
 
+    done
36931
 
+
36932
 
+    test -n "$future_libdirs" && \
36933
 
+      func_warning "remember to run \`$progname --finish$future_libdirs'"
36934
 
+
36935
 
+    if test -n "$current_libdirs"; then
36936
 
+      # Maybe just do a dry run.
36937
 
+      $opt_dry_run && current_libdirs=" -n$current_libdirs"
36938
 
+      exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs'
36939
 
+    else
36940
 
+      exit $EXIT_SUCCESS
36941
 
+    fi
36942
 
+}
36943
 
+
36944
 
+test "$mode" = install && func_mode_install ${1+"$@"}
36945
 
+
36946
 
+
36947
 
+# func_generate_dlsyms outputname originator pic_p
36948
 
+# Extract symbols from dlprefiles and create ${outputname}S.o with
36949
 
+# a dlpreopen symbol table.
36950
 
+func_generate_dlsyms ()
36951
 
+{
36952
 
+    $opt_debug
36953
 
+    my_outputname="$1"
36954
 
+    my_originator="$2"
36955
 
+    my_pic_p="${3-no}"
36956
 
+    my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'`
36957
 
+    my_dlsyms=
36958
 
+
36959
 
+    if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
36960
 
+      if test -n "$NM" && test -n "$global_symbol_pipe"; then
36961
 
+       my_dlsyms="${my_outputname}S.c"
36962
 
+      else
36963
 
+       func_error "not configured to extract global symbols from dlpreopened files"
36964
 
+      fi
36965
 
+    fi
36966
 
+
36967
 
+    if test -n "$my_dlsyms"; then
36968
 
+      case $my_dlsyms in
36969
 
+      "") ;;
36970
 
+      *.c)
36971
 
+       # Discover the nlist of each of the dlfiles.
36972
 
+       nlist="$output_objdir/${my_outputname}.nm"
36973
 
+
36974
 
+       func_show_eval "$RM $nlist ${nlist}S ${nlist}T"
36975
 
+
36976
 
+       # Parse the name list into a source file.
36977
 
+       func_verbose "creating $output_objdir/$my_dlsyms"
36978
 
+
36979
 
+       $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\
36980
 
+/* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */
36981
 
+/* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */
36982
 
+
36983
 
+#ifdef __cplusplus
36984
 
+extern \"C\" {
36985
 
+#endif
36986
 
+
36987
 
+/* External symbol declarations for the compiler. */\
36988
 
+"
36989
 
+
36990
 
+       if test "$dlself" = yes; then
36991
 
+         func_verbose "generating symbol list for \`$output'"
36992
 
+
36993
 
+         $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist"
36994
 
+
36995
 
+         # Add our own program objects to the symbol list.
36996
 
+         progfiles=`$ECHO "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
36997
 
+         for progfile in $progfiles; do
36998
 
+           func_verbose "extracting global C symbols from \`$progfile'"
36999
 
+           $opt_dry_run || eval "$NM $progfile | $global_symbol_pipe >> '$nlist'"
37000
 
+         done
37001
 
+
37002
 
+         if test -n "$exclude_expsyms"; then
37003
 
+           $opt_dry_run || {
37004
 
+             eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T'
37005
 
+             eval '$MV "$nlist"T "$nlist"'
37006
 
+           }
37007
 
+         fi
37008
 
+
37009
 
+         if test -n "$export_symbols_regex"; then
37010
 
+           $opt_dry_run || {
37011
 
+             eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T'
37012
 
+             eval '$MV "$nlist"T "$nlist"'
37013
 
+           }
37014
 
+         fi
37015
 
+
37016
 
+         # Prepare the list of exported symbols
37017
 
+         if test -z "$export_symbols"; then
37018
 
+           export_symbols="$output_objdir/$outputname.exp"
37019
 
+           $opt_dry_run || {
37020
 
+             $RM $export_symbols
37021
 
+             eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
37022
 
+             case $host in
37023
 
+             *cygwin* | *mingw* | *cegcc* )
37024
 
+                eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
37025
 
+                eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"'
37026
 
+               ;;
37027
 
+             esac
37028
 
+           }
37029
 
+         else
37030
 
+           $opt_dry_run || {
37031
 
+             eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"'
37032
 
+             eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T'
37033
 
+             eval '$MV "$nlist"T "$nlist"'
37034
 
+             case $host in
37035
 
+               *cygwin | *mingw* | *cegcc* )
37036
 
+                 eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
37037
 
+                 eval 'cat "$nlist" >> "$output_objdir/$outputname.def"'
37038
 
+                 ;;
37039
 
+             esac
37040
 
+           }
37041
 
+         fi
37042
 
+       fi
37043
 
+
37044
 
+       for dlprefile in $dlprefiles; do
37045
 
+         func_verbose "extracting global C symbols from \`$dlprefile'"
37046
 
+         func_basename "$dlprefile"
37047
 
+         name="$func_basename_result"
37048
 
+         $opt_dry_run || {
37049
 
+           eval '$ECHO ": $name " >> "$nlist"'
37050
 
+           eval "$NM $dlprefile 2>/dev/null | $global_symbol_pipe >> '$nlist'"
37051
 
+         }
37052
 
+       done
37053
 
+
37054
 
+       $opt_dry_run || {
37055
 
+         # Make sure we have at least an empty file.
37056
 
+         test -f "$nlist" || : > "$nlist"
37057
 
+
37058
 
+         if test -n "$exclude_expsyms"; then
37059
 
+           $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T
37060
 
+           $MV "$nlist"T "$nlist"
37061
 
+         fi
37062
 
+
37063
 
+         # Try sorting and uniquifying the output.
37064
 
+         if $GREP -v "^: " < "$nlist" |
37065
 
+             if sort -k 3 </dev/null >/dev/null 2>&1; then
37066
 
+               sort -k 3
37067
 
+             else
37068
 
+               sort +2
37069
 
+             fi |
37070
 
+             uniq > "$nlist"S; then
37071
 
+           :
37072
 
+         else
37073
 
+           $GREP -v "^: " < "$nlist" > "$nlist"S
37074
 
+         fi
37075
 
+
37076
 
+         if test -f "$nlist"S; then
37077
 
+           eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"'
37078
 
+         else
37079
 
+           $ECHO '/* NONE */' >> "$output_objdir/$my_dlsyms"
37080
 
+         fi
37081
 
+
37082
 
+         $ECHO >> "$output_objdir/$my_dlsyms" "\
37083
 
+
37084
 
+/* The mapping between symbol names and symbols.  */
37085
 
+typedef struct {
37086
 
+  const char *name;
37087
 
+  void *address;
37088
 
+} lt_dlsymlist;
37089
 
+"
37090
 
+         case $host in
37091
 
+         *cygwin* | *mingw* | *cegcc* )
37092
 
+           $ECHO >> "$output_objdir/$my_dlsyms" "\
37093
 
+/* DATA imports from DLLs on WIN32 con't be const, because
37094
 
+   runtime relocations are performed -- see ld's documentation
37095
 
+   on pseudo-relocs.  */"
37096
 
+           lt_dlsym_const= ;;
37097
 
+         *osf5*)
37098
 
+           echo >> "$output_objdir/$my_dlsyms" "\
37099
 
+/* This system does not cope well with relocations in const data */"
37100
 
+           lt_dlsym_const= ;;
37101
 
+         *)
37102
 
+           lt_dlsym_const=const ;;
37103
 
+         esac
37104
 
+
37105
 
+         $ECHO >> "$output_objdir/$my_dlsyms" "\
37106
 
+extern $lt_dlsym_const lt_dlsymlist
37107
 
+lt_${my_prefix}_LTX_preloaded_symbols[];
37108
 
+$lt_dlsym_const lt_dlsymlist
37109
 
+lt_${my_prefix}_LTX_preloaded_symbols[] =
37110
 
+{\
37111
 
+  { \"$my_originator\", (void *) 0 },"
37112
 
+
37113
 
+         case $need_lib_prefix in
37114
 
+         no)
37115
 
+           eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms"
37116
 
+           ;;
37117
 
+         *)
37118
 
+           eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms"
37119
 
+           ;;
37120
 
+         esac
37121
 
+         $ECHO >> "$output_objdir/$my_dlsyms" "\
37122
 
+  {0, (void *) 0}
37123
 
+};
37124
 
+
37125
 
+/* This works around a problem in FreeBSD linker */
37126
 
+#ifdef FREEBSD_WORKAROUND
37127
 
+static const void *lt_preloaded_setup() {
37128
 
+  return lt_${my_prefix}_LTX_preloaded_symbols;
37129
 
+}
37130
 
+#endif
37131
 
+
37132
 
+#ifdef __cplusplus
37133
 
+}
37134
 
+#endif\
37135
 
+"
37136
 
+       } # !$opt_dry_run
37137
 
+
37138
 
+       pic_flag_for_symtable=
37139
 
+       case "$compile_command " in
37140
 
+       *" -static "*) ;;
37141
 
+       *)
37142
 
+         case $host in
37143
 
+         # compiling the symbol table file with pic_flag works around
37144
 
+         # a FreeBSD bug that causes programs to crash when -lm is
37145
 
+         # linked before any other PIC object.  But we must not use
37146
 
+         # pic_flag when linking with -static.  The problem exists in
37147
 
+         # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1.
37148
 
+         *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*)
37149
 
+           pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;;
37150
 
+         *-*-hpux*)
37151
 
+           pic_flag_for_symtable=" $pic_flag"  ;;
37152
 
+         *)
37153
 
+           if test "X$my_pic_p" != Xno; then
37154
 
+             pic_flag_for_symtable=" $pic_flag"
37155
 
+           fi
37156
 
+           ;;
37157
 
+         esac
37158
 
+         ;;
37159
 
+       esac
37160
 
+       symtab_cflags=
37161
 
+       for arg in $LTCFLAGS; do
37162
 
+         case $arg in
37163
 
+         -pie | -fpie | -fPIE) ;;
37164
 
+         *) symtab_cflags="$symtab_cflags $arg" ;;
37165
 
+         esac
37166
 
+       done
37167
 
+
37168
 
+       # Now compile the dynamic symbol file.
37169
 
+       func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?'
37170
 
+
37171
 
+       # Clean up the generated files.
37172
 
+       func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"'
37173
 
+
37174
 
+       # Transform the symbol file into the correct name.
37175
 
+       symfileobj="$output_objdir/${my_outputname}S.$objext"
37176
 
+       case $host in
37177
 
+       *cygwin* | *mingw* | *cegcc* )
37178
 
+         if test -f "$output_objdir/$my_outputname.def"; then
37179
 
+           compile_command=`$ECHO "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
37180
 
+           finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
37181
 
+         else
37182
 
+           compile_command=`$ECHO "X$compile_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"`
37183
 
+           finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"`
37184
 
+         fi
37185
 
+         ;;
37186
 
+       *)
37187
 
+         compile_command=`$ECHO "X$compile_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"`
37188
 
+         finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"`
37189
 
+         ;;
37190
 
+       esac
37191
 
+       ;;
37192
 
+      *)
37193
 
+       func_fatal_error "unknown suffix for \`$my_dlsyms'"
37194
 
+       ;;
37195
 
+      esac
37196
 
+    else
37197
 
+      # We keep going just in case the user didn't refer to
37198
 
+      # lt_preloaded_symbols.  The linker will fail if global_symbol_pipe
37199
 
+      # really was required.
37200
 
+
37201
 
+      # Nullify the symbol file.
37202
 
+      compile_command=`$ECHO "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"`
37203
 
+      finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"`
37204
 
+    fi
37205
 
+}
37206
 
+
37207
 
+# func_win32_libid arg
37208
 
+# return the library type of file 'arg'
37209
 
+#
37210
 
+# Need a lot of goo to handle *both* DLLs and import libs
37211
 
+# Has to be a shell function in order to 'eat' the argument
37212
 
+# that is supplied when $file_magic_command is called.
37213
 
+func_win32_libid ()
37214
 
+{
37215
 
+  $opt_debug
37216
 
+  win32_libid_type="unknown"
37217
 
+  win32_fileres=`file -L $1 2>/dev/null`
37218
 
+  case $win32_fileres in
37219
 
+  *ar\ archive\ import\ library*) # definitely import
37220
 
+    win32_libid_type="x86 archive import"
37221
 
+    ;;
37222
 
+  *ar\ archive*) # could be an import, or static
37223
 
+    if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null |
37224
 
+       $EGREP 'file format pe-i386(.*architecture: i386)?' >/dev/null ; then
37225
 
+      win32_nmres=`eval $NM -f posix -A $1 |
37226
 
+       $SED -n -e '
37227
 
+           1,100{
37228
 
+               / I /{
37229
 
+                   s,.*,import,
37230
 
+                   p
37231
 
+                   q
37232
 
+               }
37233
 
+           }'`
37234
 
+      case $win32_nmres in
37235
 
+      import*)  win32_libid_type="x86 archive import";;
37236
 
+      *)        win32_libid_type="x86 archive static";;
37237
 
+      esac
37238
 
+    fi
37239
 
+    ;;
37240
 
+  *DLL*)
37241
 
+    win32_libid_type="x86 DLL"
37242
 
+    ;;
37243
 
+  *executable*) # but shell scripts are "executable" too...
37244
 
+    case $win32_fileres in
37245
 
+    *MS\ Windows\ PE\ Intel*)
37246
 
+      win32_libid_type="x86 DLL"
37247
 
+      ;;
37248
 
+    esac
37249
 
+    ;;
37250
 
+  esac
37251
 
+  $ECHO "$win32_libid_type"
37252
 
+}
37253
 
+
37254
 
+
37255
 
+
37256
 
+# func_extract_an_archive dir oldlib
37257
 
+func_extract_an_archive ()
37258
 
+{
37259
 
+    $opt_debug
37260
 
+    f_ex_an_ar_dir="$1"; shift
37261
 
+    f_ex_an_ar_oldlib="$1"
37262
 
+    func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" 'exit $?'
37263
 
+    if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then
37264
 
+     :
37265
 
+    else
37266
 
+      func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib"
37267
 
+    fi
37268
 
+}
37269
 
+
37270
 
+
37271
 
+# func_extract_archives gentop oldlib ...
37272
 
+func_extract_archives ()
37273
 
+{
37274
 
+    $opt_debug
37275
 
+    my_gentop="$1"; shift
37276
 
+    my_oldlibs=${1+"$@"}
37277
 
+    my_oldobjs=""
37278
 
+    my_xlib=""
37279
 
+    my_xabs=""
37280
 
+    my_xdir=""
37281
 
+
37282
 
+    for my_xlib in $my_oldlibs; do
37283
 
+      # Extract the objects.
37284
 
+      case $my_xlib in
37285
 
+       [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;;
37286
 
+       *) my_xabs=`pwd`"/$my_xlib" ;;
37287
 
+      esac
37288
 
+      func_basename "$my_xlib"
37289
 
+      my_xlib="$func_basename_result"
37290
 
+      my_xlib_u=$my_xlib
37291
 
+      while :; do
37292
 
+        case " $extracted_archives " in
37293
 
+       *" $my_xlib_u "*)
37294
 
+         func_arith $extracted_serial + 1
37295
 
+         extracted_serial=$func_arith_result
37296
 
+         my_xlib_u=lt$extracted_serial-$my_xlib ;;
37297
 
+       *) break ;;
37298
 
+       esac
37299
 
+      done
37300
 
+      extracted_archives="$extracted_archives $my_xlib_u"
37301
 
+      my_xdir="$my_gentop/$my_xlib_u"
37302
 
+
37303
 
+      func_mkdir_p "$my_xdir"
37304
 
+
37305
 
+      case $host in
37306
 
+      *-darwin*)
37307
 
+       func_verbose "Extracting $my_xabs"
37308
 
+       # Do not bother doing anything if just a dry run
37309
 
+       $opt_dry_run || {
37310
 
+         darwin_orig_dir=`pwd`
37311
 
+         cd $my_xdir || exit $?
37312
 
+         darwin_archive=$my_xabs
37313
 
+         darwin_curdir=`pwd`
37314
 
+         darwin_base_archive=`basename "$darwin_archive"`
37315
 
+         darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true`
37316
 
+         if test -n "$darwin_arches"; then
37317
 
+           darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'`
37318
 
+           darwin_arch=
37319
 
+           func_verbose "$darwin_base_archive has multiple architectures $darwin_arches"
37320
 
+           for darwin_arch in  $darwin_arches ; do
37321
 
+             func_mkdir_p "unfat-$$/${darwin_base_archive}-${darwin_arch}"
37322
 
+             $LIPO -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}"
37323
 
+             cd "unfat-$$/${darwin_base_archive}-${darwin_arch}"
37324
 
+             func_extract_an_archive "`pwd`" "${darwin_base_archive}"
37325
 
+             cd "$darwin_curdir"
37326
 
+             $RM "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}"
37327
 
+           done # $darwin_arches
37328
 
+            ## Okay now we've a bunch of thin objects, gotta fatten them up :)
37329
 
+           darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u`
37330
 
+           darwin_file=
37331
 
+           darwin_files=
37332
 
+           for darwin_file in $darwin_filelist; do
37333
 
+             darwin_files=`find unfat-$$ -name $darwin_file -print | $NL2SP`
37334
 
+             $LIPO -create -output "$darwin_file" $darwin_files
37335
 
+           done # $darwin_filelist
37336
 
+           $RM -rf unfat-$$
37337
 
+           cd "$darwin_orig_dir"
37338
 
+         else
37339
 
+           cd $darwin_orig_dir
37340
 
+           func_extract_an_archive "$my_xdir" "$my_xabs"
37341
 
+         fi # $darwin_arches
37342
 
+       } # !$opt_dry_run
37343
 
+       ;;
37344
 
+      *)
37345
 
+        func_extract_an_archive "$my_xdir" "$my_xabs"
37346
 
+       ;;
37347
 
+      esac
37348
 
+      my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP`
37349
 
+    done
37350
 
+
37351
 
+    func_extract_archives_result="$my_oldobjs"
37352
 
+}
37353
 
+
37354
 
+
37355
 
+
37356
 
+# func_emit_wrapper_part1 [arg=no]
37357
 
+#
37358
 
+# Emit the first part of a libtool wrapper script on stdout.
37359
 
+# For more information, see the description associated with
37360
 
+# func_emit_wrapper(), below.
37361
 
+func_emit_wrapper_part1 ()
37362
 
+{
37363
 
+       func_emit_wrapper_part1_arg1=no
37364
 
+       if test -n "$1" ; then
37365
 
+         func_emit_wrapper_part1_arg1=$1
37366
 
+       fi
37367
 
+
37368
 
+       $ECHO "\
37369
 
+#! $SHELL
37370
 
+
37371
 
+# $output - temporary wrapper script for $objdir/$outputname
37372
 
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
37373
 
+#
37374
 
+# The $output program cannot be directly executed until all the libtool
37375
 
+# libraries that it depends on are installed.
37376
 
+#
37377
 
+# This wrapper script should never be moved out of the build directory.
37378
 
+# If it is, it will not operate correctly.
37379
 
+
37380
 
+# Sed substitution that helps us do robust quoting.  It backslashifies
37381
 
+# metacharacters that are still active within double-quoted strings.
37382
 
+Xsed='${SED} -e 1s/^X//'
37383
 
+sed_quote_subst='$sed_quote_subst'
37384
 
+
37385
 
+# Be Bourne compatible
37386
 
+if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then
37387
 
+  emulate sh
37388
 
+  NULLCMD=:
37389
 
+  # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which
37390
 
+  # is contrary to our usage.  Disable this feature.
37391
 
+  alias -g '\${1+\"\$@\"}'='\"\$@\"'
37392
 
+  setopt NO_GLOB_SUBST
37393
 
+else
37394
 
+  case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac
37395
 
+fi
37396
 
+BIN_SH=xpg4; export BIN_SH # for Tru64
37397
 
+DUALCASE=1; export DUALCASE # for MKS sh
37398
 
+
37399
 
+# The HP-UX ksh and POSIX shell print the target directory to stdout
37400
 
+# if CDPATH is set.
37401
 
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
37402
 
+
37403
 
+relink_command=\"$relink_command\"
37404
 
+
37405
 
+# This environment variable determines our operation mode.
37406
 
+if test \"\$libtool_install_magic\" = \"$magic\"; then
37407
 
+  # install mode needs the following variables:
37408
 
+  generated_by_libtool_version='$macro_version'
37409
 
+  notinst_deplibs='$notinst_deplibs'
37410
 
+else
37411
 
+  # When we are sourced in execute mode, \$file and \$ECHO are already set.
37412
 
+  if test \"\$libtool_execute_magic\" != \"$magic\"; then
37413
 
+    ECHO=\"$qecho\"
37414
 
+    file=\"\$0\"
37415
 
+    # Make sure echo works.
37416
 
+    if test \"X\$1\" = X--no-reexec; then
37417
 
+      # Discard the --no-reexec flag, and continue.
37418
 
+      shift
37419
 
+    elif test \"X\`{ \$ECHO '\t'; } 2>/dev/null\`\" = 'X\t'; then
37420
 
+      # Yippee, \$ECHO works!
37421
 
+      :
37422
 
+    else
37423
 
+      # Restart under the correct shell, and then maybe \$ECHO will work.
37424
 
+      exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"}
37425
 
+    fi
37426
 
+  fi\
37427
 
+"
37428
 
+       $ECHO "\
37429
 
+
37430
 
+  # Find the directory that this script lives in.
37431
 
+  thisdir=\`\$ECHO \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\`
37432
 
+  test \"x\$thisdir\" = \"x\$file\" && thisdir=.
37433
 
+
37434
 
+  # Follow symbolic links until we get to the real thisdir.
37435
 
+  file=\`ls -ld \"\$file\" | ${SED} -n 's/.*-> //p'\`
37436
 
+  while test -n \"\$file\"; do
37437
 
+    destdir=\`\$ECHO \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\`
37438
 
+
37439
 
+    # If there was a directory component, then change thisdir.
37440
 
+    if test \"x\$destdir\" != \"x\$file\"; then
37441
 
+      case \"\$destdir\" in
37442
 
+      [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;;
37443
 
+      *) thisdir=\"\$thisdir/\$destdir\" ;;
37444
 
+      esac
37445
 
+    fi
37446
 
+
37447
 
+    file=\`\$ECHO \"X\$file\" | \$Xsed -e 's%^.*/%%'\`
37448
 
+    file=\`ls -ld \"\$thisdir/\$file\" | ${SED} -n 's/.*-> //p'\`
37449
 
+  done
37450
 
+"
37451
 
+}
37452
 
+# end: func_emit_wrapper_part1
37453
 
+
37454
 
+# func_emit_wrapper_part2 [arg=no]
37455
 
+#
37456
 
+# Emit the second part of a libtool wrapper script on stdout.
37457
 
+# For more information, see the description associated with
37458
 
+# func_emit_wrapper(), below.
37459
 
+func_emit_wrapper_part2 ()
37460
 
+{
37461
 
+       func_emit_wrapper_part2_arg1=no
37462
 
+       if test -n "$1" ; then
37463
 
+         func_emit_wrapper_part2_arg1=$1
37464
 
+       fi
37465
 
+
37466
 
+       $ECHO "\
37467
 
+
37468
 
+  # Usually 'no', except on cygwin/mingw when embedded into
37469
 
+  # the cwrapper.
37470
 
+  WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_part2_arg1
37471
 
+  if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then
37472
 
+    # special case for '.'
37473
 
+    if test \"\$thisdir\" = \".\"; then
37474
 
+      thisdir=\`pwd\`
37475
 
+    fi
37476
 
+    # remove .libs from thisdir
37477
 
+    case \"\$thisdir\" in
37478
 
+    *[\\\\/]$objdir ) thisdir=\`\$ECHO \"X\$thisdir\" | \$Xsed -e 's%[\\\\/][^\\\\/]*$%%'\` ;;
37479
 
+    $objdir )   thisdir=. ;;
37480
 
+    esac
37481
 
+  fi
37482
 
+
37483
 
+  # Try to get the absolute directory name.
37484
 
+  absdir=\`cd \"\$thisdir\" && pwd\`
37485
 
+  test -n \"\$absdir\" && thisdir=\"\$absdir\"
37486
 
+"
37487
 
+
37488
 
+       if test "$fast_install" = yes; then
37489
 
+         $ECHO "\
37490
 
+  program=lt-'$outputname'$exeext
37491
 
+  progdir=\"\$thisdir/$objdir\"
37492
 
+
37493
 
+  if test ! -f \"\$progdir/\$program\" ||
37494
 
+     { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\
37495
 
+       test \"X\$file\" != \"X\$progdir/\$program\"; }; then
37496
 
+
37497
 
+    file=\"\$\$-\$program\"
37498
 
+
37499
 
+    if test ! -d \"\$progdir\"; then
37500
 
+      $MKDIR \"\$progdir\"
37501
 
+    else
37502
 
+      $RM \"\$progdir/\$file\"
37503
 
+    fi"
37504
 
+
37505
 
+         $ECHO "\
37506
 
+
37507
 
+    # relink executable if necessary
37508
 
+    if test -n \"\$relink_command\"; then
37509
 
+      if relink_command_output=\`eval \$relink_command 2>&1\`; then :
37510
 
+      else
37511
 
+       $ECHO \"\$relink_command_output\" >&2
37512
 
+       $RM \"\$progdir/\$file\"
37513
 
+       exit 1
37514
 
+      fi
37515
 
+    fi
37516
 
+
37517
 
+    $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null ||
37518
 
+    { $RM \"\$progdir/\$program\";
37519
 
+      $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; }
37520
 
+    $RM \"\$progdir/\$file\"
37521
 
+  fi"
37522
 
+       else
37523
 
+         $ECHO "\
37524
 
+  program='$outputname'
37525
 
+  progdir=\"\$thisdir/$objdir\"
37526
 
+"
37527
 
+       fi
37528
 
+
37529
 
+       $ECHO "\
37530
 
+
37531
 
+  if test -f \"\$progdir/\$program\"; then"
37532
 
+
37533
 
+       # Export our shlibpath_var if we have one.
37534
 
+       if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
37535
 
+         $ECHO "\
37536
 
+    # Add our own library path to $shlibpath_var
37537
 
+    $shlibpath_var=\"$temp_rpath\$$shlibpath_var\"
37538
 
+
37539
 
+    # Some systems cannot cope with colon-terminated $shlibpath_var
37540
 
+    # The second colon is a workaround for a bug in BeOS R4 sed
37541
 
+    $shlibpath_var=\`\$ECHO \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\`
37542
 
+
37543
 
+    export $shlibpath_var
37544
 
+"
37545
 
+       fi
37546
 
+
37547
 
+       # fixup the dll searchpath if we need to.
37548
 
+       if test -n "$dllsearchpath"; then
37549
 
+         $ECHO "\
37550
 
+    # Add the dll search path components to the executable PATH
37551
 
+    PATH=$dllsearchpath:\$PATH
37552
 
+"
37553
 
+       fi
37554
 
+
37555
 
+       $ECHO "\
37556
 
+    if test \"\$libtool_execute_magic\" != \"$magic\"; then
37557
 
+      # Run the actual program with our arguments.
37558
 
+"
37559
 
+       case $host in
37560
 
+       # Backslashes separate directories on plain windows
37561
 
+       *-*-mingw | *-*-os2* | *-cegcc*)
37562
 
+         $ECHO "\
37563
 
+      exec \"\$progdir\\\\\$program\" \${1+\"\$@\"}
37564
 
+"
37565
 
+         ;;
37566
 
+
37567
 
+       *)
37568
 
+         $ECHO "\
37569
 
+      exec \"\$progdir/\$program\" \${1+\"\$@\"}
37570
 
+"
37571
 
+         ;;
37572
 
+       esac
37573
 
+       $ECHO "\
37574
 
+      \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2
37575
 
+      exit 1
37576
 
+    fi
37577
 
+  else
37578
 
+    # The program doesn't exist.
37579
 
+    \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2
37580
 
+    \$ECHO \"This script is just a wrapper for \$program.\" 1>&2
37581
 
+    $ECHO \"See the $PACKAGE documentation for more information.\" 1>&2
37582
 
+    exit 1
37583
 
+  fi
37584
 
+fi\
37585
 
+"
37586
 
+}
37587
 
+# end: func_emit_wrapper_part2
37588
 
+
37589
 
+
37590
 
+# func_emit_wrapper [arg=no]
37591
 
+#
37592
 
+# Emit a libtool wrapper script on stdout.
37593
 
+# Don't directly open a file because we may want to
37594
 
+# incorporate the script contents within a cygwin/mingw
37595
 
+# wrapper executable.  Must ONLY be called from within
37596
 
+# func_mode_link because it depends on a number of variables
37597
 
+# set therein.
37598
 
+#
37599
 
+# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR
37600
 
+# variable will take.  If 'yes', then the emitted script
37601
 
+# will assume that the directory in which it is stored is
37602
 
+# the $objdir directory.  This is a cygwin/mingw-specific
37603
 
+# behavior.
37604
 
+func_emit_wrapper ()
37605
 
+{
37606
 
+       func_emit_wrapper_arg1=no
37607
 
+       if test -n "$1" ; then
37608
 
+         func_emit_wrapper_arg1=$1
37609
 
+       fi
37610
 
+
37611
 
+       # split this up so that func_emit_cwrapperexe_src
37612
 
+       # can call each part independently.
37613
 
+       func_emit_wrapper_part1 "${func_emit_wrapper_arg1}"
37614
 
+       func_emit_wrapper_part2 "${func_emit_wrapper_arg1}"
37615
 
+}
37616
 
+
37617
 
+
37618
 
+# func_to_host_path arg
37619
 
+#
37620
 
+# Convert paths to host format when used with build tools.
37621
 
+# Intended for use with "native" mingw (where libtool itself
37622
 
+# is running under the msys shell), or in the following cross-
37623
 
+# build environments:
37624
 
+#    $build          $host
37625
 
+#    mingw (msys)    mingw  [e.g. native]
37626
 
+#    cygwin          mingw
37627
 
+#    *nix + wine     mingw
37628
 
+# where wine is equipped with the `winepath' executable.
37629
 
+# In the native mingw case, the (msys) shell automatically
37630
 
+# converts paths for any non-msys applications it launches,
37631
 
+# but that facility isn't available from inside the cwrapper.
37632
 
+# Similar accommodations are necessary for $host mingw and
37633
 
+# $build cygwin.  Calling this function does no harm for other
37634
 
+# $host/$build combinations not listed above.
37635
 
+#
37636
 
+# ARG is the path (on $build) that should be converted to
37637
 
+# the proper representation for $host. The result is stored
37638
 
+# in $func_to_host_path_result.
37639
 
+func_to_host_path ()
37640
 
+{
37641
 
+  func_to_host_path_result="$1"
37642
 
+  if test -n "$1" ; then
37643
 
+    case $host in
37644
 
+      *mingw* )
37645
 
+        lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g'
37646
 
+        case $build in
37647
 
+          *mingw* ) # actually, msys
37648
 
+            # awkward: cmd appends spaces to result
37649
 
+            lt_sed_strip_trailing_spaces="s/[ ]*\$//"
37650
 
+            func_to_host_path_tmp1=`( cmd //c echo "$1" |\
37651
 
+              $SED -e "$lt_sed_strip_trailing_spaces" ) 2>/dev/null || echo ""`
37652
 
+            func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\
37653
 
+              $SED -e "$lt_sed_naive_backslashify"`
37654
 
+            ;;
37655
 
+          *cygwin* )
37656
 
+            func_to_host_path_tmp1=`cygpath -w "$1"`
37657
 
+            func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\
37658
 
+              $SED -e "$lt_sed_naive_backslashify"`
37659
 
+            ;;
37660
 
+          * )
37661
 
+            # Unfortunately, winepath does not exit with a non-zero
37662
 
+            # error code, so we are forced to check the contents of
37663
 
+            # stdout. On the other hand, if the command is not
37664
 
+            # found, the shell will set an exit code of 127 and print
37665
 
+            # *an error message* to stdout. So we must check for both
37666
 
+            # error code of zero AND non-empty stdout, which explains
37667
 
+            # the odd construction:
37668
 
+            func_to_host_path_tmp1=`winepath -w "$1" 2>/dev/null`
37669
 
+            if test "$?" -eq 0 && test -n "${func_to_host_path_tmp1}"; then
37670
 
+              func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\
37671
 
+                $SED -e "$lt_sed_naive_backslashify"`
37672
 
+            else
37673
 
+              # Allow warning below.
37674
 
+              func_to_host_path_result=""
37675
 
+            fi
37676
 
+            ;;
37677
 
+        esac
37678
 
+        if test -z "$func_to_host_path_result" ; then
37679
 
+          func_error "Could not determine host path corresponding to"
37680
 
+          func_error "  '$1'"
37681
 
+          func_error "Continuing, but uninstalled executables may not work."
37682
 
+          # Fallback:
37683
 
+          func_to_host_path_result="$1"
37684
 
+        fi
37685
 
+        ;;
37686
 
+    esac
37687
 
+  fi
37688
 
+}
37689
 
+# end: func_to_host_path
37690
 
+
37691
 
+# func_to_host_pathlist arg
37692
 
+#
37693
 
+# Convert pathlists to host format when used with build tools.
37694
 
+# See func_to_host_path(), above. This function supports the
37695
 
+# following $build/$host combinations (but does no harm for
37696
 
+# combinations not listed here):
37697
 
+#    $build          $host
37698
 
+#    mingw (msys)    mingw  [e.g. native]
37699
 
+#    cygwin          mingw
37700
 
+#    *nix + wine     mingw
37701
 
+#
37702
 
+# Path separators are also converted from $build format to
37703
 
+# $host format. If ARG begins or ends with a path separator
37704
 
+# character, it is preserved (but converted to $host format)
37705
 
+# on output.
37706
 
+#
37707
 
+# ARG is a pathlist (on $build) that should be converted to
37708
 
+# the proper representation on $host. The result is stored
37709
 
+# in $func_to_host_pathlist_result.
37710
 
+func_to_host_pathlist ()
37711
 
+{
37712
 
+  func_to_host_pathlist_result="$1"
37713
 
+  if test -n "$1" ; then
37714
 
+    case $host in
37715
 
+      *mingw* )
37716
 
+        lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g'
37717
 
+        # Remove leading and trailing path separator characters from
37718
 
+        # ARG. msys behavior is inconsistent here, cygpath turns them
37719
 
+        # into '.;' and ';.', and winepath ignores them completely.
37720
 
+        func_to_host_pathlist_tmp2="$1"
37721
 
+        # Once set for this call, this variable should not be
37722
 
+        # reassigned. It is used in tha fallback case.
37723
 
+        func_to_host_pathlist_tmp1=`echo "$func_to_host_pathlist_tmp2" |\
37724
 
+          $SED -e 's|^:*||' -e 's|:*$||'`
37725
 
+        case $build in
37726
 
+          *mingw* ) # Actually, msys.
37727
 
+            # Awkward: cmd appends spaces to result.
37728
 
+            lt_sed_strip_trailing_spaces="s/[ ]*\$//"
37729
 
+            func_to_host_pathlist_tmp2=`( cmd //c echo "$func_to_host_pathlist_tmp1" |\
37730
 
+              $SED -e "$lt_sed_strip_trailing_spaces" ) 2>/dev/null || echo ""`
37731
 
+            func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp2" |\
37732
 
+              $SED -e "$lt_sed_naive_backslashify"`
37733
 
+            ;;
37734
 
+          *cygwin* )
37735
 
+            func_to_host_pathlist_tmp2=`cygpath -w -p "$func_to_host_pathlist_tmp1"`
37736
 
+            func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp2" |\
37737
 
+              $SED -e "$lt_sed_naive_backslashify"`
37738
 
+            ;;
37739
 
+          * )
37740
 
+            # unfortunately, winepath doesn't convert pathlists
37741
 
+            func_to_host_pathlist_result=""
37742
 
+            func_to_host_pathlist_oldIFS=$IFS
37743
 
+            IFS=:
37744
 
+            for func_to_host_pathlist_f in $func_to_host_pathlist_tmp1 ; do
37745
 
+              IFS=$func_to_host_pathlist_oldIFS
37746
 
+              if test -n "$func_to_host_pathlist_f" ; then
37747
 
+                func_to_host_path "$func_to_host_pathlist_f"
37748
 
+                if test -n "$func_to_host_path_result" ; then
37749
 
+                  if test -z "$func_to_host_pathlist_result" ; then
37750
 
+                    func_to_host_pathlist_result="$func_to_host_path_result"
37751
 
+                  else
37752
 
+                    func_to_host_pathlist_result="$func_to_host_pathlist_result;$func_to_host_path_result"
37753
 
+                  fi
37754
 
+                fi
37755
 
+              fi
37756
 
+              IFS=:
37757
 
+            done
37758
 
+            IFS=$func_to_host_pathlist_oldIFS
37759
 
+            ;;
37760
 
+        esac
37761
 
+        if test -z "$func_to_host_pathlist_result" ; then
37762
 
+          func_error "Could not determine the host path(s) corresponding to"
37763
 
+          func_error "  '$1'"
37764
 
+          func_error "Continuing, but uninstalled executables may not work."
37765
 
+          # Fallback. This may break if $1 contains DOS-style drive
37766
 
+          # specifications. The fix is not to complicate the expression
37767
 
+          # below, but for the user to provide a working wine installation
37768
 
+          # with winepath so that path translation in the cross-to-mingw
37769
 
+          # case works properly.
37770
 
+          lt_replace_pathsep_nix_to_dos="s|:|;|g"
37771
 
+          func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp1" |\
37772
 
+            $SED -e "$lt_replace_pathsep_nix_to_dos"`
37773
 
+        fi
37774
 
+        # Now, add the leading and trailing path separators back
37775
 
+        case "$1" in
37776
 
+          :* ) func_to_host_pathlist_result=";$func_to_host_pathlist_result"
37777
 
+            ;;
37778
 
+        esac
37779
 
+        case "$1" in
37780
 
+          *: ) func_to_host_pathlist_result="$func_to_host_pathlist_result;"
37781
 
+            ;;
37782
 
+        esac
37783
 
+        ;;
37784
 
+    esac
37785
 
+  fi
37786
 
+}
37787
 
+# end: func_to_host_pathlist
37788
 
+
37789
 
+# func_emit_cwrapperexe_src
37790
 
+# emit the source code for a wrapper executable on stdout
37791
 
+# Must ONLY be called from within func_mode_link because
37792
 
+# it depends on a number of variable set therein.
37793
 
+func_emit_cwrapperexe_src ()
37794
 
+{
37795
 
+       cat <<EOF
37796
 
+
37797
 
+/* $cwrappersource - temporary wrapper executable for $objdir/$outputname
37798
 
+   Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
37799
 
+
37800
 
+   The $output program cannot be directly executed until all the libtool
37801
 
+   libraries that it depends on are installed.
37802
 
+
37803
 
+   This wrapper executable should never be moved out of the build directory.
37804
 
+   If it is, it will not operate correctly.
37805
 
+
37806
 
+   Currently, it simply execs the wrapper *script* "$SHELL $output",
37807
 
+   but could eventually absorb all of the scripts functionality and
37808
 
+   exec $objdir/$outputname directly.
37809
 
+*/
37810
 
+EOF
37811
 
+           cat <<"EOF"
37812
 
+#include <stdio.h>
37813
 
+#include <stdlib.h>
37814
 
+#ifdef _MSC_VER
37815
 
+# include <direct.h>
37816
 
+# include <process.h>
37817
 
+# include <io.h>
37818
 
+# define setmode _setmode
37819
 
+#else
37820
 
+# include <unistd.h>
37821
 
+# include <stdint.h>
37822
 
+# ifdef __CYGWIN__
37823
 
+#  include <io.h>
37824
 
+#  define HAVE_SETENV
37825
 
+#  ifdef __STRICT_ANSI__
37826
 
+char *realpath (const char *, char *);
37827
 
+int putenv (char *);
37828
 
+int setenv (const char *, const char *, int);
37829
 
+#  endif
37830
 
+# endif
37831
 
+#endif
37832
 
+#include <malloc.h>
37833
 
+#include <stdarg.h>
37834
 
+#include <assert.h>
37835
 
+#include <string.h>
37836
 
+#include <ctype.h>
37837
 
+#include <errno.h>
37838
 
+#include <fcntl.h>
37839
 
+#include <sys/stat.h>
37840
 
+
37841
 
+#if defined(PATH_MAX)
37842
 
+# define LT_PATHMAX PATH_MAX
37843
 
+#elif defined(MAXPATHLEN)
37844
 
+# define LT_PATHMAX MAXPATHLEN
37845
 
+#else
37846
 
+# define LT_PATHMAX 1024
37847
 
+#endif
37848
 
+
37849
 
+#ifndef S_IXOTH
37850
 
+# define S_IXOTH 0
37851
 
+#endif
37852
 
+#ifndef S_IXGRP
37853
 
+# define S_IXGRP 0
37854
 
+#endif
37855
 
+
37856
 
+#ifdef _MSC_VER
37857
 
+# define S_IXUSR _S_IEXEC
37858
 
+# define stat _stat
37859
 
+# ifndef _INTPTR_T_DEFINED
37860
 
+#  define intptr_t int
37861
 
+# endif
37862
 
+#endif
37863
 
+
37864
 
+#ifndef DIR_SEPARATOR
37865
 
+# define DIR_SEPARATOR '/'
37866
 
+# define PATH_SEPARATOR ':'
37867
 
+#endif
37868
 
+
37869
 
+#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \
37870
 
+  defined (__OS2__)
37871
 
+# define HAVE_DOS_BASED_FILE_SYSTEM
37872
 
+# define FOPEN_WB "wb"
37873
 
+# ifndef DIR_SEPARATOR_2
37874
 
+#  define DIR_SEPARATOR_2 '\\'
37875
 
+# endif
37876
 
+# ifndef PATH_SEPARATOR_2
37877
 
+#  define PATH_SEPARATOR_2 ';'
37878
 
+# endif
37879
 
+#endif
37880
 
+
37881
 
+#ifndef DIR_SEPARATOR_2
37882
 
+# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR)
37883
 
+#else /* DIR_SEPARATOR_2 */
37884
 
+# define IS_DIR_SEPARATOR(ch) \
37885
 
+       (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2))
37886
 
+#endif /* DIR_SEPARATOR_2 */
37887
 
+
37888
 
+#ifndef PATH_SEPARATOR_2
37889
 
+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR)
37890
 
+#else /* PATH_SEPARATOR_2 */
37891
 
+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2)
37892
 
+#endif /* PATH_SEPARATOR_2 */
37893
 
+
37894
 
+#ifdef __CYGWIN__
37895
 
+# define FOPEN_WB "wb"
37896
 
+#endif
37897
 
+
37898
 
+#ifndef FOPEN_WB
37899
 
+# define FOPEN_WB "w"
37900
 
+#endif
37901
 
+#ifndef _O_BINARY
37902
 
+# define _O_BINARY 0
37903
 
+#endif
37904
 
+
37905
 
+#define XMALLOC(type, num)      ((type *) xmalloc ((num) * sizeof(type)))
37906
 
+#define XFREE(stale) do { \
37907
 
+  if (stale) { free ((void *) stale); stale = 0; } \
37908
 
+} while (0)
37909
 
+
37910
 
+#undef LTWRAPPER_DEBUGPRINTF
37911
 
+#if defined DEBUGWRAPPER
37912
 
+# define LTWRAPPER_DEBUGPRINTF(args) ltwrapper_debugprintf args
37913
 
+static void
37914
 
+ltwrapper_debugprintf (const char *fmt, ...)
37915
 
+{
37916
 
+    va_list args;
37917
 
+    va_start (args, fmt);
37918
 
+    (void) vfprintf (stderr, fmt, args);
37919
 
+    va_end (args);
37920
 
+}
37921
 
+#else
37922
 
+# define LTWRAPPER_DEBUGPRINTF(args)
37923
 
+#endif
37924
 
+
37925
 
+const char *program_name = NULL;
37926
 
+
37927
 
+void *xmalloc (size_t num);
37928
 
+char *xstrdup (const char *string);
37929
 
+const char *base_name (const char *name);
37930
 
+char *find_executable (const char *wrapper);
37931
 
+char *chase_symlinks (const char *pathspec);
37932
 
+int make_executable (const char *path);
37933
 
+int check_executable (const char *path);
37934
 
+char *strendzap (char *str, const char *pat);
37935
 
+void lt_fatal (const char *message, ...);
37936
 
+void lt_setenv (const char *name, const char *value);
37937
 
+char *lt_extend_str (const char *orig_value, const char *add, int to_end);
37938
 
+void lt_opt_process_env_set (const char *arg);
37939
 
+void lt_opt_process_env_prepend (const char *arg);
37940
 
+void lt_opt_process_env_append (const char *arg);
37941
 
+int lt_split_name_value (const char *arg, char** name, char** value);
37942
 
+void lt_update_exe_path (const char *name, const char *value);
37943
 
+void lt_update_lib_path (const char *name, const char *value);
37944
 
+
37945
 
+static const char *script_text_part1 =
37946
 
+EOF
37947
 
+
37948
 
+           func_emit_wrapper_part1 yes |
37949
 
+               $SED -e 's/\([\\"]\)/\\\1/g' \
37950
 
+                    -e 's/^/  "/' -e 's/$/\\n"/'
37951
 
+           echo ";"
37952
 
+           cat <<EOF
37953
 
+
37954
 
+static const char *script_text_part2 =
37955
 
+EOF
37956
 
+           func_emit_wrapper_part2 yes |
37957
 
+               $SED -e 's/\([\\"]\)/\\\1/g' \
37958
 
+                    -e 's/^/  "/' -e 's/$/\\n"/'
37959
 
+           echo ";"
37960
 
+
37961
 
+           cat <<EOF
37962
 
+const char * MAGIC_EXE = "$magic_exe";
37963
 
+const char * LIB_PATH_VARNAME = "$shlibpath_var";
37964
 
+EOF
37965
 
+
37966
 
+           if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
37967
 
+              func_to_host_pathlist "$temp_rpath"
37968
 
+             cat <<EOF
37969
 
+const char * LIB_PATH_VALUE   = "$func_to_host_pathlist_result";
37970
 
+EOF
37971
 
+           else
37972
 
+             cat <<"EOF"
37973
 
+const char * LIB_PATH_VALUE   = "";
37974
 
+EOF
37975
 
+           fi
37976
 
+
37977
 
+           if test -n "$dllsearchpath"; then
37978
 
+              func_to_host_pathlist "$dllsearchpath:"
37979
 
+             cat <<EOF
37980
 
+const char * EXE_PATH_VARNAME = "PATH";
37981
 
+const char * EXE_PATH_VALUE   = "$func_to_host_pathlist_result";
37982
 
+EOF
37983
 
+           else
37984
 
+             cat <<"EOF"
37985
 
+const char * EXE_PATH_VARNAME = "";
37986
 
+const char * EXE_PATH_VALUE   = "";
37987
 
+EOF
37988
 
+           fi
37989
 
+
37990
 
+           if test "$fast_install" = yes; then
37991
 
+             cat <<EOF
37992
 
+const char * TARGET_PROGRAM_NAME = "lt-$outputname"; /* hopefully, no .exe */
37993
 
+EOF
37994
 
+           else
37995
 
+             cat <<EOF
37996
 
+const char * TARGET_PROGRAM_NAME = "$outputname"; /* hopefully, no .exe */
37997
 
+EOF
37998
 
+           fi
37999
 
+
38000
 
+
38001
 
+           cat <<"EOF"
38002
 
+
38003
 
+#define LTWRAPPER_OPTION_PREFIX         "--lt-"
38004
 
+#define LTWRAPPER_OPTION_PREFIX_LENGTH  5
38005
 
+
38006
 
+static const size_t opt_prefix_len         = LTWRAPPER_OPTION_PREFIX_LENGTH;
38007
 
+static const char *ltwrapper_option_prefix = LTWRAPPER_OPTION_PREFIX;
38008
 
+
38009
 
+static const char *dumpscript_opt       = LTWRAPPER_OPTION_PREFIX "dump-script";
38010
 
+
38011
 
+static const size_t env_set_opt_len     = LTWRAPPER_OPTION_PREFIX_LENGTH + 7;
38012
 
+static const char *env_set_opt          = LTWRAPPER_OPTION_PREFIX "env-set";
38013
 
+  /* argument is putenv-style "foo=bar", value of foo is set to bar */
38014
 
+
38015
 
+static const size_t env_prepend_opt_len = LTWRAPPER_OPTION_PREFIX_LENGTH + 11;
38016
 
+static const char *env_prepend_opt      = LTWRAPPER_OPTION_PREFIX "env-prepend";
38017
 
+  /* argument is putenv-style "foo=bar", new value of foo is bar${foo} */
38018
 
+
38019
 
+static const size_t env_append_opt_len  = LTWRAPPER_OPTION_PREFIX_LENGTH + 10;
38020
 
+static const char *env_append_opt       = LTWRAPPER_OPTION_PREFIX "env-append";
38021
 
+  /* argument is putenv-style "foo=bar", new value of foo is ${foo}bar */
38022
 
+
38023
 
+int
38024
 
+main (int argc, char *argv[])
38025
 
+{
38026
 
+  char **newargz;
38027
 
+  int  newargc;
38028
 
+  char *tmp_pathspec;
38029
 
+  char *actual_cwrapper_path;
38030
 
+  char *actual_cwrapper_name;
38031
 
+  char *target_name;
38032
 
+  char *lt_argv_zero;
38033
 
+  intptr_t rval = 127;
38034
 
+
38035
 
+  int i;
38036
 
+
38037
 
+  program_name = (char *) xstrdup (base_name (argv[0]));
38038
 
+  LTWRAPPER_DEBUGPRINTF (("(main) argv[0]      : %s\n", argv[0]));
38039
 
+  LTWRAPPER_DEBUGPRINTF (("(main) program_name : %s\n", program_name));
38040
 
+
38041
 
+  /* very simple arg parsing; don't want to rely on getopt */
38042
 
+  for (i = 1; i < argc; i++)
38043
 
+    {
38044
 
+      if (strcmp (argv[i], dumpscript_opt) == 0)
38045
 
+       {
38046
 
+EOF
38047
 
+           case "$host" in
38048
 
+             *mingw* | *cygwin* )
38049
 
+               # make stdout use "unix" line endings
38050
 
+               echo "          setmode(1,_O_BINARY);"
38051
 
+               ;;
38052
 
+             esac
38053
 
+
38054
 
+           cat <<"EOF"
38055
 
+         printf ("%s", script_text_part1);
38056
 
+         printf ("%s", script_text_part2);
38057
 
+         return 0;
38058
 
+       }
38059
 
+    }
38060
 
+
38061
 
+  newargz = XMALLOC (char *, argc + 1);
38062
 
+  tmp_pathspec = find_executable (argv[0]);
38063
 
+  if (tmp_pathspec == NULL)
38064
 
+    lt_fatal ("Couldn't find %s", argv[0]);
38065
 
+  LTWRAPPER_DEBUGPRINTF (("(main) found exe (before symlink chase) at : %s\n",
38066
 
+                         tmp_pathspec));
38067
 
+
38068
 
+  actual_cwrapper_path = chase_symlinks (tmp_pathspec);
38069
 
+  LTWRAPPER_DEBUGPRINTF (("(main) found exe (after symlink chase) at : %s\n",
38070
 
+                         actual_cwrapper_path));
38071
 
+  XFREE (tmp_pathspec);
38072
 
+
38073
 
+  actual_cwrapper_name = xstrdup( base_name (actual_cwrapper_path));
38074
 
+  strendzap (actual_cwrapper_path, actual_cwrapper_name);
38075
 
+
38076
 
+  /* wrapper name transforms */
38077
 
+  strendzap (actual_cwrapper_name, ".exe");
38078
 
+  tmp_pathspec = lt_extend_str (actual_cwrapper_name, ".exe", 1);
38079
 
+  XFREE (actual_cwrapper_name);
38080
 
+  actual_cwrapper_name = tmp_pathspec;
38081
 
+  tmp_pathspec = 0;
38082
 
+
38083
 
+  /* target_name transforms -- use actual target program name; might have lt- prefix */
38084
 
+  target_name = xstrdup (base_name (TARGET_PROGRAM_NAME));
38085
 
+  strendzap (target_name, ".exe");
38086
 
+  tmp_pathspec = lt_extend_str (target_name, ".exe", 1);
38087
 
+  XFREE (target_name);
38088
 
+  target_name = tmp_pathspec;
38089
 
+  tmp_pathspec = 0;
38090
 
+
38091
 
+  LTWRAPPER_DEBUGPRINTF (("(main) libtool target name: %s\n",
38092
 
+                         target_name));
38093
 
+EOF
38094
 
+
38095
 
+           cat <<EOF
38096
 
+  newargz[0] =
38097
 
+    XMALLOC (char, (strlen (actual_cwrapper_path) +
38098
 
+                   strlen ("$objdir") + 1 + strlen (actual_cwrapper_name) + 1));
38099
 
+  strcpy (newargz[0], actual_cwrapper_path);
38100
 
+  strcat (newargz[0], "$objdir");
38101
 
+  strcat (newargz[0], "/");
38102
 
+EOF
38103
 
+
38104
 
+           cat <<"EOF"
38105
 
+  /* stop here, and copy so we don't have to do this twice */
38106
 
+  tmp_pathspec = xstrdup (newargz[0]);
38107
 
+
38108
 
+  /* do NOT want the lt- prefix here, so use actual_cwrapper_name */
38109
 
+  strcat (newargz[0], actual_cwrapper_name);
38110
 
+
38111
 
+  /* DO want the lt- prefix here if it exists, so use target_name */
38112
 
+  lt_argv_zero = lt_extend_str (tmp_pathspec, target_name, 1);
38113
 
+  XFREE (tmp_pathspec);
38114
 
+  tmp_pathspec = NULL;
38115
 
+EOF
38116
 
+
38117
 
+           case $host_os in
38118
 
+             mingw*)
38119
 
+           cat <<"EOF"
38120
 
+  {
38121
 
+    char* p;
38122
 
+    while ((p = strchr (newargz[0], '\\')) != NULL)
38123
 
+      {
38124
 
+       *p = '/';
38125
 
+      }
38126
 
+    while ((p = strchr (lt_argv_zero, '\\')) != NULL)
38127
 
+      {
38128
 
+       *p = '/';
38129
 
+      }
38130
 
+  }
38131
 
+EOF
38132
 
+           ;;
38133
 
+           esac
38134
 
+
38135
 
+           cat <<"EOF"
38136
 
+  XFREE (target_name);
38137
 
+  XFREE (actual_cwrapper_path);
38138
 
+  XFREE (actual_cwrapper_name);
38139
 
+
38140
 
+  lt_setenv ("BIN_SH", "xpg4"); /* for Tru64 */
38141
 
+  lt_setenv ("DUALCASE", "1");  /* for MSK sh */
38142
 
+  lt_update_lib_path (LIB_PATH_VARNAME, LIB_PATH_VALUE);
38143
 
+  lt_update_exe_path (EXE_PATH_VARNAME, EXE_PATH_VALUE);
38144
 
+
38145
 
+  newargc=0;
38146
 
+  for (i = 1; i < argc; i++)
38147
 
+    {
38148
 
+      if (strncmp (argv[i], env_set_opt, env_set_opt_len) == 0)
38149
 
+        {
38150
 
+          if (argv[i][env_set_opt_len] == '=')
38151
 
+            {
38152
 
+              const char *p = argv[i] + env_set_opt_len + 1;
38153
 
+              lt_opt_process_env_set (p);
38154
 
+            }
38155
 
+          else if (argv[i][env_set_opt_len] == '\0' && i + 1 < argc)
38156
 
+            {
38157
 
+              lt_opt_process_env_set (argv[++i]); /* don't copy */
38158
 
+            }
38159
 
+          else
38160
 
+            lt_fatal ("%s missing required argument", env_set_opt);
38161
 
+          continue;
38162
 
+        }
38163
 
+      if (strncmp (argv[i], env_prepend_opt, env_prepend_opt_len) == 0)
38164
 
+        {
38165
 
+          if (argv[i][env_prepend_opt_len] == '=')
38166
 
+            {
38167
 
+              const char *p = argv[i] + env_prepend_opt_len + 1;
38168
 
+              lt_opt_process_env_prepend (p);
38169
 
+            }
38170
 
+          else if (argv[i][env_prepend_opt_len] == '\0' && i + 1 < argc)
38171
 
+            {
38172
 
+              lt_opt_process_env_prepend (argv[++i]); /* don't copy */
38173
 
+            }
38174
 
+          else
38175
 
+            lt_fatal ("%s missing required argument", env_prepend_opt);
38176
 
+          continue;
38177
 
+        }
38178
 
+      if (strncmp (argv[i], env_append_opt, env_append_opt_len) == 0)
38179
 
+        {
38180
 
+          if (argv[i][env_append_opt_len] == '=')
38181
 
+            {
38182
 
+              const char *p = argv[i] + env_append_opt_len + 1;
38183
 
+              lt_opt_process_env_append (p);
38184
 
+            }
38185
 
+          else if (argv[i][env_append_opt_len] == '\0' && i + 1 < argc)
38186
 
+            {
38187
 
+              lt_opt_process_env_append (argv[++i]); /* don't copy */
38188
 
+            }
38189
 
+          else
38190
 
+            lt_fatal ("%s missing required argument", env_append_opt);
38191
 
+          continue;
38192
 
+        }
38193
 
+      if (strncmp (argv[i], ltwrapper_option_prefix, opt_prefix_len) == 0)
38194
 
+        {
38195
 
+          /* however, if there is an option in the LTWRAPPER_OPTION_PREFIX
38196
 
+             namespace, but it is not one of the ones we know about and
38197
 
+             have already dealt with, above (inluding dump-script), then
38198
 
+             report an error. Otherwise, targets might begin to believe
38199
 
+             they are allowed to use options in the LTWRAPPER_OPTION_PREFIX
38200
 
+             namespace. The first time any user complains about this, we'll
38201
 
+             need to make LTWRAPPER_OPTION_PREFIX a configure-time option
38202
 
+             or a configure.ac-settable value.
38203
 
+           */
38204
 
+          lt_fatal ("Unrecognized option in %s namespace: '%s'",
38205
 
+                    ltwrapper_option_prefix, argv[i]);
38206
 
+        }
38207
 
+      /* otherwise ... */
38208
 
+      newargz[++newargc] = xstrdup (argv[i]);
38209
 
+    }
38210
 
+  newargz[++newargc] = NULL;
38211
 
+
38212
 
+  LTWRAPPER_DEBUGPRINTF     (("(main) lt_argv_zero : %s\n", (lt_argv_zero ? lt_argv_zero : "<NULL>")));
38213
 
+  for (i = 0; i < newargc; i++)
38214
 
+    {
38215
 
+      LTWRAPPER_DEBUGPRINTF (("(main) newargz[%d]   : %s\n", i, (newargz[i] ? newargz[i] : "<NULL>")));
38216
 
+    }
38217
 
+
38218
 
+EOF
38219
 
+
38220
 
+           case $host_os in
38221
 
+             mingw*)
38222
 
+               cat <<"EOF"
38223
 
+  /* execv doesn't actually work on mingw as expected on unix */
38224
 
+  rval = _spawnv (_P_WAIT, lt_argv_zero, (const char * const *) newargz);
38225
 
+  if (rval == -1)
38226
 
+    {
38227
 
+      /* failed to start process */
38228
 
+      LTWRAPPER_DEBUGPRINTF (("(main) failed to launch target \"%s\": errno = %d\n", lt_argv_zero, errno));
38229
 
+      return 127;
38230
 
+    }
38231
 
+  return rval;
38232
 
+EOF
38233
 
+               ;;
38234
 
+             *)
38235
 
+               cat <<"EOF"
38236
 
+  execv (lt_argv_zero, newargz);
38237
 
+  return rval; /* =127, but avoids unused variable warning */
38238
 
+EOF
38239
 
+               ;;
38240
 
+           esac
38241
 
+
38242
 
+           cat <<"EOF"
38243
 
+}
38244
 
+
38245
 
+void *
38246
 
+xmalloc (size_t num)
38247
 
+{
38248
 
+  void *p = (void *) malloc (num);
38249
 
+  if (!p)
38250
 
+    lt_fatal ("Memory exhausted");
38251
 
+
38252
 
+  return p;
38253
 
+}
38254
 
+
38255
 
+char *
38256
 
+xstrdup (const char *string)
38257
 
+{
38258
 
+  return string ? strcpy ((char *) xmalloc (strlen (string) + 1),
38259
 
+                         string) : NULL;
38260
 
+}
38261
 
+
38262
 
+const char *
38263
 
+base_name (const char *name)
38264
 
+{
38265
 
+  const char *base;
38266
 
+
38267
 
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
38268
 
+  /* Skip over the disk name in MSDOS pathnames. */
38269
 
+  if (isalpha ((unsigned char) name[0]) && name[1] == ':')
38270
 
+    name += 2;
38271
 
+#endif
38272
 
+
38273
 
+  for (base = name; *name; name++)
38274
 
+    if (IS_DIR_SEPARATOR (*name))
38275
 
+      base = name + 1;
38276
 
+  return base;
38277
 
+}
38278
 
+
38279
 
+int
38280
 
+check_executable (const char *path)
38281
 
+{
38282
 
+  struct stat st;
38283
 
+
38284
 
+  LTWRAPPER_DEBUGPRINTF (("(check_executable)  : %s\n",
38285
 
+                         path ? (*path ? path : "EMPTY!") : "NULL!"));
38286
 
+  if ((!path) || (!*path))
38287
 
+    return 0;
38288
 
+
38289
 
+  if ((stat (path, &st) >= 0)
38290
 
+      && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)))
38291
 
+    return 1;
38292
 
+  else
38293
 
+    return 0;
38294
 
+}
38295
 
+
38296
 
+int
38297
 
+make_executable (const char *path)
38298
 
+{
38299
 
+  int rval = 0;
38300
 
+  struct stat st;
38301
 
+
38302
 
+  LTWRAPPER_DEBUGPRINTF (("(make_executable)   : %s\n",
38303
 
+                         path ? (*path ? path : "EMPTY!") : "NULL!"));
38304
 
+  if ((!path) || (!*path))
38305
 
+    return 0;
38306
 
+
38307
 
+  if (stat (path, &st) >= 0)
38308
 
+    {
38309
 
+      rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR);
38310
 
+    }
38311
 
+  return rval;
38312
 
+}
38313
 
+
38314
 
+/* Searches for the full path of the wrapper.  Returns
38315
 
+   newly allocated full path name if found, NULL otherwise
38316
 
+   Does not chase symlinks, even on platforms that support them.
38317
 
+*/
38318
 
+char *
38319
 
+find_executable (const char *wrapper)
38320
 
+{
38321
 
+  int has_slash = 0;
38322
 
+  const char *p;
38323
 
+  const char *p_next;
38324
 
+  /* static buffer for getcwd */
38325
 
+  char tmp[LT_PATHMAX + 1];
38326
 
+  int tmp_len;
38327
 
+  char *concat_name;
38328
 
+
38329
 
+  LTWRAPPER_DEBUGPRINTF (("(find_executable)   : %s\n",
38330
 
+                         wrapper ? (*wrapper ? wrapper : "EMPTY!") : "NULL!"));
38331
 
+
38332
 
+  if ((wrapper == NULL) || (*wrapper == '\0'))
38333
 
+    return NULL;
38334
 
+
38335
 
+  /* Absolute path? */
38336
 
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
38337
 
+  if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':')
38338
 
+    {
38339
 
+      concat_name = xstrdup (wrapper);
38340
 
+      if (check_executable (concat_name))
38341
 
+       return concat_name;
38342
 
+      XFREE (concat_name);
38343
 
+    }
38344
 
+  else
38345
 
+    {
38346
 
+#endif
38347
 
+      if (IS_DIR_SEPARATOR (wrapper[0]))
38348
 
+       {
38349
 
+         concat_name = xstrdup (wrapper);
38350
 
+         if (check_executable (concat_name))
38351
 
+           return concat_name;
38352
 
+         XFREE (concat_name);
38353
 
+       }
38354
 
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
38355
 
+    }
38356
 
+#endif
38357
 
+
38358
 
+  for (p = wrapper; *p; p++)
38359
 
+    if (*p == '/')
38360
 
+      {
38361
 
+       has_slash = 1;
38362
 
+       break;
38363
 
+      }
38364
 
+  if (!has_slash)
38365
 
+    {
38366
 
+      /* no slashes; search PATH */
38367
 
+      const char *path = getenv ("PATH");
38368
 
+      if (path != NULL)
38369
 
+       {
38370
 
+         for (p = path; *p; p = p_next)
38371
 
+           {
38372
 
+             const char *q;
38373
 
+             size_t p_len;
38374
 
+             for (q = p; *q; q++)
38375
 
+               if (IS_PATH_SEPARATOR (*q))
38376
 
+                 break;
38377
 
+             p_len = q - p;
38378
 
+             p_next = (*q == '\0' ? q : q + 1);
38379
 
+             if (p_len == 0)
38380
 
+               {
38381
 
+                 /* empty path: current directory */
38382
 
+                 if (getcwd (tmp, LT_PATHMAX) == NULL)
38383
 
+                   lt_fatal ("getcwd failed");
38384
 
+                 tmp_len = strlen (tmp);
38385
 
+                 concat_name =
38386
 
+                   XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);
38387
 
+                 memcpy (concat_name, tmp, tmp_len);
38388
 
+                 concat_name[tmp_len] = '/';
38389
 
+                 strcpy (concat_name + tmp_len + 1, wrapper);
38390
 
+               }
38391
 
+             else
38392
 
+               {
38393
 
+                 concat_name =
38394
 
+                   XMALLOC (char, p_len + 1 + strlen (wrapper) + 1);
38395
 
+                 memcpy (concat_name, p, p_len);
38396
 
+                 concat_name[p_len] = '/';
38397
 
+                 strcpy (concat_name + p_len + 1, wrapper);
38398
 
+               }
38399
 
+             if (check_executable (concat_name))
38400
 
+               return concat_name;
38401
 
+             XFREE (concat_name);
38402
 
+           }
38403
 
+       }
38404
 
+      /* not found in PATH; assume curdir */
38405
 
+    }
38406
 
+  /* Relative path | not found in path: prepend cwd */
38407
 
+  if (getcwd (tmp, LT_PATHMAX) == NULL)
38408
 
+    lt_fatal ("getcwd failed");
38409
 
+  tmp_len = strlen (tmp);
38410
 
+  concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);
38411
 
+  memcpy (concat_name, tmp, tmp_len);
38412
 
+  concat_name[tmp_len] = '/';
38413
 
+  strcpy (concat_name + tmp_len + 1, wrapper);
38414
 
+
38415
 
+  if (check_executable (concat_name))
38416
 
+    return concat_name;
38417
 
+  XFREE (concat_name);
38418
 
+  return NULL;
38419
 
+}
38420
 
+
38421
 
+char *
38422
 
+chase_symlinks (const char *pathspec)
38423
 
+{
38424
 
+#ifndef S_ISLNK
38425
 
+  return xstrdup (pathspec);
38426
 
+#else
38427
 
+  char buf[LT_PATHMAX];
38428
 
+  struct stat s;
38429
 
+  char *tmp_pathspec = xstrdup (pathspec);
38430
 
+  char *p;
38431
 
+  int has_symlinks = 0;
38432
 
+  while (strlen (tmp_pathspec) && !has_symlinks)
38433
 
+    {
38434
 
+      LTWRAPPER_DEBUGPRINTF (("checking path component for symlinks: %s\n",
38435
 
+                             tmp_pathspec));
38436
 
+      if (lstat (tmp_pathspec, &s) == 0)
38437
 
+       {
38438
 
+         if (S_ISLNK (s.st_mode) != 0)
38439
 
+           {
38440
 
+             has_symlinks = 1;
38441
 
+             break;
38442
 
+           }
38443
 
+
38444
 
+         /* search backwards for last DIR_SEPARATOR */
38445
 
+         p = tmp_pathspec + strlen (tmp_pathspec) - 1;
38446
 
+         while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))
38447
 
+           p--;
38448
 
+         if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))
38449
 
+           {
38450
 
+             /* no more DIR_SEPARATORS left */
38451
 
+             break;
38452
 
+           }
38453
 
+         *p = '\0';
38454
 
+       }
38455
 
+      else
38456
 
+       {
38457
 
+         char *errstr = strerror (errno);
38458
 
+         lt_fatal ("Error accessing file %s (%s)", tmp_pathspec, errstr);
38459
 
+       }
38460
 
+    }
38461
 
+  XFREE (tmp_pathspec);
38462
 
+
38463
 
+  if (!has_symlinks)
38464
 
+    {
38465
 
+      return xstrdup (pathspec);
38466
 
+    }
38467
 
+
38468
 
+  tmp_pathspec = realpath (pathspec, buf);
38469
 
+  if (tmp_pathspec == 0)
38470
 
+    {
38471
 
+      lt_fatal ("Could not follow symlinks for %s", pathspec);
38472
 
+    }
38473
 
+  return xstrdup (tmp_pathspec);
38474
 
+#endif
38475
 
+}
38476
 
+
38477
 
+char *
38478
 
+strendzap (char *str, const char *pat)
38479
 
+{
38480
 
+  size_t len, patlen;
38481
 
+
38482
 
+  assert (str != NULL);
38483
 
+  assert (pat != NULL);
38484
 
+
38485
 
+  len = strlen (str);
38486
 
+  patlen = strlen (pat);
38487
 
+
38488
 
+  if (patlen <= len)
38489
 
+    {
38490
 
+      str += len - patlen;
38491
 
+      if (strcmp (str, pat) == 0)
38492
 
+       *str = '\0';
38493
 
+    }
38494
 
+  return str;
38495
 
+}
38496
 
+
38497
 
+static void
38498
 
+lt_error_core (int exit_status, const char *mode,
38499
 
+              const char *message, va_list ap)
38500
 
+{
38501
 
+  fprintf (stderr, "%s: %s: ", program_name, mode);
38502
 
+  vfprintf (stderr, message, ap);
38503
 
+  fprintf (stderr, ".\n");
38504
 
+
38505
 
+  if (exit_status >= 0)
38506
 
+    exit (exit_status);
38507
 
+}
38508
 
+
38509
 
+void
38510
 
+lt_fatal (const char *message, ...)
38511
 
+{
38512
 
+  va_list ap;
38513
 
+  va_start (ap, message);
38514
 
+  lt_error_core (EXIT_FAILURE, "FATAL", message, ap);
38515
 
+  va_end (ap);
38516
 
+}
38517
 
+
38518
 
+void
38519
 
+lt_setenv (const char *name, const char *value)
38520
 
+{
38521
 
+  LTWRAPPER_DEBUGPRINTF (("(lt_setenv) setting '%s' to '%s'\n",
38522
 
+                          (name ? name : "<NULL>"),
38523
 
+                          (value ? value : "<NULL>")));
38524
 
+  {
38525
 
+#ifdef HAVE_SETENV
38526
 
+    /* always make a copy, for consistency with !HAVE_SETENV */
38527
 
+    char *str = xstrdup (value);
38528
 
+    setenv (name, str, 1);
38529
 
+#else
38530
 
+    int len = strlen (name) + 1 + strlen (value) + 1;
38531
 
+    char *str = XMALLOC (char, len);
38532
 
+    sprintf (str, "%s=%s", name, value);
38533
 
+    if (putenv (str) != EXIT_SUCCESS)
38534
 
+      {
38535
 
+        XFREE (str);
38536
 
+      }
38537
 
+#endif
38538
 
+  }
38539
 
+}
38540
 
+
38541
 
+char *
38542
 
+lt_extend_str (const char *orig_value, const char *add, int to_end)
38543
 
+{
38544
 
+  char *new_value;
38545
 
+  if (orig_value && *orig_value)
38546
 
+    {
38547
 
+      int orig_value_len = strlen (orig_value);
38548
 
+      int add_len = strlen (add);
38549
 
+      new_value = XMALLOC (char, add_len + orig_value_len + 1);
38550
 
+      if (to_end)
38551
 
+        {
38552
 
+          strcpy (new_value, orig_value);
38553
 
+          strcpy (new_value + orig_value_len, add);
38554
 
+        }
38555
 
+      else
38556
 
+        {
38557
 
+          strcpy (new_value, add);
38558
 
+          strcpy (new_value + add_len, orig_value);
38559
 
+        }
38560
 
+    }
38561
 
+  else
38562
 
+    {
38563
 
+      new_value = xstrdup (add);
38564
 
+    }
38565
 
+  return new_value;
38566
 
+}
38567
 
+
38568
 
+int
38569
 
+lt_split_name_value (const char *arg, char** name, char** value)
38570
 
+{
38571
 
+  const char *p;
38572
 
+  int len;
38573
 
+  if (!arg || !*arg)
38574
 
+    return 1;
38575
 
+
38576
 
+  p = strchr (arg, (int)'=');
38577
 
+
38578
 
+  if (!p)
38579
 
+    return 1;
38580
 
+
38581
 
+  *value = xstrdup (++p);
38582
 
+
38583
 
+  len = strlen (arg) - strlen (*value);
38584
 
+  *name = XMALLOC (char, len);
38585
 
+  strncpy (*name, arg, len-1);
38586
 
+  (*name)[len - 1] = '\0';
38587
 
+
38588
 
+  return 0;
38589
 
+}
38590
 
+
38591
 
+void
38592
 
+lt_opt_process_env_set (const char *arg)
38593
 
+{
38594
 
+  char *name = NULL;
38595
 
+  char *value = NULL;
38596
 
+
38597
 
+  if (lt_split_name_value (arg, &name, &value) != 0)
38598
 
+    {
38599
 
+      XFREE (name);
38600
 
+      XFREE (value);
38601
 
+      lt_fatal ("bad argument for %s: '%s'", env_set_opt, arg);
38602
 
+    }
38603
 
+
38604
 
+  lt_setenv (name, value);
38605
 
+  XFREE (name);
38606
 
+  XFREE (value);
38607
 
+}
38608
 
+
38609
 
+void
38610
 
+lt_opt_process_env_prepend (const char *arg)
38611
 
+{
38612
 
+  char *name = NULL;
38613
 
+  char *value = NULL;
38614
 
+  char *new_value = NULL;
38615
 
+
38616
 
+  if (lt_split_name_value (arg, &name, &value) != 0)
38617
 
+    {
38618
 
+      XFREE (name);
38619
 
+      XFREE (value);
38620
 
+      lt_fatal ("bad argument for %s: '%s'", env_prepend_opt, arg);
38621
 
+    }
38622
 
+
38623
 
+  new_value = lt_extend_str (getenv (name), value, 0);
38624
 
+  lt_setenv (name, new_value);
38625
 
+  XFREE (new_value);
38626
 
+  XFREE (name);
38627
 
+  XFREE (value);
38628
 
+}
38629
 
+
38630
 
+void
38631
 
+lt_opt_process_env_append (const char *arg)
38632
 
+{
38633
 
+  char *name = NULL;
38634
 
+  char *value = NULL;
38635
 
+  char *new_value = NULL;
38636
 
+
38637
 
+  if (lt_split_name_value (arg, &name, &value) != 0)
38638
 
+    {
38639
 
+      XFREE (name);
38640
 
+      XFREE (value);
38641
 
+      lt_fatal ("bad argument for %s: '%s'", env_append_opt, arg);
38642
 
+    }
38643
 
+
38644
 
+  new_value = lt_extend_str (getenv (name), value, 1);
38645
 
+  lt_setenv (name, new_value);
38646
 
+  XFREE (new_value);
38647
 
+  XFREE (name);
38648
 
+  XFREE (value);
38649
 
+}
38650
 
+
38651
 
+void
38652
 
+lt_update_exe_path (const char *name, const char *value)
38653
 
+{
38654
 
+  LTWRAPPER_DEBUGPRINTF (("(lt_update_exe_path) modifying '%s' by prepending '%s'\n",
38655
 
+                          (name ? name : "<NULL>"),
38656
 
+                          (value ? value : "<NULL>")));
38657
 
+
38658
 
+  if (name && *name && value && *value)
38659
 
+    {
38660
 
+      char *new_value = lt_extend_str (getenv (name), value, 0);
38661
 
+      /* some systems can't cope with a ':'-terminated path #' */
38662
 
+      int len = strlen (new_value);
38663
 
+      while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1]))
38664
 
+        {
38665
 
+          new_value[len-1] = '\0';
38666
 
+        }
38667
 
+      lt_setenv (name, new_value);
38668
 
+      XFREE (new_value);
38669
 
+    }
38670
 
+}
38671
 
+
38672
 
+void
38673
 
+lt_update_lib_path (const char *name, const char *value)
38674
 
+{
38675
 
+  LTWRAPPER_DEBUGPRINTF (("(lt_update_lib_path) modifying '%s' by prepending '%s'\n",
38676
 
+                          (name ? name : "<NULL>"),
38677
 
+                          (value ? value : "<NULL>")));
38678
 
+
38679
 
+  if (name && *name && value && *value)
38680
 
+    {
38681
 
+      char *new_value = lt_extend_str (getenv (name), value, 0);
38682
 
+      lt_setenv (name, new_value);
38683
 
+      XFREE (new_value);
38684
 
+    }
38685
 
+}
38686
 
+
38687
 
+
38688
 
+EOF
38689
 
+}
38690
 
+# end: func_emit_cwrapperexe_src
38691
 
+
38692
 
+# func_mode_link arg...
38693
 
+func_mode_link ()
38694
 
+{
38695
 
+    $opt_debug
38696
 
+    case $host in
38697
 
+    *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
38698
 
+      # It is impossible to link a dll without this setting, and
38699
 
+      # we shouldn't force the makefile maintainer to figure out
38700
 
+      # which system we are compiling for in order to pass an extra
38701
 
+      # flag for every libtool invocation.
38702
 
+      # allow_undefined=no
38703
 
+
38704
 
+      # FIXME: Unfortunately, there are problems with the above when trying
38705
 
+      # to make a dll which has undefined symbols, in which case not
38706
 
+      # even a static library is built.  For now, we need to specify
38707
 
+      # -no-undefined on the libtool link line when we can be certain
38708
 
+      # that all symbols are satisfied, otherwise we get a static library.
38709
 
+      allow_undefined=yes
38710
 
+      ;;
38711
 
+    *)
38712
 
+      allow_undefined=yes
38713
 
+      ;;
38714
 
+    esac
38715
 
+    libtool_args=$nonopt
38716
 
+    base_compile="$nonopt $@"
38717
 
+    compile_command=$nonopt
38718
 
+    finalize_command=$nonopt
38719
 
+
38720
 
+    compile_rpath=
38721
 
+    finalize_rpath=
38722
 
+    compile_shlibpath=
38723
 
+    finalize_shlibpath=
38724
 
+    convenience=
38725
 
+    old_convenience=
38726
 
+    deplibs=
38727
 
+    old_deplibs=
38728
 
+    compiler_flags=
38729
 
+    linker_flags=
38730
 
+    dllsearchpath=
38731
 
+    lib_search_path=`pwd`
38732
 
+    inst_prefix_dir=
38733
 
+    new_inherited_linker_flags=
38734
 
+
38735
 
+    avoid_version=no
38736
 
+    dlfiles=
38737
 
+    dlprefiles=
38738
 
+    dlself=no
38739
 
+    export_dynamic=no
38740
 
+    export_symbols=
38741
 
+    export_symbols_regex=
38742
 
+    generated=
38743
 
+    libobjs=
38744
 
+    ltlibs=
38745
 
+    module=no
38746
 
+    no_install=no
38747
 
+    objs=
38748
 
+    non_pic_objects=
38749
 
+    precious_files_regex=
38750
 
+    prefer_static_libs=no
38751
 
+    preload=no
38752
 
+    prev=
38753
 
+    prevarg=
38754
 
+    release=
38755
 
+    rpath=
38756
 
+    xrpath=
38757
 
+    perm_rpath=
38758
 
+    temp_rpath=
38759
 
+    thread_safe=no
38760
 
+    vinfo=
38761
 
+    vinfo_number=no
38762
 
+    weak_libs=
38763
 
+    single_module="${wl}-single_module"
38764
 
+    func_infer_tag $base_compile
38765
 
+
38766
 
+    # We need to know -static, to get the right output filenames.
38767
 
+    for arg
38768
 
+    do
38769
 
+      case $arg in
38770
 
+      -shared)
38771
 
+       test "$build_libtool_libs" != yes && \
38772
 
+         func_fatal_configuration "can not build a shared library"
38773
 
+       build_old_libs=no
38774
 
+       break
38775
 
+       ;;
38776
 
+      -all-static | -static | -static-libtool-libs)
38777
 
+       case $arg in
38778
 
+       -all-static)
38779
 
+         if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then
38780
 
+           func_warning "complete static linking is impossible in this configuration"
38781
 
+         fi
38782
 
+         if test -n "$link_static_flag"; then
38783
 
+           dlopen_self=$dlopen_self_static
38784
 
+         fi
38785
 
+         prefer_static_libs=yes
38786
 
+         ;;
38787
 
+       -static)
38788
 
+         if test -z "$pic_flag" && test -n "$link_static_flag"; then
38789
 
+           dlopen_self=$dlopen_self_static
38790
 
+         fi
38791
 
+         prefer_static_libs=built
38792
 
+         ;;
38793
 
+       -static-libtool-libs)
38794
 
+         if test -z "$pic_flag" && test -n "$link_static_flag"; then
38795
 
+           dlopen_self=$dlopen_self_static
38796
 
+         fi
38797
 
+         prefer_static_libs=yes
38798
 
+         ;;
38799
 
+       esac
38800
 
+       build_libtool_libs=no
38801
 
+       build_old_libs=yes
38802
 
+       break
38803
 
+       ;;
38804
 
+      esac
38805
 
+    done
38806
 
+
38807
 
+    # See if our shared archives depend on static archives.
38808
 
+    test -n "$old_archive_from_new_cmds" && build_old_libs=yes
38809
 
+
38810
 
+    # Go through the arguments, transforming them on the way.
38811
 
+    while test "$#" -gt 0; do
38812
 
+      arg="$1"
38813
 
+      shift
38814
 
+      func_quote_for_eval "$arg"
38815
 
+      qarg=$func_quote_for_eval_unquoted_result
38816
 
+      func_append libtool_args " $func_quote_for_eval_result"
38817
 
+
38818
 
+      # If the previous option needs an argument, assign it.
38819
 
+      if test -n "$prev"; then
38820
 
+       case $prev in
38821
 
+       output)
38822
 
+         func_append compile_command " @OUTPUT@"
38823
 
+         func_append finalize_command " @OUTPUT@"
38824
 
+         ;;
38825
 
+       esac
38826
 
+
38827
 
+       case $prev in
38828
 
+       dlfiles|dlprefiles)
38829
 
+         if test "$preload" = no; then
38830
 
+           # Add the symbol object into the linking commands.
38831
 
+           func_append compile_command " @SYMFILE@"
38832
 
+           func_append finalize_command " @SYMFILE@"
38833
 
+           preload=yes
38834
 
+         fi
38835
 
+         case $arg in
38836
 
+         *.la | *.lo) ;;  # We handle these cases below.
38837
 
+         force)
38838
 
+           if test "$dlself" = no; then
38839
 
+             dlself=needless
38840
 
+             export_dynamic=yes
38841
 
+           fi
38842
 
+           prev=
38843
 
+           continue
38844
 
+           ;;
38845
 
+         self)
38846
 
+           if test "$prev" = dlprefiles; then
38847
 
+             dlself=yes
38848
 
+           elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then
38849
 
+             dlself=yes
38850
 
+           else
38851
 
+             dlself=needless
38852
 
+             export_dynamic=yes
38853
 
+           fi
38854
 
+           prev=
38855
 
+           continue
38856
 
+           ;;
38857
 
+         *)
38858
 
+           if test "$prev" = dlfiles; then
38859
 
+             dlfiles="$dlfiles $arg"
38860
 
+           else
38861
 
+             dlprefiles="$dlprefiles $arg"
38862
 
+           fi
38863
 
+           prev=
38864
 
+           continue
38865
 
+           ;;
38866
 
+         esac
38867
 
+         ;;
38868
 
+       expsyms)
38869
 
+         export_symbols="$arg"
38870
 
+         test -f "$arg" \
38871
 
+           || func_fatal_error "symbol file \`$arg' does not exist"
38872
 
+         prev=
38873
 
+         continue
38874
 
+         ;;
38875
 
+       expsyms_regex)
38876
 
+         export_symbols_regex="$arg"
38877
 
+         prev=
38878
 
+         continue
38879
 
+         ;;
38880
 
+       framework)
38881
 
+         case $host in
38882
 
+           *-*-darwin*)
38883
 
+             case "$deplibs " in
38884
 
+               *" $qarg.ltframework "*) ;;
38885
 
+               *) deplibs="$deplibs $qarg.ltframework" # this is fixed later
38886
 
+                  ;;
38887
 
+             esac
38888
 
+             ;;
38889
 
+         esac
38890
 
+         prev=
38891
 
+         continue
38892
 
+         ;;
38893
 
+       inst_prefix)
38894
 
+         inst_prefix_dir="$arg"
38895
 
+         prev=
38896
 
+         continue
38897
 
+         ;;
38898
 
+       objectlist)
38899
 
+         if test -f "$arg"; then
38900
 
+           save_arg=$arg
38901
 
+           moreargs=
38902
 
+           for fil in `cat "$save_arg"`
38903
 
+           do
38904
 
+#            moreargs="$moreargs $fil"
38905
 
+             arg=$fil
38906
 
+             # A libtool-controlled object.
38907
 
+
38908
 
+             # Check to see that this really is a libtool object.
38909
 
+             if func_lalib_unsafe_p "$arg"; then
38910
 
+               pic_object=
38911
 
+               non_pic_object=
38912
 
+
38913
 
+               # Read the .lo file
38914
 
+               func_source "$arg"
38915
 
+
38916
 
+               if test -z "$pic_object" ||
38917
 
+                  test -z "$non_pic_object" ||
38918
 
+                  test "$pic_object" = none &&
38919
 
+                  test "$non_pic_object" = none; then
38920
 
+                 func_fatal_error "cannot find name of object for \`$arg'"
38921
 
+               fi
38922
 
+
38923
 
+               # Extract subdirectory from the argument.
38924
 
+               func_dirname "$arg" "/" ""
38925
 
+               xdir="$func_dirname_result"
38926
 
+
38927
 
+               if test "$pic_object" != none; then
38928
 
+                 # Prepend the subdirectory the object is found in.
38929
 
+                 pic_object="$xdir$pic_object"
38930
 
+
38931
 
+                 if test "$prev" = dlfiles; then
38932
 
+                   if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
38933
 
+                     dlfiles="$dlfiles $pic_object"
38934
 
+                     prev=
38935
 
+                     continue
38936
 
+                   else
38937
 
+                     # If libtool objects are unsupported, then we need to preload.
38938
 
+                     prev=dlprefiles
38939
 
+                   fi
38940
 
+                 fi
38941
 
+
38942
 
+                 # CHECK ME:  I think I busted this.  -Ossama
38943
 
+                 if test "$prev" = dlprefiles; then
38944
 
+                   # Preload the old-style object.
38945
 
+                   dlprefiles="$dlprefiles $pic_object"
38946
 
+                   prev=
38947
 
+                 fi
38948
 
+
38949
 
+                 # A PIC object.
38950
 
+                 func_append libobjs " $pic_object"
38951
 
+                 arg="$pic_object"
38952
 
+               fi
38953
 
+
38954
 
+               # Non-PIC object.
38955
 
+               if test "$non_pic_object" != none; then
38956
 
+                 # Prepend the subdirectory the object is found in.
38957
 
+                 non_pic_object="$xdir$non_pic_object"
38958
 
+
38959
 
+                 # A standard non-PIC object
38960
 
+                 func_append non_pic_objects " $non_pic_object"
38961
 
+                 if test -z "$pic_object" || test "$pic_object" = none ; then
38962
 
+                   arg="$non_pic_object"
38963
 
+                 fi
38964
 
+               else
38965
 
+                 # If the PIC object exists, use it instead.
38966
 
+                 # $xdir was prepended to $pic_object above.
38967
 
+                 non_pic_object="$pic_object"
38968
 
+                 func_append non_pic_objects " $non_pic_object"
38969
 
+               fi
38970
 
+             else
38971
 
+               # Only an error if not doing a dry-run.
38972
 
+               if $opt_dry_run; then
38973
 
+                 # Extract subdirectory from the argument.
38974
 
+                 func_dirname "$arg" "/" ""
38975
 
+                 xdir="$func_dirname_result"
38976
 
+
38977
 
+                 func_lo2o "$arg"
38978
 
+                 pic_object=$xdir$objdir/$func_lo2o_result
38979
 
+                 non_pic_object=$xdir$func_lo2o_result
38980
 
+                 func_append libobjs " $pic_object"
38981
 
+                 func_append non_pic_objects " $non_pic_object"
38982
 
+               else
38983
 
+                 func_fatal_error "\`$arg' is not a valid libtool object"
38984
 
+               fi
38985
 
+             fi
38986
 
+           done
38987
 
+         else
38988
 
+           func_fatal_error "link input file \`$arg' does not exist"
38989
 
+         fi
38990
 
+         arg=$save_arg
38991
 
+         prev=
38992
 
+         continue
38993
 
+         ;;
38994
 
+       precious_regex)
38995
 
+         precious_files_regex="$arg"
38996
 
+         prev=
38997
 
+         continue
38998
 
+         ;;
38999
 
+       release)
39000
 
+         release="-$arg"
39001
 
+         prev=
39002
 
+         continue
39003
 
+         ;;
39004
 
+       rpath | xrpath)
39005
 
+         # We need an absolute path.
39006
 
+         case $arg in
39007
 
+         [\\/]* | [A-Za-z]:[\\/]*) ;;
39008
 
+         *)
39009
 
+           func_fatal_error "only absolute run-paths are allowed"
39010
 
+           ;;
39011
 
+         esac
39012
 
+         if test "$prev" = rpath; then
39013
 
+           case "$rpath " in
39014
 
+           *" $arg "*) ;;
39015
 
+           *) rpath="$rpath $arg" ;;
39016
 
+           esac
39017
 
+         else
39018
 
+           case "$xrpath " in
39019
 
+           *" $arg "*) ;;
39020
 
+           *) xrpath="$xrpath $arg" ;;
39021
 
+           esac
39022
 
+         fi
39023
 
+         prev=
39024
 
+         continue
39025
 
+         ;;
39026
 
+       shrext)
39027
 
+         shrext_cmds="$arg"
39028
 
+         prev=
39029
 
+         continue
39030
 
+         ;;
39031
 
+       weak)
39032
 
+         weak_libs="$weak_libs $arg"
39033
 
+         prev=
39034
 
+         continue
39035
 
+         ;;
39036
 
+       xcclinker)
39037
 
+         linker_flags="$linker_flags $qarg"
39038
 
+         compiler_flags="$compiler_flags $qarg"
39039
 
+         prev=
39040
 
+         func_append compile_command " $qarg"
39041
 
+         func_append finalize_command " $qarg"
39042
 
+         continue
39043
 
+         ;;
39044
 
+       xcompiler)
39045
 
+         compiler_flags="$compiler_flags $qarg"
39046
 
+         prev=
39047
 
+         func_append compile_command " $qarg"
39048
 
+         func_append finalize_command " $qarg"
39049
 
+         continue
39050
 
+         ;;
39051
 
+       xlinker)
39052
 
+         linker_flags="$linker_flags $qarg"
39053
 
+         compiler_flags="$compiler_flags $wl$qarg"
39054
 
+         prev=
39055
 
+         func_append compile_command " $wl$qarg"
39056
 
+         func_append finalize_command " $wl$qarg"
39057
 
+         continue
39058
 
+         ;;
39059
 
+       *)
39060
 
+         eval "$prev=\"\$arg\""
39061
 
+         prev=
39062
 
+         continue
39063
 
+         ;;
39064
 
+       esac
39065
 
+      fi # test -n "$prev"
39066
 
+
39067
 
+      prevarg="$arg"
39068
 
+
39069
 
+      case $arg in
39070
 
+      -all-static)
39071
 
+       if test -n "$link_static_flag"; then
39072
 
+         # See comment for -static flag below, for more details.
39073
 
+         func_append compile_command " $link_static_flag"
39074
 
+         func_append finalize_command " $link_static_flag"
39075
 
+       fi
39076
 
+       continue
39077
 
+       ;;
39078
 
+
39079
 
+      -allow-undefined)
39080
 
+       # FIXME: remove this flag sometime in the future.
39081
 
+       func_fatal_error "\`-allow-undefined' must not be used because it is the default"
39082
 
+       ;;
39083
 
+
39084
 
+      -avoid-version)
39085
 
+       avoid_version=yes
39086
 
+       continue
39087
 
+       ;;
39088
 
+
39089
 
+      -dlopen)
39090
 
+       prev=dlfiles
39091
 
+       continue
39092
 
+       ;;
39093
 
+
39094
 
+      -dlpreopen)
39095
 
+       prev=dlprefiles
39096
 
+       continue
39097
 
+       ;;
39098
 
+
39099
 
+      -export-dynamic)
39100
 
+       export_dynamic=yes
39101
 
+       continue
39102
 
+       ;;
39103
 
+
39104
 
+      -export-symbols | -export-symbols-regex)
39105
 
+       if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
39106
 
+         func_fatal_error "more than one -exported-symbols argument is not allowed"
39107
 
+       fi
39108
 
+       if test "X$arg" = "X-export-symbols"; then
39109
 
+         prev=expsyms
39110
 
+       else
39111
 
+         prev=expsyms_regex
39112
 
+       fi
39113
 
+       continue
39114
 
+       ;;
39115
 
+
39116
 
+      -framework)
39117
 
+       prev=framework
39118
 
+       continue
39119
 
+       ;;
39120
 
+
39121
 
+      -inst-prefix-dir)
39122
 
+       prev=inst_prefix
39123
 
+       continue
39124
 
+       ;;
39125
 
+
39126
 
+      # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:*
39127
 
+      # so, if we see these flags be careful not to treat them like -L
39128
 
+      -L[A-Z][A-Z]*:*)
39129
 
+       case $with_gcc/$host in
39130
 
+       no/*-*-irix* | /*-*-irix*)
39131
 
+         func_append compile_command " $arg"
39132
 
+         func_append finalize_command " $arg"
39133
 
+         ;;
39134
 
+       esac
39135
 
+       continue
39136
 
+       ;;
39137
 
+
39138
 
+      -L*)
39139
 
+       func_stripname '-L' '' "$arg"
39140
 
+       dir=$func_stripname_result
39141
 
+       if test -z "$dir"; then
39142
 
+         if test "$#" -gt 0; then
39143
 
+           func_fatal_error "require no space between \`-L' and \`$1'"
39144
 
+         else
39145
 
+           func_fatal_error "need path for \`-L' option"
39146
 
+         fi
39147
 
+       fi
39148
 
+       # We need an absolute path.
39149
 
+       case $dir in
39150
 
+       [\\/]* | [A-Za-z]:[\\/]*) ;;
39151
 
+       *)
39152
 
+         absdir=`cd "$dir" && pwd`
39153
 
+         test -z "$absdir" && \
39154
 
+           func_fatal_error "cannot determine absolute directory name of \`$dir'"
39155
 
+         dir="$absdir"
39156
 
+         ;;
39157
 
+       esac
39158
 
+       case "$deplibs " in
39159
 
+       *" -L$dir "*) ;;
39160
 
+       *)
39161
 
+         deplibs="$deplibs -L$dir"
39162
 
+         lib_search_path="$lib_search_path $dir"
39163
 
+         ;;
39164
 
+       esac
39165
 
+       case $host in
39166
 
+       *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
39167
 
+         testbindir=`$ECHO "X$dir" | $Xsed -e 's*/lib$*/bin*'`
39168
 
+         case :$dllsearchpath: in
39169
 
+         *":$dir:"*) ;;
39170
 
+         ::) dllsearchpath=$dir;;
39171
 
+         *) dllsearchpath="$dllsearchpath:$dir";;
39172
 
+         esac
39173
 
+         case :$dllsearchpath: in
39174
 
+         *":$testbindir:"*) ;;
39175
 
+         ::) dllsearchpath=$testbindir;;
39176
 
+         *) dllsearchpath="$dllsearchpath:$testbindir";;
39177
 
+         esac
39178
 
+         ;;
39179
 
+       esac
39180
 
+       continue
39181
 
+       ;;
39182
 
+
39183
 
+      -l*)
39184
 
+       if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then
39185
 
+         case $host in
39186
 
+         *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc*)
39187
 
+           # These systems don't actually have a C or math library (as such)
39188
 
+           continue
39189
 
+           ;;
39190
 
+         *-*-os2*)
39191
 
+           # These systems don't actually have a C library (as such)
39192
 
+           test "X$arg" = "X-lc" && continue
39193
 
+           ;;
39194
 
+         *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
39195
 
+           # Do not include libc due to us having libc/libc_r.
39196
 
+           test "X$arg" = "X-lc" && continue
39197
 
+           ;;
39198
 
+         *-*-rhapsody* | *-*-darwin1.[012])
39199
 
+           # Rhapsody C and math libraries are in the System framework
39200
 
+           deplibs="$deplibs System.ltframework"
39201
 
+           continue
39202
 
+           ;;
39203
 
+         *-*-sco3.2v5* | *-*-sco5v6*)
39204
 
+           # Causes problems with __ctype
39205
 
+           test "X$arg" = "X-lc" && continue
39206
 
+           ;;
39207
 
+         *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
39208
 
+           # Compiler inserts libc in the correct place for threads to work
39209
 
+           test "X$arg" = "X-lc" && continue
39210
 
+           ;;
39211
 
+         esac
39212
 
+       elif test "X$arg" = "X-lc_r"; then
39213
 
+        case $host in
39214
 
+        *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
39215
 
+          # Do not include libc_r directly, use -pthread flag.
39216
 
+          continue
39217
 
+          ;;
39218
 
+        esac
39219
 
+       fi
39220
 
+       deplibs="$deplibs $arg"
39221
 
+       continue
39222
 
+       ;;
39223
 
+
39224
 
+      -module)
39225
 
+       module=yes
39226
 
+       continue
39227
 
+       ;;
39228
 
+
39229
 
+      # Tru64 UNIX uses -model [arg] to determine the layout of C++
39230
 
+      # classes, name mangling, and exception handling.
39231
 
+      # Darwin uses the -arch flag to determine output architecture.
39232
 
+      -model|-arch|-isysroot)
39233
 
+       compiler_flags="$compiler_flags $arg"
39234
 
+       func_append compile_command " $arg"
39235
 
+       func_append finalize_command " $arg"
39236
 
+       prev=xcompiler
39237
 
+       continue
39238
 
+       ;;
39239
 
+
39240
 
+      -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads)
39241
 
+       compiler_flags="$compiler_flags $arg"
39242
 
+       func_append compile_command " $arg"
39243
 
+       func_append finalize_command " $arg"
39244
 
+       case "$new_inherited_linker_flags " in
39245
 
+           *" $arg "*) ;;
39246
 
+           * ) new_inherited_linker_flags="$new_inherited_linker_flags $arg" ;;
39247
 
+       esac
39248
 
+       continue
39249
 
+       ;;
39250
 
+
39251
 
+      -multi_module)
39252
 
+       single_module="${wl}-multi_module"
39253
 
+       continue
39254
 
+       ;;
39255
 
+
39256
 
+      -no-fast-install)
39257
 
+       fast_install=no
39258
 
+       continue
39259
 
+       ;;
39260
 
+
39261
 
+      -no-install)
39262
 
+       case $host in
39263
 
+       *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*)
39264
 
+         # The PATH hackery in wrapper scripts is required on Windows
39265
 
+         # and Darwin in order for the loader to find any dlls it needs.
39266
 
+         func_warning "\`-no-install' is ignored for $host"
39267
 
+         func_warning "assuming \`-no-fast-install' instead"
39268
 
+         fast_install=no
39269
 
+         ;;
39270
 
+       *) no_install=yes ;;
39271
 
+       esac
39272
 
+       continue
39273
 
+       ;;
39274
 
+
39275
 
+      -no-undefined)
39276
 
+       allow_undefined=no
39277
 
+       continue
39278
 
+       ;;
39279
 
+
39280
 
+      -objectlist)
39281
 
+       prev=objectlist
39282
 
+       continue
39283
 
+       ;;
39284
 
+
39285
 
+      -o) prev=output ;;
39286
 
+
39287
 
+      -precious-files-regex)
39288
 
+       prev=precious_regex
39289
 
+       continue
39290
 
+       ;;
39291
 
+
39292
 
+      -release)
39293
 
+       prev=release
39294
 
+       continue
39295
 
+       ;;
39296
 
+
39297
 
+      -rpath)
39298
 
+       prev=rpath
39299
 
+       continue
39300
 
+       ;;
39301
 
+
39302
 
+      -R)
39303
 
+       prev=xrpath
39304
 
+       continue
39305
 
+       ;;
39306
 
+
39307
 
+      -R*)
39308
 
+       func_stripname '-R' '' "$arg"
39309
 
+       dir=$func_stripname_result
39310
 
+       # We need an absolute path.
39311
 
+       case $dir in
39312
 
+       [\\/]* | [A-Za-z]:[\\/]*) ;;
39313
 
+       *)
39314
 
+         func_fatal_error "only absolute run-paths are allowed"
39315
 
+         ;;
39316
 
+       esac
39317
 
+       case "$xrpath " in
39318
 
+       *" $dir "*) ;;
39319
 
+       *) xrpath="$xrpath $dir" ;;
39320
 
+       esac
39321
 
+       continue
39322
 
+       ;;
39323
 
+
39324
 
+      -shared)
39325
 
+       # The effects of -shared are defined in a previous loop.
39326
 
+       continue
39327
 
+       ;;
39328
 
+
39329
 
+      -shrext)
39330
 
+       prev=shrext
39331
 
+       continue
39332
 
+       ;;
39333
 
+
39334
 
+      -static | -static-libtool-libs)
39335
 
+       # The effects of -static are defined in a previous loop.
39336
 
+       # We used to do the same as -all-static on platforms that
39337
 
+       # didn't have a PIC flag, but the assumption that the effects
39338
 
+       # would be equivalent was wrong.  It would break on at least
39339
 
+       # Digital Unix and AIX.
39340
 
+       continue
39341
 
+       ;;
39342
 
+
39343
 
+      -thread-safe)
39344
 
+       thread_safe=yes
39345
 
+       continue
39346
 
+       ;;
39347
 
+
39348
 
+      -version-info)
39349
 
+       prev=vinfo
39350
 
+       continue
39351
 
+       ;;
39352
 
+
39353
 
+      -version-number)
39354
 
+       prev=vinfo
39355
 
+       vinfo_number=yes
39356
 
+       continue
39357
 
+       ;;
39358
 
+
39359
 
+      -weak)
39360
 
+        prev=weak
39361
 
+       continue
39362
 
+       ;;
39363
 
+
39364
 
+      -Wc,*)
39365
 
+       func_stripname '-Wc,' '' "$arg"
39366
 
+       args=$func_stripname_result
39367
 
+       arg=
39368
 
+       save_ifs="$IFS"; IFS=','
39369
 
+       for flag in $args; do
39370
 
+         IFS="$save_ifs"
39371
 
+          func_quote_for_eval "$flag"
39372
 
+         arg="$arg $wl$func_quote_for_eval_result"
39373
 
+         compiler_flags="$compiler_flags $func_quote_for_eval_result"
39374
 
+       done
39375
 
+       IFS="$save_ifs"
39376
 
+       func_stripname ' ' '' "$arg"
39377
 
+       arg=$func_stripname_result
39378
 
+       ;;
39379
 
+
39380
 
+      -Wl,*)
39381
 
+       func_stripname '-Wl,' '' "$arg"
39382
 
+       args=$func_stripname_result
39383
 
+       arg=
39384
 
+       save_ifs="$IFS"; IFS=','
39385
 
+       for flag in $args; do
39386
 
+         IFS="$save_ifs"
39387
 
+          func_quote_for_eval "$flag"
39388
 
+         arg="$arg $wl$func_quote_for_eval_result"
39389
 
+         compiler_flags="$compiler_flags $wl$func_quote_for_eval_result"
39390
 
+         linker_flags="$linker_flags $func_quote_for_eval_result"
39391
 
+       done
39392
 
+       IFS="$save_ifs"
39393
 
+       func_stripname ' ' '' "$arg"
39394
 
+       arg=$func_stripname_result
39395
 
+       ;;
39396
 
+
39397
 
+      -Xcompiler)
39398
 
+       prev=xcompiler
39399
 
+       continue
39400
 
+       ;;
39401
 
+
39402
 
+      -Xlinker)
39403
 
+       prev=xlinker
39404
 
+       continue
39405
 
+       ;;
39406
 
+
39407
 
+      -XCClinker)
39408
 
+       prev=xcclinker
39409
 
+       continue
39410
 
+       ;;
39411
 
+
39412
 
+      # -msg_* for osf cc
39413
 
+      -msg_*)
39414
 
+       func_quote_for_eval "$arg"
39415
 
+       arg="$func_quote_for_eval_result"
39416
 
+       ;;
39417
 
+
39418
 
+      # -64, -mips[0-9] enable 64-bit mode on the SGI compiler
39419
 
+      # -r[0-9][0-9]* specifies the processor on the SGI compiler
39420
 
+      # -xarch=*, -xtarget=* enable 64-bit mode on the Sun compiler
39421
 
+      # +DA*, +DD* enable 64-bit mode on the HP compiler
39422
 
+      # -q* pass through compiler args for the IBM compiler
39423
 
+      # -m*, -t[45]*, -txscale* pass through architecture-specific
39424
 
+      # compiler args for GCC
39425
 
+      # -F/path gives path to uninstalled frameworks, gcc on darwin
39426
 
+      # -p, -pg, --coverage, -fprofile-* pass through profiling flag for GCC
39427
 
+      # @file GCC response files
39428
 
+      -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \
39429
 
+      -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*)
39430
 
+        func_quote_for_eval "$arg"
39431
 
+       arg="$func_quote_for_eval_result"
39432
 
+        func_append compile_command " $arg"
39433
 
+        func_append finalize_command " $arg"
39434
 
+        compiler_flags="$compiler_flags $arg"
39435
 
+        continue
39436
 
+        ;;
39437
 
+
39438
 
+      # Some other compiler flag.
39439
 
+      -* | +*)
39440
 
+        func_quote_for_eval "$arg"
39441
 
+       arg="$func_quote_for_eval_result"
39442
 
+       ;;
39443
 
+
39444
 
+      *.$objext)
39445
 
+       # A standard object.
39446
 
+       objs="$objs $arg"
39447
 
+       ;;
39448
 
+
39449
 
+      *.lo)
39450
 
+       # A libtool-controlled object.
39451
 
+
39452
 
+       # Check to see that this really is a libtool object.
39453
 
+       if func_lalib_unsafe_p "$arg"; then
39454
 
+         pic_object=
39455
 
+         non_pic_object=
39456
 
+
39457
 
+         # Read the .lo file
39458
 
+         func_source "$arg"
39459
 
+
39460
 
+         if test -z "$pic_object" ||
39461
 
+            test -z "$non_pic_object" ||
39462
 
+            test "$pic_object" = none &&
39463
 
+            test "$non_pic_object" = none; then
39464
 
+           func_fatal_error "cannot find name of object for \`$arg'"
39465
 
+         fi
39466
 
+
39467
 
+         # Extract subdirectory from the argument.
39468
 
+         func_dirname "$arg" "/" ""
39469
 
+         xdir="$func_dirname_result"
39470
 
+
39471
 
+         if test "$pic_object" != none; then
39472
 
+           # Prepend the subdirectory the object is found in.
39473
 
+           pic_object="$xdir$pic_object"
39474
 
+
39475
 
+           if test "$prev" = dlfiles; then
39476
 
+             if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
39477
 
+               dlfiles="$dlfiles $pic_object"
39478
 
+               prev=
39479
 
+               continue
39480
 
+             else
39481
 
+               # If libtool objects are unsupported, then we need to preload.
39482
 
+               prev=dlprefiles
39483
 
+             fi
39484
 
+           fi
39485
 
+
39486
 
+           # CHECK ME:  I think I busted this.  -Ossama
39487
 
+           if test "$prev" = dlprefiles; then
39488
 
+             # Preload the old-style object.
39489
 
+             dlprefiles="$dlprefiles $pic_object"
39490
 
+             prev=
39491
 
+           fi
39492
 
+
39493
 
+           # A PIC object.
39494
 
+           func_append libobjs " $pic_object"
39495
 
+           arg="$pic_object"
39496
 
+         fi
39497
 
+
39498
 
+         # Non-PIC object.
39499
 
+         if test "$non_pic_object" != none; then
39500
 
+           # Prepend the subdirectory the object is found in.
39501
 
+           non_pic_object="$xdir$non_pic_object"
39502
 
+
39503
 
+           # A standard non-PIC object
39504
 
+           func_append non_pic_objects " $non_pic_object"
39505
 
+           if test -z "$pic_object" || test "$pic_object" = none ; then
39506
 
+             arg="$non_pic_object"
39507
 
+           fi
39508
 
+         else
39509
 
+           # If the PIC object exists, use it instead.
39510
 
+           # $xdir was prepended to $pic_object above.
39511
 
+           non_pic_object="$pic_object"
39512
 
+           func_append non_pic_objects " $non_pic_object"
39513
 
+         fi
39514
 
+       else
39515
 
+         # Only an error if not doing a dry-run.
39516
 
+         if $opt_dry_run; then
39517
 
+           # Extract subdirectory from the argument.
39518
 
+           func_dirname "$arg" "/" ""
39519
 
+           xdir="$func_dirname_result"
39520
 
+
39521
 
+           func_lo2o "$arg"
39522
 
+           pic_object=$xdir$objdir/$func_lo2o_result
39523
 
+           non_pic_object=$xdir$func_lo2o_result
39524
 
+           func_append libobjs " $pic_object"
39525
 
+           func_append non_pic_objects " $non_pic_object"
39526
 
+         else
39527
 
+           func_fatal_error "\`$arg' is not a valid libtool object"
39528
 
+         fi
39529
 
+       fi
39530
 
+       ;;
39531
 
+
39532
 
+      *.$libext)
39533
 
+       # An archive.
39534
 
+       deplibs="$deplibs $arg"
39535
 
+       old_deplibs="$old_deplibs $arg"
39536
 
+       continue
39537
 
+       ;;
39538
 
+
39539
 
+      *.la)
39540
 
+       # A libtool-controlled library.
39541
 
+
39542
 
+       if test "$prev" = dlfiles; then
39543
 
+         # This library was specified with -dlopen.
39544
 
+         dlfiles="$dlfiles $arg"
39545
 
+         prev=
39546
 
+       elif test "$prev" = dlprefiles; then
39547
 
+         # The library was specified with -dlpreopen.
39548
 
+         dlprefiles="$dlprefiles $arg"
39549
 
+         prev=
39550
 
+       else
39551
 
+         deplibs="$deplibs $arg"
39552
 
+       fi
39553
 
+       continue
39554
 
+       ;;
39555
 
+
39556
 
+      # Some other compiler argument.
39557
 
+      *)
39558
 
+       # Unknown arguments in both finalize_command and compile_command need
39559
 
+       # to be aesthetically quoted because they are evaled later.
39560
 
+       func_quote_for_eval "$arg"
39561
 
+       arg="$func_quote_for_eval_result"
39562
 
+       ;;
39563
 
+      esac # arg
39564
 
+
39565
 
+      # Now actually substitute the argument into the commands.
39566
 
+      if test -n "$arg"; then
39567
 
+       func_append compile_command " $arg"
39568
 
+       func_append finalize_command " $arg"
39569
 
+      fi
39570
 
+    done # argument parsing loop
39571
 
+
39572
 
+    test -n "$prev" && \
39573
 
+      func_fatal_help "the \`$prevarg' option requires an argument"
39574
 
+
39575
 
+    if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then
39576
 
+      eval arg=\"$export_dynamic_flag_spec\"
39577
 
+      func_append compile_command " $arg"
39578
 
+      func_append finalize_command " $arg"
39579
 
+    fi
39580
 
+
39581
 
+    oldlibs=
39582
 
+    # calculate the name of the file, without its directory
39583
 
+    func_basename "$output"
39584
 
+    outputname="$func_basename_result"
39585
 
+    libobjs_save="$libobjs"
39586
 
+
39587
 
+    if test -n "$shlibpath_var"; then
39588
 
+      # get the directories listed in $shlibpath_var
39589
 
+      eval shlib_search_path=\`\$ECHO \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\`
39590
 
+    else
39591
 
+      shlib_search_path=
39592
 
+    fi
39593
 
+    eval sys_lib_search_path=\"$sys_lib_search_path_spec\"
39594
 
+    eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\"
39595
 
+
39596
 
+    func_dirname "$output" "/" ""
39597
 
+    output_objdir="$func_dirname_result$objdir"
39598
 
+    # Create the object directory.
39599
 
+    func_mkdir_p "$output_objdir"
39600
 
+
39601
 
+    # Determine the type of output
39602
 
+    case $output in
39603
 
+    "")
39604
 
+      func_fatal_help "you must specify an output file"
39605
 
+      ;;
39606
 
+    *.$libext) linkmode=oldlib ;;
39607
 
+    *.lo | *.$objext) linkmode=obj ;;
39608
 
+    *.la) linkmode=lib ;;
39609
 
+    *) linkmode=prog ;; # Anything else should be a program.
39610
 
+    esac
39611
 
+
39612
 
+    specialdeplibs=
39613
 
+
39614
 
+    libs=
39615
 
+    # Find all interdependent deplibs by searching for libraries
39616
 
+    # that are linked more than once (e.g. -la -lb -la)
39617
 
+    for deplib in $deplibs; do
39618
 
+      if $opt_duplicate_deps ; then
39619
 
+       case "$libs " in
39620
 
+       *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
39621
 
+       esac
39622
 
+      fi
39623
 
+      libs="$libs $deplib"
39624
 
+    done
39625
 
+
39626
 
+    if test "$linkmode" = lib; then
39627
 
+      libs="$predeps $libs $compiler_lib_search_path $postdeps"
39628
 
+
39629
 
+      # Compute libraries that are listed more than once in $predeps
39630
 
+      # $postdeps and mark them as special (i.e., whose duplicates are
39631
 
+      # not to be eliminated).
39632
 
+      pre_post_deps=
39633
 
+      if $opt_duplicate_compiler_generated_deps; then
39634
 
+       for pre_post_dep in $predeps $postdeps; do
39635
 
+         case "$pre_post_deps " in
39636
 
+         *" $pre_post_dep "*) specialdeplibs="$specialdeplibs $pre_post_deps" ;;
39637
 
+         esac
39638
 
+         pre_post_deps="$pre_post_deps $pre_post_dep"
39639
 
+       done
39640
 
+      fi
39641
 
+      pre_post_deps=
39642
 
+    fi
39643
 
+
39644
 
+    deplibs=
39645
 
+    newdependency_libs=
39646
 
+    newlib_search_path=
39647
 
+    need_relink=no # whether we're linking any uninstalled libtool libraries
39648
 
+    notinst_deplibs= # not-installed libtool libraries
39649
 
+    notinst_path= # paths that contain not-installed libtool libraries
39650
 
+
39651
 
+    case $linkmode in
39652
 
+    lib)
39653
 
+       passes="conv dlpreopen link"
39654
 
+       for file in $dlfiles $dlprefiles; do
39655
 
+         case $file in
39656
 
+         *.la) ;;
39657
 
+         *)
39658
 
+           func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file"
39659
 
+           ;;
39660
 
+         esac
39661
 
+       done
39662
 
+       ;;
39663
 
+    prog)
39664
 
+       compile_deplibs=
39665
 
+       finalize_deplibs=
39666
 
+       alldeplibs=no
39667
 
+       newdlfiles=
39668
 
+       newdlprefiles=
39669
 
+       passes="conv scan dlopen dlpreopen link"
39670
 
+       ;;
39671
 
+    *)  passes="conv"
39672
 
+       ;;
39673
 
+    esac
39674
 
+
39675
 
+    for pass in $passes; do
39676
 
+      # The preopen pass in lib mode reverses $deplibs; put it back here
39677
 
+      # so that -L comes before libs that need it for instance...
39678
 
+      if test "$linkmode,$pass" = "lib,link"; then
39679
 
+       ## FIXME: Find the place where the list is rebuilt in the wrong
39680
 
+       ##        order, and fix it there properly
39681
 
+        tmp_deplibs=
39682
 
+       for deplib in $deplibs; do
39683
 
+         tmp_deplibs="$deplib $tmp_deplibs"
39684
 
+       done
39685
 
+       deplibs="$tmp_deplibs"
39686
 
+      fi
39687
 
+
39688
 
+      if test "$linkmode,$pass" = "lib,link" ||
39689
 
+        test "$linkmode,$pass" = "prog,scan"; then
39690
 
+       libs="$deplibs"
39691
 
+       deplibs=
39692
 
+      fi
39693
 
+      if test "$linkmode" = prog; then
39694
 
+       case $pass in
39695
 
+       dlopen) libs="$dlfiles" ;;
39696
 
+       dlpreopen) libs="$dlprefiles" ;;
39697
 
+       link)
39698
 
+         libs="$deplibs %DEPLIBS%"
39699
 
+         test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs"
39700
 
+         ;;
39701
 
+       esac
39702
 
+      fi
39703
 
+      if test "$linkmode,$pass" = "lib,dlpreopen"; then
39704
 
+       # Collect and forward deplibs of preopened libtool libs
39705
 
+       for lib in $dlprefiles; do
39706
 
+         # Ignore non-libtool-libs
39707
 
+         dependency_libs=
39708
 
+         case $lib in
39709
 
+         *.la) func_source "$lib" ;;
39710
 
+         esac
39711
 
+
39712
 
+         # Collect preopened libtool deplibs, except any this library
39713
 
+         # has declared as weak libs
39714
 
+         for deplib in $dependency_libs; do
39715
 
+            deplib_base=`$ECHO "X$deplib" | $Xsed -e "$basename"`
39716
 
+           case " $weak_libs " in
39717
 
+           *" $deplib_base "*) ;;
39718
 
+           *) deplibs="$deplibs $deplib" ;;
39719
 
+           esac
39720
 
+         done
39721
 
+       done
39722
 
+       libs="$dlprefiles"
39723
 
+      fi
39724
 
+      if test "$pass" = dlopen; then
39725
 
+       # Collect dlpreopened libraries
39726
 
+       save_deplibs="$deplibs"
39727
 
+       deplibs=
39728
 
+      fi
39729
 
+
39730
 
+      for deplib in $libs; do
39731
 
+       lib=
39732
 
+       found=no
39733
 
+       case $deplib in
39734
 
+       -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads)
39735
 
+         if test "$linkmode,$pass" = "prog,link"; then
39736
 
+           compile_deplibs="$deplib $compile_deplibs"
39737
 
+           finalize_deplibs="$deplib $finalize_deplibs"
39738
 
+         else
39739
 
+           compiler_flags="$compiler_flags $deplib"
39740
 
+           if test "$linkmode" = lib ; then
39741
 
+               case "$new_inherited_linker_flags " in
39742
 
+                   *" $deplib "*) ;;
39743
 
+                   * ) new_inherited_linker_flags="$new_inherited_linker_flags $deplib" ;;
39744
 
+               esac
39745
 
+           fi
39746
 
+         fi
39747
 
+         continue
39748
 
+         ;;
39749
 
+       -l*)
39750
 
+         if test "$linkmode" != lib && test "$linkmode" != prog; then
39751
 
+           func_warning "\`-l' is ignored for archives/objects"
39752
 
+           continue
39753
 
+         fi
39754
 
+         func_stripname '-l' '' "$deplib"
39755
 
+         name=$func_stripname_result
39756
 
+         if test "$linkmode" = lib; then
39757
 
+           searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path"
39758
 
+         else
39759
 
+           searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path"
39760
 
+         fi
39761
 
+         for searchdir in $searchdirs; do
39762
 
+           for search_ext in .la $std_shrext .so .a; do
39763
 
+             # Search the libtool library
39764
 
+             lib="$searchdir/lib${name}${search_ext}"
39765
 
+             if test -f "$lib"; then
39766
 
+               if test "$search_ext" = ".la"; then
39767
 
+                 found=yes
39768
 
+               else
39769
 
+                 found=no
39770
 
+               fi
39771
 
+               break 2
39772
 
+             fi
39773
 
+           done
39774
 
+         done
39775
 
+         if test "$found" != yes; then
39776
 
+           # deplib doesn't seem to be a libtool library
39777
 
+           if test "$linkmode,$pass" = "prog,link"; then
39778
 
+             compile_deplibs="$deplib $compile_deplibs"
39779
 
+             finalize_deplibs="$deplib $finalize_deplibs"
39780
 
+           else
39781
 
+             deplibs="$deplib $deplibs"
39782
 
+             test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
39783
 
+           fi
39784
 
+           continue
39785
 
+         else # deplib is a libtool library
39786
 
+           # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib,
39787
 
+           # We need to do some special things here, and not later.
39788
 
+           if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
39789
 
+             case " $predeps $postdeps " in
39790
 
+             *" $deplib "*)
39791
 
+               if func_lalib_p "$lib"; then
39792
 
+                 library_names=
39793
 
+                 old_library=
39794
 
+                 func_source "$lib"
39795
 
+                 for l in $old_library $library_names; do
39796
 
+                   ll="$l"
39797
 
+                 done
39798
 
+                 if test "X$ll" = "X$old_library" ; then # only static version available
39799
 
+                   found=no
39800
 
+                   func_dirname "$lib" "" "."
39801
 
+                   ladir="$func_dirname_result"
39802
 
+                   lib=$ladir/$old_library
39803
 
+                   if test "$linkmode,$pass" = "prog,link"; then
39804
 
+                     compile_deplibs="$deplib $compile_deplibs"
39805
 
+                     finalize_deplibs="$deplib $finalize_deplibs"
39806
 
+                   else
39807
 
+                     deplibs="$deplib $deplibs"
39808
 
+                     test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
39809
 
+                   fi
39810
 
+                   continue
39811
 
+                 fi
39812
 
+               fi
39813
 
+               ;;
39814
 
+             *) ;;
39815
 
+             esac
39816
 
+           fi
39817
 
+         fi
39818
 
+         ;; # -l
39819
 
+       *.ltframework)
39820
 
+         if test "$linkmode,$pass" = "prog,link"; then
39821
 
+           compile_deplibs="$deplib $compile_deplibs"
39822
 
+           finalize_deplibs="$deplib $finalize_deplibs"
39823
 
+         else
39824
 
+           deplibs="$deplib $deplibs"
39825
 
+           if test "$linkmode" = lib ; then
39826
 
+               case "$new_inherited_linker_flags " in
39827
 
+                   *" $deplib "*) ;;
39828
 
+                   * ) new_inherited_linker_flags="$new_inherited_linker_flags $deplib" ;;
39829
 
+               esac
39830
 
+           fi
39831
 
+         fi
39832
 
+         continue
39833
 
+         ;;
39834
 
+       -L*)
39835
 
+         case $linkmode in
39836
 
+         lib)
39837
 
+           deplibs="$deplib $deplibs"
39838
 
+           test "$pass" = conv && continue
39839
 
+           newdependency_libs="$deplib $newdependency_libs"
39840
 
+           func_stripname '-L' '' "$deplib"
39841
 
+           newlib_search_path="$newlib_search_path $func_stripname_result"
39842
 
+           ;;
39843
 
+         prog)
39844
 
+           if test "$pass" = conv; then
39845
 
+             deplibs="$deplib $deplibs"
39846
 
+             continue
39847
 
+           fi
39848
 
+           if test "$pass" = scan; then
39849
 
+             deplibs="$deplib $deplibs"
39850
 
+           else
39851
 
+             compile_deplibs="$deplib $compile_deplibs"
39852
 
+             finalize_deplibs="$deplib $finalize_deplibs"
39853
 
+           fi
39854
 
+           func_stripname '-L' '' "$deplib"
39855
 
+           newlib_search_path="$newlib_search_path $func_stripname_result"
39856
 
+           ;;
39857
 
+         *)
39858
 
+           func_warning "\`-L' is ignored for archives/objects"
39859
 
+           ;;
39860
 
+         esac # linkmode
39861
 
+         continue
39862
 
+         ;; # -L
39863
 
+       -R*)
39864
 
+         if test "$pass" = link; then
39865
 
+           func_stripname '-R' '' "$deplib"
39866
 
+           dir=$func_stripname_result
39867
 
+           # Make sure the xrpath contains only unique directories.
39868
 
+           case "$xrpath " in
39869
 
+           *" $dir "*) ;;
39870
 
+           *) xrpath="$xrpath $dir" ;;
39871
 
+           esac
39872
 
+         fi
39873
 
+         deplibs="$deplib $deplibs"
39874
 
+         continue
39875
 
+         ;;
39876
 
+       *.la) lib="$deplib" ;;
39877
 
+       *.$libext)
39878
 
+         if test "$pass" = conv; then
39879
 
+           deplibs="$deplib $deplibs"
39880
 
+           continue
39881
 
+         fi
39882
 
+         case $linkmode in
39883
 
+         lib)
39884
 
+           # Linking convenience modules into shared libraries is allowed,
39885
 
+           # but linking other static libraries is non-portable.
39886
 
+           case " $dlpreconveniencelibs " in
39887
 
+           *" $deplib "*) ;;
39888
 
+           *)
39889
 
+             valid_a_lib=no
39890
 
+             case $deplibs_check_method in
39891
 
+               match_pattern*)
39892
 
+                 set dummy $deplibs_check_method; shift
39893
 
+                 match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
39894
 
+                 if eval "\$ECHO \"X$deplib\"" 2>/dev/null | $Xsed -e 10q \
39895
 
+                   | $EGREP "$match_pattern_regex" > /dev/null; then
39896
 
+                   valid_a_lib=yes
39897
 
+                 fi
39898
 
+               ;;
39899
 
+               pass_all)
39900
 
+                 valid_a_lib=yes
39901
 
+               ;;
39902
 
+             esac
39903
 
+             if test "$valid_a_lib" != yes; then
39904
 
+               $ECHO
39905
 
+               $ECHO "*** Warning: Trying to link with static lib archive $deplib."
39906
 
+               $ECHO "*** I have the capability to make that library automatically link in when"
39907
 
+               $ECHO "*** you link to this library.  But I can only do this if you have a"
39908
 
+               $ECHO "*** shared version of the library, which you do not appear to have"
39909
 
+               $ECHO "*** because the file extensions .$libext of this argument makes me believe"
39910
 
+               $ECHO "*** that it is just a static archive that I should not use here."
39911
 
+             else
39912
 
+               $ECHO
39913
 
+               $ECHO "*** Warning: Linking the shared library $output against the"
39914
 
+               $ECHO "*** static library $deplib is not portable!"
39915
 
+               deplibs="$deplib $deplibs"
39916
 
+             fi
39917
 
+             ;;
39918
 
+           esac
39919
 
+           continue
39920
 
+           ;;
39921
 
+         prog)
39922
 
+           if test "$pass" != link; then
39923
 
+             deplibs="$deplib $deplibs"
39924
 
+           else
39925
 
+             compile_deplibs="$deplib $compile_deplibs"
39926
 
+             finalize_deplibs="$deplib $finalize_deplibs"
39927
 
+           fi
39928
 
+           continue
39929
 
+           ;;
39930
 
+         esac # linkmode
39931
 
+         ;; # *.$libext
39932
 
+       *.lo | *.$objext)
39933
 
+         if test "$pass" = conv; then
39934
 
+           deplibs="$deplib $deplibs"
39935
 
+         elif test "$linkmode" = prog; then
39936
 
+           if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then
39937
 
+             # If there is no dlopen support or we're linking statically,
39938
 
+             # we need to preload.
39939
 
+             newdlprefiles="$newdlprefiles $deplib"
39940
 
+             compile_deplibs="$deplib $compile_deplibs"
39941
 
+             finalize_deplibs="$deplib $finalize_deplibs"
39942
 
+           else
39943
 
+             newdlfiles="$newdlfiles $deplib"
39944
 
+           fi
39945
 
+         fi
39946
 
+         continue
39947
 
+         ;;
39948
 
+       %DEPLIBS%)
39949
 
+         alldeplibs=yes
39950
 
+         continue
39951
 
+         ;;
39952
 
+       esac # case $deplib
39953
 
+
39954
 
+       if test "$found" = yes || test -f "$lib"; then :
39955
 
+       else
39956
 
+         func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'"
39957
 
+       fi
39958
 
+
39959
 
+       # Check to see that this really is a libtool archive.
39960
 
+       func_lalib_unsafe_p "$lib" \
39961
 
+         || func_fatal_error "\`$lib' is not a valid libtool archive"
39962
 
+
39963
 
+       func_dirname "$lib" "" "."
39964
 
+       ladir="$func_dirname_result"
39965
 
+
39966
 
+       dlname=
39967
 
+       dlopen=
39968
 
+       dlpreopen=
39969
 
+       libdir=
39970
 
+       library_names=
39971
 
+       old_library=
39972
 
+       inherited_linker_flags=
39973
 
+       # If the library was installed with an old release of libtool,
39974
 
+       # it will not redefine variables installed, or shouldnotlink
39975
 
+       installed=yes
39976
 
+       shouldnotlink=no
39977
 
+       avoidtemprpath=
39978
 
+
39979
 
+
39980
 
+       # Read the .la file
39981
 
+       func_source "$lib"
39982
 
+
39983
 
+       # Convert "-framework foo" to "foo.ltframework"
39984
 
+       if test -n "$inherited_linker_flags"; then
39985
 
+         tmp_inherited_linker_flags=`$ECHO "X$inherited_linker_flags" | $Xsed -e 's/-framework \([^ $]*\)/\1.ltframework/g'`
39986
 
+         for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do
39987
 
+           case " $new_inherited_linker_flags " in
39988
 
+             *" $tmp_inherited_linker_flag "*) ;;
39989
 
+             *) new_inherited_linker_flags="$new_inherited_linker_flags $tmp_inherited_linker_flag";;
39990
 
+           esac
39991
 
+         done
39992
 
+       fi
39993
 
+       dependency_libs=`$ECHO "X $dependency_libs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
39994
 
+       if test "$linkmode,$pass" = "lib,link" ||
39995
 
+          test "$linkmode,$pass" = "prog,scan" ||
39996
 
+          { test "$linkmode" != prog && test "$linkmode" != lib; }; then
39997
 
+         test -n "$dlopen" && dlfiles="$dlfiles $dlopen"
39998
 
+         test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen"
39999
 
+       fi
40000
 
+
40001
 
+       if test "$pass" = conv; then
40002
 
+         # Only check for convenience libraries
40003
 
+         deplibs="$lib $deplibs"
40004
 
+         if test -z "$libdir"; then
40005
 
+           if test -z "$old_library"; then
40006
 
+             func_fatal_error "cannot find name of link library for \`$lib'"
40007
 
+           fi
40008
 
+           # It is a libtool convenience library, so add in its objects.
40009
 
+           convenience="$convenience $ladir/$objdir/$old_library"
40010
 
+           old_convenience="$old_convenience $ladir/$objdir/$old_library"
40011
 
+           tmp_libs=
40012
 
+           for deplib in $dependency_libs; do
40013
 
+             deplibs="$deplib $deplibs"
40014
 
+             if $opt_duplicate_deps ; then
40015
 
+               case "$tmp_libs " in
40016
 
+               *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
40017
 
+               esac
40018
 
+             fi
40019
 
+             tmp_libs="$tmp_libs $deplib"
40020
 
+           done
40021
 
+         elif test "$linkmode" != prog && test "$linkmode" != lib; then
40022
 
+           func_fatal_error "\`$lib' is not a convenience library"
40023
 
+         fi
40024
 
+         continue
40025
 
+       fi # $pass = conv
40026
 
+
40027
 
+
40028
 
+       # Get the name of the library we link against.
40029
 
+       linklib=
40030
 
+       for l in $old_library $library_names; do
40031
 
+         linklib="$l"
40032
 
+       done
40033
 
+       if test -z "$linklib"; then
40034
 
+         func_fatal_error "cannot find name of link library for \`$lib'"
40035
 
+       fi
40036
 
+
40037
 
+       # This library was specified with -dlopen.
40038
 
+       if test "$pass" = dlopen; then
40039
 
+         if test -z "$libdir"; then
40040
 
+           func_fatal_error "cannot -dlopen a convenience library: \`$lib'"
40041
 
+         fi
40042
 
+         if test -z "$dlname" ||
40043
 
+            test "$dlopen_support" != yes ||
40044
 
+            test "$build_libtool_libs" = no; then
40045
 
+           # If there is no dlname, no dlopen support or we're linking
40046
 
+           # statically, we need to preload.  We also need to preload any
40047
 
+           # dependent libraries so libltdl's deplib preloader doesn't
40048
 
+           # bomb out in the load deplibs phase.
40049
 
+           dlprefiles="$dlprefiles $lib $dependency_libs"
40050
 
+         else
40051
 
+           newdlfiles="$newdlfiles $lib"
40052
 
+         fi
40053
 
+         continue
40054
 
+       fi # $pass = dlopen
40055
 
+
40056
 
+       # We need an absolute path.
40057
 
+       case $ladir in
40058
 
+       [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;;
40059
 
+       *)
40060
 
+         abs_ladir=`cd "$ladir" && pwd`
40061
 
+         if test -z "$abs_ladir"; then
40062
 
+           func_warning "cannot determine absolute directory name of \`$ladir'"
40063
 
+           func_warning "passing it literally to the linker, although it might fail"
40064
 
+           abs_ladir="$ladir"
40065
 
+         fi
40066
 
+         ;;
40067
 
+       esac
40068
 
+       func_basename "$lib"
40069
 
+       laname="$func_basename_result"
40070
 
+
40071
 
+       # Find the relevant object directory and library name.
40072
 
+       if test "X$installed" = Xyes; then
40073
 
+         if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then
40074
 
+           func_warning "library \`$lib' was moved."
40075
 
+           dir="$ladir"
40076
 
+           absdir="$abs_ladir"
40077
 
+           libdir="$abs_ladir"
40078
 
+         else
40079
 
+           dir="$libdir"
40080
 
+           absdir="$libdir"
40081
 
+         fi
40082
 
+         test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes
40083
 
+       else
40084
 
+         if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then
40085
 
+           dir="$ladir"
40086
 
+           absdir="$abs_ladir"
40087
 
+           # Remove this search path later
40088
 
+           notinst_path="$notinst_path $abs_ladir"
40089
 
+         else
40090
 
+           dir="$ladir/$objdir"
40091
 
+           absdir="$abs_ladir/$objdir"
40092
 
+           # Remove this search path later
40093
 
+           notinst_path="$notinst_path $abs_ladir"
40094
 
+         fi
40095
 
+       fi # $installed = yes
40096
 
+       func_stripname 'lib' '.la' "$laname"
40097
 
+       name=$func_stripname_result
40098
 
+
40099
 
+       # This library was specified with -dlpreopen.
40100
 
+       if test "$pass" = dlpreopen; then
40101
 
+         if test -z "$libdir" && test "$linkmode" = prog; then
40102
 
+           func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'"
40103
 
+         fi
40104
 
+         # Prefer using a static library (so that no silly _DYNAMIC symbols
40105
 
+         # are required to link).
40106
 
+         if test -n "$old_library"; then
40107
 
+           newdlprefiles="$newdlprefiles $dir/$old_library"
40108
 
+           # Keep a list of preopened convenience libraries to check
40109
 
+           # that they are being used correctly in the link pass.
40110
 
+           test -z "$libdir" && \
40111
 
+               dlpreconveniencelibs="$dlpreconveniencelibs $dir/$old_library"
40112
 
+         # Otherwise, use the dlname, so that lt_dlopen finds it.
40113
 
+         elif test -n "$dlname"; then
40114
 
+           newdlprefiles="$newdlprefiles $dir/$dlname"
40115
 
+         else
40116
 
+           newdlprefiles="$newdlprefiles $dir/$linklib"
40117
 
+         fi
40118
 
+       fi # $pass = dlpreopen
40119
 
+
40120
 
+       if test -z "$libdir"; then
40121
 
+         # Link the convenience library
40122
 
+         if test "$linkmode" = lib; then
40123
 
+           deplibs="$dir/$old_library $deplibs"
40124
 
+         elif test "$linkmode,$pass" = "prog,link"; then
40125
 
+           compile_deplibs="$dir/$old_library $compile_deplibs"
40126
 
+           finalize_deplibs="$dir/$old_library $finalize_deplibs"
40127
 
+         else
40128
 
+           deplibs="$lib $deplibs" # used for prog,scan pass
40129
 
+         fi
40130
 
+         continue
40131
 
+       fi
40132
 
+
40133
 
+
40134
 
+       if test "$linkmode" = prog && test "$pass" != link; then
40135
 
+         newlib_search_path="$newlib_search_path $ladir"
40136
 
+         deplibs="$lib $deplibs"
40137
 
+
40138
 
+         linkalldeplibs=no
40139
 
+         if test "$link_all_deplibs" != no || test -z "$library_names" ||
40140
 
+            test "$build_libtool_libs" = no; then
40141
 
+           linkalldeplibs=yes
40142
 
+         fi
40143
 
+
40144
 
+         tmp_libs=
40145
 
+         for deplib in $dependency_libs; do
40146
 
+           case $deplib in
40147
 
+           -L*) func_stripname '-L' '' "$deplib"
40148
 
+                newlib_search_path="$newlib_search_path $func_stripname_result"
40149
 
+                ;;
40150
 
+           esac
40151
 
+           # Need to link against all dependency_libs?
40152
 
+           if test "$linkalldeplibs" = yes; then
40153
 
+             deplibs="$deplib $deplibs"
40154
 
+           else
40155
 
+             # Need to hardcode shared library paths
40156
 
+             # or/and link against static libraries
40157
 
+             newdependency_libs="$deplib $newdependency_libs"
40158
 
+           fi
40159
 
+           if $opt_duplicate_deps ; then
40160
 
+             case "$tmp_libs " in
40161
 
+             *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
40162
 
+             esac
40163
 
+           fi
40164
 
+           tmp_libs="$tmp_libs $deplib"
40165
 
+         done # for deplib
40166
 
+         continue
40167
 
+       fi # $linkmode = prog...
40168
 
+
40169
 
+       if test "$linkmode,$pass" = "prog,link"; then
40170
 
+         if test -n "$library_names" &&
40171
 
+            { { test "$prefer_static_libs" = no ||
40172
 
+                test "$prefer_static_libs,$installed" = "built,yes"; } ||
40173
 
+              test -z "$old_library"; }; then
40174
 
+           # We need to hardcode the library path
40175
 
+           if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then
40176
 
+             # Make sure the rpath contains only unique directories.
40177
 
+             case "$temp_rpath:" in
40178
 
+             *"$absdir:"*) ;;
40179
 
+             *) temp_rpath="$temp_rpath$absdir:" ;;
40180
 
+             esac
40181
 
+           fi
40182
 
+
40183
 
+           # Hardcode the library path.
40184
 
+           # Skip directories that are in the system default run-time
40185
 
+           # search path.
40186
 
+           case " $sys_lib_dlsearch_path " in
40187
 
+           *" $absdir "*) ;;
40188
 
+           *)
40189
 
+             case "$compile_rpath " in
40190
 
+             *" $absdir "*) ;;
40191
 
+             *) compile_rpath="$compile_rpath $absdir"
40192
 
+             esac
40193
 
+             ;;
40194
 
+           esac
40195
 
+           case " $sys_lib_dlsearch_path " in
40196
 
+           *" $libdir "*) ;;
40197
 
+           *)
40198
 
+             case "$finalize_rpath " in
40199
 
+             *" $libdir "*) ;;
40200
 
+             *) finalize_rpath="$finalize_rpath $libdir"
40201
 
+             esac
40202
 
+             ;;
40203
 
+           esac
40204
 
+         fi # $linkmode,$pass = prog,link...
40205
 
+
40206
 
+         if test "$alldeplibs" = yes &&
40207
 
+            { test "$deplibs_check_method" = pass_all ||
40208
 
+              { test "$build_libtool_libs" = yes &&
40209
 
+                test -n "$library_names"; }; }; then
40210
 
+           # We only need to search for static libraries
40211
 
+           continue
40212
 
+         fi
40213
 
+       fi
40214
 
+
40215
 
+       link_static=no # Whether the deplib will be linked statically
40216
 
+       use_static_libs=$prefer_static_libs
40217
 
+       if test "$use_static_libs" = built && test "$installed" = yes; then
40218
 
+         use_static_libs=no
40219
 
+       fi
40220
 
+       if test -n "$library_names" &&
40221
 
+          { test "$use_static_libs" = no || test -z "$old_library"; }; then
40222
 
+         case $host in
40223
 
+         *cygwin* | *mingw* | *cegcc*)
40224
 
+             # No point in relinking DLLs because paths are not encoded
40225
 
+             notinst_deplibs="$notinst_deplibs $lib"
40226
 
+             need_relink=no
40227
 
+           ;;
40228
 
+         *)
40229
 
+           if test "$installed" = no; then
40230
 
+             notinst_deplibs="$notinst_deplibs $lib"
40231
 
+             need_relink=yes
40232
 
+           fi
40233
 
+           ;;
40234
 
+         esac
40235
 
+         # This is a shared library
40236
 
+
40237
 
+         # Warn about portability, can't link against -module's on some
40238
 
+         # systems (darwin).  Don't bleat about dlopened modules though!
40239
 
+         dlopenmodule=""
40240
 
+         for dlpremoduletest in $dlprefiles; do
40241
 
+           if test "X$dlpremoduletest" = "X$lib"; then
40242
 
+             dlopenmodule="$dlpremoduletest"
40243
 
+             break
40244
 
+           fi
40245
 
+         done
40246
 
+         if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then
40247
 
+           $ECHO
40248
 
+           if test "$linkmode" = prog; then
40249
 
+             $ECHO "*** Warning: Linking the executable $output against the loadable module"
40250
 
+           else
40251
 
+             $ECHO "*** Warning: Linking the shared library $output against the loadable module"
40252
 
+           fi
40253
 
+           $ECHO "*** $linklib is not portable!"
40254
 
+         fi
40255
 
+         if test "$linkmode" = lib &&
40256
 
+            test "$hardcode_into_libs" = yes; then
40257
 
+           # Hardcode the library path.
40258
 
+           # Skip directories that are in the system default run-time
40259
 
+           # search path.
40260
 
+           case " $sys_lib_dlsearch_path " in
40261
 
+           *" $absdir "*) ;;
40262
 
+           *)
40263
 
+             case "$compile_rpath " in
40264
 
+             *" $absdir "*) ;;
40265
 
+             *) compile_rpath="$compile_rpath $absdir"
40266
 
+             esac
40267
 
+             ;;
40268
 
+           esac
40269
 
+           case " $sys_lib_dlsearch_path " in
40270
 
+           *" $libdir "*) ;;
40271
 
+           *)
40272
 
+             case "$finalize_rpath " in
40273
 
+             *" $libdir "*) ;;
40274
 
+             *) finalize_rpath="$finalize_rpath $libdir"
40275
 
+             esac
40276
 
+             ;;
40277
 
+           esac
40278
 
+         fi
40279
 
+
40280
 
+         if test -n "$old_archive_from_expsyms_cmds"; then
40281
 
+           # figure out the soname
40282
 
+           set dummy $library_names
40283
 
+           shift
40284
 
+           realname="$1"
40285
 
+           shift
40286
 
+           libname=`eval "\\$ECHO \"$libname_spec\""`
40287
 
+           # use dlname if we got it. it's perfectly good, no?
40288
 
+           if test -n "$dlname"; then
40289
 
+             soname="$dlname"
40290
 
+           elif test -n "$soname_spec"; then
40291
 
+             # bleh windows
40292
 
+             case $host in
40293
 
+             *cygwin* | mingw* | *cegcc*)
40294
 
+               func_arith $current - $age
40295
 
+               major=$func_arith_result
40296
 
+               versuffix="-$major"
40297
 
+               ;;
40298
 
+             esac
40299
 
+             eval soname=\"$soname_spec\"
40300
 
+           else
40301
 
+             soname="$realname"
40302
 
+           fi
40303
 
+
40304
 
+           # Make a new name for the extract_expsyms_cmds to use
40305
 
+           soroot="$soname"
40306
 
+           func_basename "$soroot"
40307
 
+           soname="$func_basename_result"
40308
 
+           func_stripname 'lib' '.dll' "$soname"
40309
 
+           newlib=libimp-$func_stripname_result.a
40310
 
+
40311
 
+           # If the library has no export list, then create one now
40312
 
+           if test -f "$output_objdir/$soname-def"; then :
40313
 
+           else
40314
 
+             func_verbose "extracting exported symbol list from \`$soname'"
40315
 
+             func_execute_cmds "$extract_expsyms_cmds" 'exit $?'
40316
 
+           fi
40317
 
+
40318
 
+           # Create $newlib
40319
 
+           if test -f "$output_objdir/$newlib"; then :; else
40320
 
+             func_verbose "generating import library for \`$soname'"
40321
 
+             func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?'
40322
 
+           fi
40323
 
+           # make sure the library variables are pointing to the new library
40324
 
+           dir=$output_objdir
40325
 
+           linklib=$newlib
40326
 
+         fi # test -n "$old_archive_from_expsyms_cmds"
40327
 
+
40328
 
+         if test "$linkmode" = prog || test "$mode" != relink; then
40329
 
+           add_shlibpath=
40330
 
+           add_dir=
40331
 
+           add=
40332
 
+           lib_linked=yes
40333
 
+           case $hardcode_action in
40334
 
+           immediate | unsupported)
40335
 
+             if test "$hardcode_direct" = no; then
40336
 
+               add="$dir/$linklib"
40337
 
+               case $host in
40338
 
+                 *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;;
40339
 
+                 *-*-sysv4*uw2*) add_dir="-L$dir" ;;
40340
 
+                 *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \
40341
 
+                   *-*-unixware7*) add_dir="-L$dir" ;;
40342
 
+                 *-*-darwin* )
40343
 
+                   # if the lib is a (non-dlopened) module then we can not
40344
 
+                   # link against it, someone is ignoring the earlier warnings
40345
 
+                   if /usr/bin/file -L $add 2> /dev/null |
40346
 
+                        $GREP ": [^:]* bundle" >/dev/null ; then
40347
 
+                     if test "X$dlopenmodule" != "X$lib"; then
40348
 
+                       $ECHO "*** Warning: lib $linklib is a module, not a shared library"
40349
 
+                       if test -z "$old_library" ; then
40350
 
+                         $ECHO
40351
 
+                         $ECHO "*** And there doesn't seem to be a static archive available"
40352
 
+                         $ECHO "*** The link will probably fail, sorry"
40353
 
+                       else
40354
 
+                         add="$dir/$old_library"
40355
 
+                       fi
40356
 
+                     elif test -n "$old_library"; then
40357
 
+                       add="$dir/$old_library"
40358
 
+                     fi
40359
 
+                   fi
40360
 
+               esac
40361
 
+             elif test "$hardcode_minus_L" = no; then
40362
 
+               case $host in
40363
 
+               *-*-sunos*) add_shlibpath="$dir" ;;
40364
 
+               esac
40365
 
+               add_dir="-L$dir"
40366
 
+               add="-l$name"
40367
 
+             elif test "$hardcode_shlibpath_var" = no; then
40368
 
+               add_shlibpath="$dir"
40369
 
+               add="-l$name"
40370
 
+             else
40371
 
+               lib_linked=no
40372
 
+             fi
40373
 
+             ;;
40374
 
+           relink)
40375
 
+             if test "$hardcode_direct" = yes &&
40376
 
+                test "$hardcode_direct_absolute" = no; then
40377
 
+               add="$dir/$linklib"
40378
 
+             elif test "$hardcode_minus_L" = yes; then
40379
 
+               add_dir="-L$dir"
40380
 
+               # Try looking first in the location we're being installed to.
40381
 
+               if test -n "$inst_prefix_dir"; then
40382
 
+                 case $libdir in
40383
 
+                   [\\/]*)
40384
 
+                     add_dir="$add_dir -L$inst_prefix_dir$libdir"
40385
 
+                     ;;
40386
 
+                 esac
40387
 
+               fi
40388
 
+               add="-l$name"
40389
 
+             elif test "$hardcode_shlibpath_var" = yes; then
40390
 
+               add_shlibpath="$dir"
40391
 
+               add="-l$name"
40392
 
+             else
40393
 
+               lib_linked=no
40394
 
+             fi
40395
 
+             ;;
40396
 
+           *) lib_linked=no ;;
40397
 
+           esac
40398
 
+
40399
 
+           if test "$lib_linked" != yes; then
40400
 
+             func_fatal_configuration "unsupported hardcode properties"
40401
 
+           fi
40402
 
+
40403
 
+           if test -n "$add_shlibpath"; then
40404
 
+             case :$compile_shlibpath: in
40405
 
+             *":$add_shlibpath:"*) ;;
40406
 
+             *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;;
40407
 
+             esac
40408
 
+           fi
40409
 
+           if test "$linkmode" = prog; then
40410
 
+             test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs"
40411
 
+             test -n "$add" && compile_deplibs="$add $compile_deplibs"
40412
 
+           else
40413
 
+             test -n "$add_dir" && deplibs="$add_dir $deplibs"
40414
 
+             test -n "$add" && deplibs="$add $deplibs"
40415
 
+             if test "$hardcode_direct" != yes &&
40416
 
+                test "$hardcode_minus_L" != yes &&
40417
 
+                test "$hardcode_shlibpath_var" = yes; then
40418
 
+               case :$finalize_shlibpath: in
40419
 
+               *":$libdir:"*) ;;
40420
 
+               *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;;
40421
 
+               esac
40422
 
+             fi
40423
 
+           fi
40424
 
+         fi
40425
 
+
40426
 
+         if test "$linkmode" = prog || test "$mode" = relink; then
40427
 
+           add_shlibpath=
40428
 
+           add_dir=
40429
 
+           add=
40430
 
+           # Finalize command for both is simple: just hardcode it.
40431
 
+           if test "$hardcode_direct" = yes &&
40432
 
+              test "$hardcode_direct_absolute" = no; then
40433
 
+             add="$libdir/$linklib"
40434
 
+           elif test "$hardcode_minus_L" = yes; then
40435
 
+             add_dir="-L$libdir"
40436
 
+             add="-l$name"
40437
 
+           elif test "$hardcode_shlibpath_var" = yes; then
40438
 
+             case :$finalize_shlibpath: in
40439
 
+             *":$libdir:"*) ;;
40440
 
+             *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;;
40441
 
+             esac
40442
 
+             add="-l$name"
40443
 
+           elif test "$hardcode_automatic" = yes; then
40444
 
+             if test -n "$inst_prefix_dir" &&
40445
 
+                test -f "$inst_prefix_dir$libdir/$linklib" ; then
40446
 
+               add="$inst_prefix_dir$libdir/$linklib"
40447
 
+             else
40448
 
+               add="$libdir/$linklib"
40449
 
+             fi
40450
 
+           else
40451
 
+             # We cannot seem to hardcode it, guess we'll fake it.
40452
 
+             add_dir="-L$libdir"
40453
 
+             # Try looking first in the location we're being installed to.
40454
 
+             if test -n "$inst_prefix_dir"; then
40455
 
+               case $libdir in
40456
 
+                 [\\/]*)
40457
 
+                   add_dir="$add_dir -L$inst_prefix_dir$libdir"
40458
 
+                   ;;
40459
 
+               esac
40460
 
+             fi
40461
 
+             add="-l$name"
40462
 
+           fi
40463
 
+
40464
 
+           if test "$linkmode" = prog; then
40465
 
+             test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs"
40466
 
+             test -n "$add" && finalize_deplibs="$add $finalize_deplibs"
40467
 
+           else
40468
 
+             test -n "$add_dir" && deplibs="$add_dir $deplibs"
40469
 
+             test -n "$add" && deplibs="$add $deplibs"
40470
 
+           fi
40471
 
+         fi
40472
 
+       elif test "$linkmode" = prog; then
40473
 
+         # Here we assume that one of hardcode_direct or hardcode_minus_L
40474
 
+         # is not unsupported.  This is valid on all known static and
40475
 
+         # shared platforms.
40476
 
+         if test "$hardcode_direct" != unsupported; then
40477
 
+           test -n "$old_library" && linklib="$old_library"
40478
 
+           compile_deplibs="$dir/$linklib $compile_deplibs"
40479
 
+           finalize_deplibs="$dir/$linklib $finalize_deplibs"
40480
 
+         else
40481
 
+           compile_deplibs="-l$name -L$dir $compile_deplibs"
40482
 
+           finalize_deplibs="-l$name -L$dir $finalize_deplibs"
40483
 
+         fi
40484
 
+       elif test "$build_libtool_libs" = yes; then
40485
 
+         # Not a shared library
40486
 
+         if test "$deplibs_check_method" != pass_all; then
40487
 
+           # We're trying link a shared library against a static one
40488
 
+           # but the system doesn't support it.
40489
 
+
40490
 
+           # Just print a warning and add the library to dependency_libs so
40491
 
+           # that the program can be linked against the static library.
40492
 
+           $ECHO
40493
 
+           $ECHO "*** Warning: This system can not link to static lib archive $lib."
40494
 
+           $ECHO "*** I have the capability to make that library automatically link in when"
40495
 
+           $ECHO "*** you link to this library.  But I can only do this if you have a"
40496
 
+           $ECHO "*** shared version of the library, which you do not appear to have."
40497
 
+           if test "$module" = yes; then
40498
 
+             $ECHO "*** But as you try to build a module library, libtool will still create "
40499
 
+             $ECHO "*** a static module, that should work as long as the dlopening application"
40500
 
+             $ECHO "*** is linked with the -dlopen flag to resolve symbols at runtime."
40501
 
+             if test -z "$global_symbol_pipe"; then
40502
 
+               $ECHO
40503
 
+               $ECHO "*** However, this would only work if libtool was able to extract symbol"
40504
 
+               $ECHO "*** lists from a program, using \`nm' or equivalent, but libtool could"
40505
 
+               $ECHO "*** not find such a program.  So, this module is probably useless."
40506
 
+               $ECHO "*** \`nm' from GNU binutils and a full rebuild may help."
40507
 
+             fi
40508
 
+             if test "$build_old_libs" = no; then
40509
 
+               build_libtool_libs=module
40510
 
+               build_old_libs=yes
40511
 
+             else
40512
 
+               build_libtool_libs=no
40513
 
+             fi
40514
 
+           fi
40515
 
+         else
40516
 
+           deplibs="$dir/$old_library $deplibs"
40517
 
+           link_static=yes
40518
 
+         fi
40519
 
+       fi # link shared/static library?
40520
 
+
40521
 
+       if test "$linkmode" = lib; then
40522
 
+         if test -n "$dependency_libs" &&
40523
 
+            { test "$hardcode_into_libs" != yes ||
40524
 
+              test "$build_old_libs" = yes ||
40525
 
+              test "$link_static" = yes; }; then
40526
 
+           # Extract -R from dependency_libs
40527
 
+           temp_deplibs=
40528
 
+           for libdir in $dependency_libs; do
40529
 
+             case $libdir in
40530
 
+             -R*) func_stripname '-R' '' "$libdir"
40531
 
+                  temp_xrpath=$func_stripname_result
40532
 
+                  case " $xrpath " in
40533
 
+                  *" $temp_xrpath "*) ;;
40534
 
+                  *) xrpath="$xrpath $temp_xrpath";;
40535
 
+                  esac;;
40536
 
+             *) temp_deplibs="$temp_deplibs $libdir";;
40537
 
+             esac
40538
 
+           done
40539
 
+           dependency_libs="$temp_deplibs"
40540
 
+         fi
40541
 
+
40542
 
+         newlib_search_path="$newlib_search_path $absdir"
40543
 
+         # Link against this library
40544
 
+         test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs"
40545
 
+         # ... and its dependency_libs
40546
 
+         tmp_libs=
40547
 
+         for deplib in $dependency_libs; do
40548
 
+           newdependency_libs="$deplib $newdependency_libs"
40549
 
+           if $opt_duplicate_deps ; then
40550
 
+             case "$tmp_libs " in
40551
 
+             *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
40552
 
+             esac
40553
 
+           fi
40554
 
+           tmp_libs="$tmp_libs $deplib"
40555
 
+         done
40556
 
+
40557
 
+         if test "$link_all_deplibs" != no; then
40558
 
+           # Add the search paths of all dependency libraries
40559
 
+           for deplib in $dependency_libs; do
40560
 
+             path=
40561
 
+             case $deplib in
40562
 
+             -L*) path="$deplib" ;;
40563
 
+             *.la)
40564
 
+               func_dirname "$deplib" "" "."
40565
 
+               dir="$func_dirname_result"
40566
 
+               # We need an absolute path.
40567
 
+               case $dir in
40568
 
+               [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;;
40569
 
+               *)
40570
 
+                 absdir=`cd "$dir" && pwd`
40571
 
+                 if test -z "$absdir"; then
40572
 
+                   func_warning "cannot determine absolute directory name of \`$dir'"
40573
 
+                   absdir="$dir"
40574
 
+                 fi
40575
 
+                 ;;
40576
 
+               esac
40577
 
+               if $GREP "^installed=no" $deplib > /dev/null; then
40578
 
+               case $host in
40579
 
+               *-*-darwin*)
40580
 
+                 depdepl=
40581
 
+                 eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib`
40582
 
+                 if test -n "$deplibrary_names" ; then
40583
 
+                   for tmp in $deplibrary_names ; do
40584
 
+                     depdepl=$tmp
40585
 
+                   done
40586
 
+                   if test -f "$absdir/$objdir/$depdepl" ; then
40587
 
+                     depdepl="$absdir/$objdir/$depdepl"
40588
 
+                     darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'`
40589
 
+                      if test -z "$darwin_install_name"; then
40590
 
+                          darwin_install_name=`${OTOOL64} -L $depdepl  | awk '{if (NR == 2) {print $1;exit}}'`
40591
 
+                      fi
40592
 
+                     compiler_flags="$compiler_flags ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}"
40593
 
+                     linker_flags="$linker_flags -dylib_file ${darwin_install_name}:${depdepl}"
40594
 
+                     path=
40595
 
+                   fi
40596
 
+                 fi
40597
 
+                 ;;
40598
 
+               *)
40599
 
+                 path="-L$absdir/$objdir"
40600
 
+                 ;;
40601
 
+               esac
40602
 
+               else
40603
 
+                 eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
40604
 
+                 test -z "$libdir" && \
40605
 
+                   func_fatal_error "\`$deplib' is not a valid libtool archive"
40606
 
+                 test "$absdir" != "$libdir" && \
40607
 
+                   func_warning "\`$deplib' seems to be moved"
40608
 
+
40609
 
+                 path="-L$absdir"
40610
 
+               fi
40611
 
+               ;;
40612
 
+             esac
40613
 
+             case " $deplibs " in
40614
 
+             *" $path "*) ;;
40615
 
+             *) deplibs="$path $deplibs" ;;
40616
 
+             esac
40617
 
+           done
40618
 
+         fi # link_all_deplibs != no
40619
 
+       fi # linkmode = lib
40620
 
+      done # for deplib in $libs
40621
 
+      if test "$pass" = link; then
40622
 
+       if test "$linkmode" = "prog"; then
40623
 
+         compile_deplibs="$new_inherited_linker_flags $compile_deplibs"
40624
 
+         finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs"
40625
 
+       else
40626
 
+         compiler_flags="$compiler_flags "`$ECHO "X $new_inherited_linker_flags" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
40627
 
+       fi
40628
 
+      fi
40629
 
+      dependency_libs="$newdependency_libs"
40630
 
+      if test "$pass" = dlpreopen; then
40631
 
+       # Link the dlpreopened libraries before other libraries
40632
 
+       for deplib in $save_deplibs; do
40633
 
+         deplibs="$deplib $deplibs"
40634
 
+       done
40635
 
+      fi
40636
 
+      if test "$pass" != dlopen; then
40637
 
+       if test "$pass" != conv; then
40638
 
+         # Make sure lib_search_path contains only unique directories.
40639
 
+         lib_search_path=
40640
 
+         for dir in $newlib_search_path; do
40641
 
+           case "$lib_search_path " in
40642
 
+           *" $dir "*) ;;
40643
 
+           *) lib_search_path="$lib_search_path $dir" ;;
40644
 
+           esac
40645
 
+         done
40646
 
+         newlib_search_path=
40647
 
+       fi
40648
 
+
40649
 
+       if test "$linkmode,$pass" != "prog,link"; then
40650
 
+         vars="deplibs"
40651
 
+       else
40652
 
+         vars="compile_deplibs finalize_deplibs"
40653
 
+       fi
40654
 
+       for var in $vars dependency_libs; do
40655
 
+         # Add libraries to $var in reverse order
40656
 
+         eval tmp_libs=\"\$$var\"
40657
 
+         new_libs=
40658
 
+         for deplib in $tmp_libs; do
40659
 
+           # FIXME: Pedantically, this is the right thing to do, so
40660
 
+           #        that some nasty dependency loop isn't accidentally
40661
 
+           #        broken:
40662
 
+           #new_libs="$deplib $new_libs"
40663
 
+           # Pragmatically, this seems to cause very few problems in
40664
 
+           # practice:
40665
 
+           case $deplib in
40666
 
+           -L*) new_libs="$deplib $new_libs" ;;
40667
 
+           -R*) ;;
40668
 
+           *)
40669
 
+             # And here is the reason: when a library appears more
40670
 
+             # than once as an explicit dependence of a library, or
40671
 
+             # is implicitly linked in more than once by the
40672
 
+             # compiler, it is considered special, and multiple
40673
 
+             # occurrences thereof are not removed.  Compare this
40674
 
+             # with having the same library being listed as a
40675
 
+             # dependency of multiple other libraries: in this case,
40676
 
+             # we know (pedantically, we assume) the library does not
40677
 
+             # need to be listed more than once, so we keep only the
40678
 
+             # last copy.  This is not always right, but it is rare
40679
 
+             # enough that we require users that really mean to play
40680
 
+             # such unportable linking tricks to link the library
40681
 
+             # using -Wl,-lname, so that libtool does not consider it
40682
 
+             # for duplicate removal.
40683
 
+             case " $specialdeplibs " in
40684
 
+             *" $deplib "*) new_libs="$deplib $new_libs" ;;
40685
 
+             *)
40686
 
+               case " $new_libs " in
40687
 
+               *" $deplib "*) ;;
40688
 
+               *) new_libs="$deplib $new_libs" ;;
40689
 
+               esac
40690
 
+               ;;
40691
 
+             esac
40692
 
+             ;;
40693
 
+           esac
40694
 
+         done
40695
 
+         tmp_libs=
40696
 
+         for deplib in $new_libs; do
40697
 
+           case $deplib in
40698
 
+           -L*)
40699
 
+             case " $tmp_libs " in
40700
 
+             *" $deplib "*) ;;
40701
 
+             *) tmp_libs="$tmp_libs $deplib" ;;
40702
 
+             esac
40703
 
+             ;;
40704
 
+           *) tmp_libs="$tmp_libs $deplib" ;;
40705
 
+           esac
40706
 
+         done
40707
 
+         eval $var=\"$tmp_libs\"
40708
 
+       done # for var
40709
 
+      fi
40710
 
+      # Last step: remove runtime libs from dependency_libs
40711
 
+      # (they stay in deplibs)
40712
 
+      tmp_libs=
40713
 
+      for i in $dependency_libs ; do
40714
 
+       case " $predeps $postdeps $compiler_lib_search_path " in
40715
 
+       *" $i "*)
40716
 
+         i=""
40717
 
+         ;;
40718
 
+       esac
40719
 
+       if test -n "$i" ; then
40720
 
+         tmp_libs="$tmp_libs $i"
40721
 
+       fi
40722
 
+      done
40723
 
+      dependency_libs=$tmp_libs
40724
 
+    done # for pass
40725
 
+    if test "$linkmode" = prog; then
40726
 
+      dlfiles="$newdlfiles"
40727
 
+    fi
40728
 
+    if test "$linkmode" = prog || test "$linkmode" = lib; then
40729
 
+      dlprefiles="$newdlprefiles"
40730
 
+    fi
40731
 
+
40732
 
+    case $linkmode in
40733
 
+    oldlib)
40734
 
+      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
40735
 
+       func_warning "\`-dlopen' is ignored for archives"
40736
 
+      fi
40737
 
+
40738
 
+      case " $deplibs" in
40739
 
+      *\ -l* | *\ -L*)
40740
 
+       func_warning "\`-l' and \`-L' are ignored for archives" ;;
40741
 
+      esac
40742
 
+
40743
 
+      test -n "$rpath" && \
40744
 
+       func_warning "\`-rpath' is ignored for archives"
40745
 
+
40746
 
+      test -n "$xrpath" && \
40747
 
+       func_warning "\`-R' is ignored for archives"
40748
 
+
40749
 
+      test -n "$vinfo" && \
40750
 
+       func_warning "\`-version-info/-version-number' is ignored for archives"
40751
 
+
40752
 
+      test -n "$release" && \
40753
 
+       func_warning "\`-release' is ignored for archives"
40754
 
+
40755
 
+      test -n "$export_symbols$export_symbols_regex" && \
40756
 
+       func_warning "\`-export-symbols' is ignored for archives"
40757
 
+
40758
 
+      # Now set the variables for building old libraries.
40759
 
+      build_libtool_libs=no
40760
 
+      oldlibs="$output"
40761
 
+      objs="$objs$old_deplibs"
40762
 
+      ;;
40763
 
+
40764
 
+    lib)
40765
 
+      # Make sure we only generate libraries of the form `libNAME.la'.
40766
 
+      case $outputname in
40767
 
+      lib*)
40768
 
+       func_stripname 'lib' '.la' "$outputname"
40769
 
+       name=$func_stripname_result
40770
 
+       eval shared_ext=\"$shrext_cmds\"
40771
 
+       eval libname=\"$libname_spec\"
40772
 
+       ;;
40773
 
+      *)
40774
 
+       test "$module" = no && \
40775
 
+         func_fatal_help "libtool library \`$output' must begin with \`lib'"
40776
 
+
40777
 
+       if test "$need_lib_prefix" != no; then
40778
 
+         # Add the "lib" prefix for modules if required
40779
 
+         func_stripname '' '.la' "$outputname"
40780
 
+         name=$func_stripname_result
40781
 
+         eval shared_ext=\"$shrext_cmds\"
40782
 
+         eval libname=\"$libname_spec\"
40783
 
+       else
40784
 
+         func_stripname '' '.la' "$outputname"
40785
 
+         libname=$func_stripname_result
40786
 
+       fi
40787
 
+       ;;
40788
 
+      esac
40789
 
+
40790
 
+      if test -n "$objs"; then
40791
 
+       if test "$deplibs_check_method" != pass_all; then
40792
 
+         func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs"
40793
 
+       else
40794
 
+         $ECHO
40795
 
+         $ECHO "*** Warning: Linking the shared library $output against the non-libtool"
40796
 
+         $ECHO "*** objects $objs is not portable!"
40797
 
+         libobjs="$libobjs $objs"
40798
 
+       fi
40799
 
+      fi
40800
 
+
40801
 
+      test "$dlself" != no && \
40802
 
+       func_warning "\`-dlopen self' is ignored for libtool libraries"
40803
 
+
40804
 
+      set dummy $rpath
40805
 
+      shift
40806
 
+      test "$#" -gt 1 && \
40807
 
+       func_warning "ignoring multiple \`-rpath's for a libtool library"
40808
 
+
40809
 
+      install_libdir="$1"
40810
 
+
40811
 
+      oldlibs=
40812
 
+      if test -z "$rpath"; then
40813
 
+       if test "$build_libtool_libs" = yes; then
40814
 
+         # Building a libtool convenience library.
40815
 
+         # Some compilers have problems with a `.al' extension so
40816
 
+         # convenience libraries should have the same extension an
40817
 
+         # archive normally would.
40818
 
+         oldlibs="$output_objdir/$libname.$libext $oldlibs"
40819
 
+         build_libtool_libs=convenience
40820
 
+         build_old_libs=yes
40821
 
+       fi
40822
 
+
40823
 
+       test -n "$vinfo" && \
40824
 
+         func_warning "\`-version-info/-version-number' is ignored for convenience libraries"
40825
 
+
40826
 
+       test -n "$release" && \
40827
 
+         func_warning "\`-release' is ignored for convenience libraries"
40828
 
+      else
40829
 
+
40830
 
+       # Parse the version information argument.
40831
 
+       save_ifs="$IFS"; IFS=':'
40832
 
+       set dummy $vinfo 0 0 0
40833
 
+       shift
40834
 
+       IFS="$save_ifs"
40835
 
+
40836
 
+       test -n "$7" && \
40837
 
+         func_fatal_help "too many parameters to \`-version-info'"
40838
 
+
40839
 
+       # convert absolute version numbers to libtool ages
40840
 
+       # this retains compatibility with .la files and attempts
40841
 
+       # to make the code below a bit more comprehensible
40842
 
+
40843
 
+       case $vinfo_number in
40844
 
+       yes)
40845
 
+         number_major="$1"
40846
 
+         number_minor="$2"
40847
 
+         number_revision="$3"
40848
 
+         #
40849
 
+         # There are really only two kinds -- those that
40850
 
+         # use the current revision as the major version
40851
 
+         # and those that subtract age and use age as
40852
 
+         # a minor version.  But, then there is irix
40853
 
+         # which has an extra 1 added just for fun
40854
 
+         #
40855
 
+         case $version_type in
40856
 
+         darwin|linux|osf|windows|none)
40857
 
+           func_arith $number_major + $number_minor
40858
 
+           current=$func_arith_result
40859
 
+           age="$number_minor"
40860
 
+           revision="$number_revision"
40861
 
+           ;;
40862
 
+         freebsd-aout|freebsd-elf|sunos)
40863
 
+           current="$number_major"
40864
 
+           revision="$number_minor"
40865
 
+           age="0"
40866
 
+           ;;
40867
 
+         irix|nonstopux)
40868
 
+           func_arith $number_major + $number_minor
40869
 
+           current=$func_arith_result
40870
 
+           age="$number_minor"
40871
 
+           revision="$number_minor"
40872
 
+           lt_irix_increment=no
40873
 
+           ;;
40874
 
+         *)
40875
 
+           func_fatal_configuration "$modename: unknown library version type \`$version_type'"
40876
 
+           ;;
40877
 
+         esac
40878
 
+         ;;
40879
 
+       no)
40880
 
+         current="$1"
40881
 
+         revision="$2"
40882
 
+         age="$3"
40883
 
+         ;;
40884
 
+       esac
40885
 
+
40886
 
+       # Check that each of the things are valid numbers.
40887
 
+       case $current in
40888
 
+       0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
40889
 
+       *)
40890
 
+         func_error "CURRENT \`$current' must be a nonnegative integer"
40891
 
+         func_fatal_error "\`$vinfo' is not valid version information"
40892
 
+         ;;
40893
 
+       esac
40894
 
+
40895
 
+       case $revision in
40896
 
+       0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
40897
 
+       *)
40898
 
+         func_error "REVISION \`$revision' must be a nonnegative integer"
40899
 
+         func_fatal_error "\`$vinfo' is not valid version information"
40900
 
+         ;;
40901
 
+       esac
40902
 
+
40903
 
+       case $age in
40904
 
+       0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
40905
 
+       *)
40906
 
+         func_error "AGE \`$age' must be a nonnegative integer"
40907
 
+         func_fatal_error "\`$vinfo' is not valid version information"
40908
 
+         ;;
40909
 
+       esac
40910
 
+
40911
 
+       if test "$age" -gt "$current"; then
40912
 
+         func_error "AGE \`$age' is greater than the current interface number \`$current'"
40913
 
+         func_fatal_error "\`$vinfo' is not valid version information"
40914
 
+       fi
40915
 
+
40916
 
+       # Calculate the version variables.
40917
 
+       major=
40918
 
+       versuffix=
40919
 
+       verstring=
40920
 
+       case $version_type in
40921
 
+       none) ;;
40922
 
+
40923
 
+       darwin)
40924
 
+         # Like Linux, but with the current version available in
40925
 
+         # verstring for coding it into the library header
40926
 
+         func_arith $current - $age
40927
 
+         major=.$func_arith_result
40928
 
+         versuffix="$major.$age.$revision"
40929
 
+         # Darwin ld doesn't like 0 for these options...
40930
 
+         func_arith $current + 1
40931
 
+         minor_current=$func_arith_result
40932
 
+         xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision"
40933
 
+         verstring="-compatibility_version $minor_current -current_version $minor_current.$revision"
40934
 
+         ;;
40935
 
+
40936
 
+       freebsd-aout)
40937
 
+         major=".$current"
40938
 
+         versuffix=".$current.$revision";
40939
 
+         ;;
40940
 
+
40941
 
+       freebsd-elf)
40942
 
+         major=".$current"
40943
 
+         versuffix=".$current"
40944
 
+         ;;
40945
 
+
40946
 
+       irix | nonstopux)
40947
 
+         if test "X$lt_irix_increment" = "Xno"; then
40948
 
+           func_arith $current - $age
40949
 
+         else
40950
 
+           func_arith $current - $age + 1
40951
 
+         fi
40952
 
+         major=$func_arith_result
40953
 
+
40954
 
+         case $version_type in
40955
 
+           nonstopux) verstring_prefix=nonstopux ;;
40956
 
+           *)         verstring_prefix=sgi ;;
40957
 
+         esac
40958
 
+         verstring="$verstring_prefix$major.$revision"
40959
 
+
40960
 
+         # Add in all the interfaces that we are compatible with.
40961
 
+         loop=$revision
40962
 
+         while test "$loop" -ne 0; do
40963
 
+           func_arith $revision - $loop
40964
 
+           iface=$func_arith_result
40965
 
+           func_arith $loop - 1
40966
 
+           loop=$func_arith_result
40967
 
+           verstring="$verstring_prefix$major.$iface:$verstring"
40968
 
+         done
40969
 
+
40970
 
+         # Before this point, $major must not contain `.'.
40971
 
+         major=.$major
40972
 
+         versuffix="$major.$revision"
40973
 
+         ;;
40974
 
+
40975
 
+       linux)
40976
 
+         func_arith $current - $age
40977
 
+         major=.$func_arith_result
40978
 
+         versuffix="$major.$age.$revision"
40979
 
+         ;;
40980
 
+
40981
 
+       osf)
40982
 
+         func_arith $current - $age
40983
 
+         major=.$func_arith_result
40984
 
+         versuffix=".$current.$age.$revision"
40985
 
+         verstring="$current.$age.$revision"
40986
 
+
40987
 
+         # Add in all the interfaces that we are compatible with.
40988
 
+         loop=$age
40989
 
+         while test "$loop" -ne 0; do
40990
 
+           func_arith $current - $loop
40991
 
+           iface=$func_arith_result
40992
 
+           func_arith $loop - 1
40993
 
+           loop=$func_arith_result
40994
 
+           verstring="$verstring:${iface}.0"
40995
 
+         done
40996
 
+
40997
 
+         # Make executables depend on our current version.
40998
 
+         verstring="$verstring:${current}.0"
40999
 
+         ;;
41000
 
+
41001
 
+       qnx)
41002
 
+         major=".$current"
41003
 
+         versuffix=".$current"
41004
 
+         ;;
41005
 
+
41006
 
+       sunos)
41007
 
+         major=".$current"
41008
 
+         versuffix=".$current.$revision"
41009
 
+         ;;
41010
 
+
41011
 
+       windows)
41012
 
+         # Use '-' rather than '.', since we only want one
41013
 
+         # extension on DOS 8.3 filesystems.
41014
 
+         func_arith $current - $age
41015
 
+         major=$func_arith_result
41016
 
+         versuffix="-$major"
41017
 
+         ;;
41018
 
+
41019
 
+       *)
41020
 
+         func_fatal_configuration "unknown library version type \`$version_type'"
41021
 
+         ;;
41022
 
+       esac
41023
 
+
41024
 
+       # Clear the version info if we defaulted, and they specified a release.
41025
 
+       if test -z "$vinfo" && test -n "$release"; then
41026
 
+         major=
41027
 
+         case $version_type in
41028
 
+         darwin)
41029
 
+           # we can't check for "0.0" in archive_cmds due to quoting
41030
 
+           # problems, so we reset it completely
41031
 
+           verstring=
41032
 
+           ;;
41033
 
+         *)
41034
 
+           verstring="0.0"
41035
 
+           ;;
41036
 
+         esac
41037
 
+         if test "$need_version" = no; then
41038
 
+           versuffix=
41039
 
+         else
41040
 
+           versuffix=".0.0"
41041
 
+         fi
41042
 
+       fi
41043
 
+
41044
 
+       # Remove version info from name if versioning should be avoided
41045
 
+       if test "$avoid_version" = yes && test "$need_version" = no; then
41046
 
+         major=
41047
 
+         versuffix=
41048
 
+         verstring=""
41049
 
+       fi
41050
 
+
41051
 
+       # Check to see if the archive will have undefined symbols.
41052
 
+       if test "$allow_undefined" = yes; then
41053
 
+         if test "$allow_undefined_flag" = unsupported; then
41054
 
+           func_warning "undefined symbols not allowed in $host shared libraries"
41055
 
+           build_libtool_libs=no
41056
 
+           build_old_libs=yes
41057
 
+         fi
41058
 
+       else
41059
 
+         # Don't allow undefined symbols.
41060
 
+         allow_undefined_flag="$no_undefined_flag"
41061
 
+       fi
41062
 
+
41063
 
+      fi
41064
 
+
41065
 
+      func_generate_dlsyms "$libname" "$libname" "yes"
41066
 
+      libobjs="$libobjs $symfileobj"
41067
 
+      test "X$libobjs" = "X " && libobjs=
41068
 
+
41069
 
+      if test "$mode" != relink; then
41070
 
+       # Remove our outputs, but don't remove object files since they
41071
 
+       # may have been created when compiling PIC objects.
41072
 
+       removelist=
41073
 
+       tempremovelist=`$ECHO "$output_objdir/*"`
41074
 
+       for p in $tempremovelist; do
41075
 
+         case $p in
41076
 
+           *.$objext | *.gcno)
41077
 
+              ;;
41078
 
+           $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*)
41079
 
+              if test "X$precious_files_regex" != "X"; then
41080
 
+                if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1
41081
 
+                then
41082
 
+                  continue
41083
 
+                fi
41084
 
+              fi
41085
 
+              removelist="$removelist $p"
41086
 
+              ;;
41087
 
+           *) ;;
41088
 
+         esac
41089
 
+       done
41090
 
+       test -n "$removelist" && \
41091
 
+         func_show_eval "${RM}r \$removelist"
41092
 
+      fi
41093
 
+
41094
 
+      # Now set the variables for building old libraries.
41095
 
+      if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then
41096
 
+       oldlibs="$oldlibs $output_objdir/$libname.$libext"
41097
 
+
41098
 
+       # Transform .lo files to .o files.
41099
 
+       oldobjs="$objs "`$ECHO "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP`
41100
 
+      fi
41101
 
+
41102
 
+      # Eliminate all temporary directories.
41103
 
+      #for path in $notinst_path; do
41104
 
+      #        lib_search_path=`$ECHO "X$lib_search_path " | $Xsed -e "s% $path % %g"`
41105
 
+      #        deplibs=`$ECHO "X$deplibs " | $Xsed -e "s% -L$path % %g"`
41106
 
+      #        dependency_libs=`$ECHO "X$dependency_libs " | $Xsed -e "s% -L$path % %g"`
41107
 
+      #done
41108
 
+
41109
 
+      if test -n "$xrpath"; then
41110
 
+       # If the user specified any rpath flags, then add them.
41111
 
+       temp_xrpath=
41112
 
+       for libdir in $xrpath; do
41113
 
+         temp_xrpath="$temp_xrpath -R$libdir"
41114
 
+         case "$finalize_rpath " in
41115
 
+         *" $libdir "*) ;;
41116
 
+         *) finalize_rpath="$finalize_rpath $libdir" ;;
41117
 
+         esac
41118
 
+       done
41119
 
+       if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then
41120
 
+         dependency_libs="$temp_xrpath $dependency_libs"
41121
 
+       fi
41122
 
+      fi
41123
 
+
41124
 
+      # Make sure dlfiles contains only unique files that won't be dlpreopened
41125
 
+      old_dlfiles="$dlfiles"
41126
 
+      dlfiles=
41127
 
+      for lib in $old_dlfiles; do
41128
 
+       case " $dlprefiles $dlfiles " in
41129
 
+       *" $lib "*) ;;
41130
 
+       *) dlfiles="$dlfiles $lib" ;;
41131
 
+       esac
41132
 
+      done
41133
 
+
41134
 
+      # Make sure dlprefiles contains only unique files
41135
 
+      old_dlprefiles="$dlprefiles"
41136
 
+      dlprefiles=
41137
 
+      for lib in $old_dlprefiles; do
41138
 
+       case "$dlprefiles " in
41139
 
+       *" $lib "*) ;;
41140
 
+       *) dlprefiles="$dlprefiles $lib" ;;
41141
 
+       esac
41142
 
+      done
41143
 
+
41144
 
+      if test "$build_libtool_libs" = yes; then
41145
 
+       if test -n "$rpath"; then
41146
 
+         case $host in
41147
 
+         *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc*)
41148
 
+           # these systems don't actually have a c library (as such)!
41149
 
+           ;;
41150
 
+         *-*-rhapsody* | *-*-darwin1.[012])
41151
 
+           # Rhapsody C library is in the System framework
41152
 
+           deplibs="$deplibs System.ltframework"
41153
 
+           ;;
41154
 
+         *-*-netbsd*)
41155
 
+           # Don't link with libc until the a.out ld.so is fixed.
41156
 
+           ;;
41157
 
+         *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
41158
 
+           # Do not include libc due to us having libc/libc_r.
41159
 
+           ;;
41160
 
+         *-*-sco3.2v5* | *-*-sco5v6*)
41161
 
+           # Causes problems with __ctype
41162
 
+           ;;
41163
 
+         *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
41164
 
+           # Compiler inserts libc in the correct place for threads to work
41165
 
+           ;;
41166
 
+         *)
41167
 
+           # Add libc to deplibs on all other systems if necessary.
41168
 
+           if test "$build_libtool_need_lc" = "yes"; then
41169
 
+             deplibs="$deplibs -lc"
41170
 
+           fi
41171
 
+           ;;
41172
 
+         esac
41173
 
+       fi
41174
 
+
41175
 
+       # Transform deplibs into only deplibs that can be linked in shared.
41176
 
+       name_save=$name
41177
 
+       libname_save=$libname
41178
 
+       release_save=$release
41179
 
+       versuffix_save=$versuffix
41180
 
+       major_save=$major
41181
 
+       # I'm not sure if I'm treating the release correctly.  I think
41182
 
+       # release should show up in the -l (ie -lgmp5) so we don't want to
41183
 
+       # add it in twice.  Is that correct?
41184
 
+       release=""
41185
 
+       versuffix=""
41186
 
+       major=""
41187
 
+       newdeplibs=
41188
 
+       droppeddeps=no
41189
 
+       case $deplibs_check_method in
41190
 
+       pass_all)
41191
 
+         # Don't check for shared/static.  Everything works.
41192
 
+         # This might be a little naive.  We might want to check
41193
 
+         # whether the library exists or not.  But this is on
41194
 
+         # osf3 & osf4 and I'm not really sure... Just
41195
 
+         # implementing what was already the behavior.
41196
 
+         newdeplibs=$deplibs
41197
 
+         ;;
41198
 
+       test_compile)
41199
 
+         # This code stresses the "libraries are programs" paradigm to its
41200
 
+         # limits. Maybe even breaks it.  We compile a program, linking it
41201
 
+         # against the deplibs as a proxy for the library.  Then we can check
41202
 
+         # whether they linked in statically or dynamically with ldd.
41203
 
+         $opt_dry_run || $RM conftest.c
41204
 
+         cat > conftest.c <<EOF
41205
 
+         int main() { return 0; }
41206
 
+EOF
41207
 
+         $opt_dry_run || $RM conftest
41208
 
+         if $LTCC $LTCFLAGS -o conftest conftest.c $deplibs; then
41209
 
+           ldd_output=`ldd conftest`
41210
 
+           for i in $deplibs; do
41211
 
+             case $i in
41212
 
+             -l*)
41213
 
+               func_stripname -l '' "$i"
41214
 
+               name=$func_stripname_result
41215
 
+               if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
41216
 
+                 case " $predeps $postdeps " in
41217
 
+                 *" $i "*)
41218
 
+                   newdeplibs="$newdeplibs $i"
41219
 
+                   i=""
41220
 
+                   ;;
41221
 
+                 esac
41222
 
+               fi
41223
 
+               if test -n "$i" ; then
41224
 
+                 libname=`eval "\\$ECHO \"$libname_spec\""`
41225
 
+                 deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
41226
 
+                 set dummy $deplib_matches; shift
41227
 
+                 deplib_match=$1
41228
 
+                 if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
41229
 
+                   newdeplibs="$newdeplibs $i"
41230
 
+                 else
41231
 
+                   droppeddeps=yes
41232
 
+                   $ECHO
41233
 
+                   $ECHO "*** Warning: dynamic linker does not accept needed library $i."
41234
 
+                   $ECHO "*** I have the capability to make that library automatically link in when"
41235
 
+                   $ECHO "*** you link to this library.  But I can only do this if you have a"
41236
 
+                   $ECHO "*** shared version of the library, which I believe you do not have"
41237
 
+                   $ECHO "*** because a test_compile did reveal that the linker did not use it for"
41238
 
+                   $ECHO "*** its dynamic dependency list that programs get resolved with at runtime."
41239
 
+                 fi
41240
 
+               fi
41241
 
+               ;;
41242
 
+             *)
41243
 
+               newdeplibs="$newdeplibs $i"
41244
 
+               ;;
41245
 
+             esac
41246
 
+           done
41247
 
+         else
41248
 
+           # Error occurred in the first compile.  Let's try to salvage
41249
 
+           # the situation: Compile a separate program for each library.
41250
 
+           for i in $deplibs; do
41251
 
+             case $i in
41252
 
+             -l*)
41253
 
+               func_stripname -l '' "$i"
41254
 
+               name=$func_stripname_result
41255
 
+               $opt_dry_run || $RM conftest
41256
 
+               if $LTCC $LTCFLAGS -o conftest conftest.c $i; then
41257
 
+                 ldd_output=`ldd conftest`
41258
 
+                 if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
41259
 
+                   case " $predeps $postdeps " in
41260
 
+                   *" $i "*)
41261
 
+                     newdeplibs="$newdeplibs $i"
41262
 
+                     i=""
41263
 
+                     ;;
41264
 
+                   esac
41265
 
+                 fi
41266
 
+                 if test -n "$i" ; then
41267
 
+                   libname=`eval "\\$ECHO \"$libname_spec\""`
41268
 
+                   deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
41269
 
+                   set dummy $deplib_matches; shift
41270
 
+                   deplib_match=$1
41271
 
+                   if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
41272
 
+                     newdeplibs="$newdeplibs $i"
41273
 
+                   else
41274
 
+                     droppeddeps=yes
41275
 
+                     $ECHO
41276
 
+                     $ECHO "*** Warning: dynamic linker does not accept needed library $i."
41277
 
+                     $ECHO "*** I have the capability to make that library automatically link in when"
41278
 
+                     $ECHO "*** you link to this library.  But I can only do this if you have a"
41279
 
+                     $ECHO "*** shared version of the library, which you do not appear to have"
41280
 
+                     $ECHO "*** because a test_compile did reveal that the linker did not use this one"
41281
 
+                     $ECHO "*** as a dynamic dependency that programs can get resolved with at runtime."
41282
 
+                   fi
41283
 
+                 fi
41284
 
+               else
41285
 
+                 droppeddeps=yes
41286
 
+                 $ECHO
41287
 
+                 $ECHO "*** Warning!  Library $i is needed by this library but I was not able to"
41288
 
+                 $ECHO "*** make it link in!  You will probably need to install it or some"
41289
 
+                 $ECHO "*** library that it depends on before this library will be fully"
41290
 
+                 $ECHO "*** functional.  Installing it before continuing would be even better."
41291
 
+               fi
41292
 
+               ;;
41293
 
+             *)
41294
 
+               newdeplibs="$newdeplibs $i"
41295
 
+               ;;
41296
 
+             esac
41297
 
+           done
41298
 
+         fi
41299
 
+         ;;
41300
 
+       file_magic*)
41301
 
+         set dummy $deplibs_check_method; shift
41302
 
+         file_magic_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
41303
 
+         for a_deplib in $deplibs; do
41304
 
+           case $a_deplib in
41305
 
+           -l*)
41306
 
+             func_stripname -l '' "$a_deplib"
41307
 
+             name=$func_stripname_result
41308
 
+             if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
41309
 
+               case " $predeps $postdeps " in
41310
 
+               *" $a_deplib "*)
41311
 
+                 newdeplibs="$newdeplibs $a_deplib"
41312
 
+                 a_deplib=""
41313
 
+                 ;;
41314
 
+               esac
41315
 
+             fi
41316
 
+             if test -n "$a_deplib" ; then
41317
 
+               libname=`eval "\\$ECHO \"$libname_spec\""`
41318
 
+               for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
41319
 
+                 potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
41320
 
+                 for potent_lib in $potential_libs; do
41321
 
+                     # Follow soft links.
41322
 
+                     if ls -lLd "$potent_lib" 2>/dev/null |
41323
 
+                        $GREP " -> " >/dev/null; then
41324
 
+                       continue
41325
 
+                     fi
41326
 
+                     # The statement above tries to avoid entering an
41327
 
+                     # endless loop below, in case of cyclic links.
41328
 
+                     # We might still enter an endless loop, since a link
41329
 
+                     # loop can be closed while we follow links,
41330
 
+                     # but so what?
41331
 
+                     potlib="$potent_lib"
41332
 
+                     while test -h "$potlib" 2>/dev/null; do
41333
 
+                       potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'`
41334
 
+                       case $potliblink in
41335
 
+                       [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";;
41336
 
+                       *) potlib=`$ECHO "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";;
41337
 
+                       esac
41338
 
+                     done
41339
 
+                     if eval $file_magic_cmd \"\$potlib\" 2>/dev/null |
41340
 
+                        $SED -e 10q |
41341
 
+                        $EGREP "$file_magic_regex" > /dev/null; then
41342
 
+                       newdeplibs="$newdeplibs $a_deplib"
41343
 
+                       a_deplib=""
41344
 
+                       break 2
41345
 
+                     fi
41346
 
+                 done
41347
 
+               done
41348
 
+             fi
41349
 
+             if test -n "$a_deplib" ; then
41350
 
+               droppeddeps=yes
41351
 
+               $ECHO
41352
 
+               $ECHO "*** Warning: linker path does not have real file for library $a_deplib."
41353
 
+               $ECHO "*** I have the capability to make that library automatically link in when"
41354
 
+               $ECHO "*** you link to this library.  But I can only do this if you have a"
41355
 
+               $ECHO "*** shared version of the library, which you do not appear to have"
41356
 
+               $ECHO "*** because I did check the linker path looking for a file starting"
41357
 
+               if test -z "$potlib" ; then
41358
 
+                 $ECHO "*** with $libname but no candidates were found. (...for file magic test)"
41359
 
+               else
41360
 
+                 $ECHO "*** with $libname and none of the candidates passed a file format test"
41361
 
+                 $ECHO "*** using a file magic. Last file checked: $potlib"
41362
 
+               fi
41363
 
+             fi
41364
 
+             ;;
41365
 
+           *)
41366
 
+             # Add a -L argument.
41367
 
+             newdeplibs="$newdeplibs $a_deplib"
41368
 
+             ;;
41369
 
+           esac
41370
 
+         done # Gone through all deplibs.
41371
 
+         ;;
41372
 
+       match_pattern*)
41373
 
+         set dummy $deplibs_check_method; shift
41374
 
+         match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
41375
 
+         for a_deplib in $deplibs; do
41376
 
+           case $a_deplib in
41377
 
+           -l*)
41378
 
+             func_stripname -l '' "$a_deplib"
41379
 
+             name=$func_stripname_result
41380
 
+             if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
41381
 
+               case " $predeps $postdeps " in
41382
 
+               *" $a_deplib "*)
41383
 
+                 newdeplibs="$newdeplibs $a_deplib"
41384
 
+                 a_deplib=""
41385
 
+                 ;;
41386
 
+               esac
41387
 
+             fi
41388
 
+             if test -n "$a_deplib" ; then
41389
 
+               libname=`eval "\\$ECHO \"$libname_spec\""`
41390
 
+               for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
41391
 
+                 potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
41392
 
+                 for potent_lib in $potential_libs; do
41393
 
+                   potlib="$potent_lib" # see symlink-check above in file_magic test
41394
 
+                   if eval "\$ECHO \"X$potent_lib\"" 2>/dev/null | $Xsed -e 10q | \
41395
 
+                      $EGREP "$match_pattern_regex" > /dev/null; then
41396
 
+                     newdeplibs="$newdeplibs $a_deplib"
41397
 
+                     a_deplib=""
41398
 
+                     break 2
41399
 
+                   fi
41400
 
+                 done
41401
 
+               done
41402
 
+             fi
41403
 
+             if test -n "$a_deplib" ; then
41404
 
+               droppeddeps=yes
41405
 
+               $ECHO
41406
 
+               $ECHO "*** Warning: linker path does not have real file for library $a_deplib."
41407
 
+               $ECHO "*** I have the capability to make that library automatically link in when"
41408
 
+               $ECHO "*** you link to this library.  But I can only do this if you have a"
41409
 
+               $ECHO "*** shared version of the library, which you do not appear to have"
41410
 
+               $ECHO "*** because I did check the linker path looking for a file starting"
41411
 
+               if test -z "$potlib" ; then
41412
 
+                 $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)"
41413
 
+               else
41414
 
+                 $ECHO "*** with $libname and none of the candidates passed a file format test"
41415
 
+                 $ECHO "*** using a regex pattern. Last file checked: $potlib"
41416
 
+               fi
41417
 
+             fi
41418
 
+             ;;
41419
 
+           *)
41420
 
+             # Add a -L argument.
41421
 
+             newdeplibs="$newdeplibs $a_deplib"
41422
 
+             ;;
41423
 
+           esac
41424
 
+         done # Gone through all deplibs.
41425
 
+         ;;
41426
 
+       none | unknown | *)
41427
 
+         newdeplibs=""
41428
 
+         tmp_deplibs=`$ECHO "X $deplibs" | $Xsed \
41429
 
+             -e 's/ -lc$//' -e 's/ -[LR][^ ]*//g'`
41430
 
+         if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
41431
 
+           for i in $predeps $postdeps ; do
41432
 
+             # can't use Xsed below, because $i might contain '/'
41433
 
+             tmp_deplibs=`$ECHO "X $tmp_deplibs" | $Xsed -e "s,$i,,"`
41434
 
+           done
41435
 
+         fi
41436
 
+         if $ECHO "X $tmp_deplibs" | $Xsed -e 's/[      ]//g' |
41437
 
+            $GREP . >/dev/null; then
41438
 
+           $ECHO
41439
 
+           if test "X$deplibs_check_method" = "Xnone"; then
41440
 
+             $ECHO "*** Warning: inter-library dependencies are not supported in this platform."
41441
 
+           else
41442
 
+             $ECHO "*** Warning: inter-library dependencies are not known to be supported."
41443
 
+           fi
41444
 
+           $ECHO "*** All declared inter-library dependencies are being dropped."
41445
 
+           droppeddeps=yes
41446
 
+         fi
41447
 
+         ;;
41448
 
+       esac
41449
 
+       versuffix=$versuffix_save
41450
 
+       major=$major_save
41451
 
+       release=$release_save
41452
 
+       libname=$libname_save
41453
 
+       name=$name_save
41454
 
+
41455
 
+       case $host in
41456
 
+       *-*-rhapsody* | *-*-darwin1.[012])
41457
 
+         # On Rhapsody replace the C library with the System framework
41458
 
+         newdeplibs=`$ECHO "X $newdeplibs" | $Xsed -e 's/ -lc / System.ltframework /'`
41459
 
+         ;;
41460
 
+       esac
41461
 
+
41462
 
+       if test "$droppeddeps" = yes; then
41463
 
+         if test "$module" = yes; then
41464
 
+           $ECHO
41465
 
+           $ECHO "*** Warning: libtool could not satisfy all declared inter-library"
41466
 
+           $ECHO "*** dependencies of module $libname.  Therefore, libtool will create"
41467
 
+           $ECHO "*** a static module, that should work as long as the dlopening"
41468
 
+           $ECHO "*** application is linked with the -dlopen flag."
41469
 
+           if test -z "$global_symbol_pipe"; then
41470
 
+             $ECHO
41471
 
+             $ECHO "*** However, this would only work if libtool was able to extract symbol"
41472
 
+             $ECHO "*** lists from a program, using \`nm' or equivalent, but libtool could"
41473
 
+             $ECHO "*** not find such a program.  So, this module is probably useless."
41474
 
+             $ECHO "*** \`nm' from GNU binutils and a full rebuild may help."
41475
 
+           fi
41476
 
+           if test "$build_old_libs" = no; then
41477
 
+             oldlibs="$output_objdir/$libname.$libext"
41478
 
+             build_libtool_libs=module
41479
 
+             build_old_libs=yes
41480
 
+           else
41481
 
+             build_libtool_libs=no
41482
 
+           fi
41483
 
+         else
41484
 
+           $ECHO "*** The inter-library dependencies that have been dropped here will be"
41485
 
+           $ECHO "*** automatically added whenever a program is linked with this library"
41486
 
+           $ECHO "*** or is declared to -dlopen it."
41487
 
+
41488
 
+           if test "$allow_undefined" = no; then
41489
 
+             $ECHO
41490
 
+             $ECHO "*** Since this library must not contain undefined symbols,"
41491
 
+             $ECHO "*** because either the platform does not support them or"
41492
 
+             $ECHO "*** it was explicitly requested with -no-undefined,"
41493
 
+             $ECHO "*** libtool will only create a static version of it."
41494
 
+             if test "$build_old_libs" = no; then
41495
 
+               oldlibs="$output_objdir/$libname.$libext"
41496
 
+               build_libtool_libs=module
41497
 
+               build_old_libs=yes
41498
 
+             else
41499
 
+               build_libtool_libs=no
41500
 
+             fi
41501
 
+           fi
41502
 
+         fi
41503
 
+       fi
41504
 
+       # Done checking deplibs!
41505
 
+       deplibs=$newdeplibs
41506
 
+      fi
41507
 
+      # Time to change all our "foo.ltframework" stuff back to "-framework foo"
41508
 
+      case $host in
41509
 
+       *-*-darwin*)
41510
 
+         newdeplibs=`$ECHO "X $newdeplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
41511
 
+         new_inherited_linker_flags=`$ECHO "X $new_inherited_linker_flags" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
41512
 
+         deplibs=`$ECHO "X $deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
41513
 
+         ;;
41514
 
+      esac
41515
 
+
41516
 
+      # move library search paths that coincide with paths to not yet
41517
 
+      # installed libraries to the beginning of the library search list
41518
 
+      new_libs=
41519
 
+      for path in $notinst_path; do
41520
 
+       case " $new_libs " in
41521
 
+       *" -L$path/$objdir "*) ;;
41522
 
+       *)
41523
 
+         case " $deplibs " in
41524
 
+         *" -L$path/$objdir "*)
41525
 
+           new_libs="$new_libs -L$path/$objdir" ;;
41526
 
+         esac
41527
 
+         ;;
41528
 
+       esac
41529
 
+      done
41530
 
+      for deplib in $deplibs; do
41531
 
+       case $deplib in
41532
 
+       -L*)
41533
 
+         case " $new_libs " in
41534
 
+         *" $deplib "*) ;;
41535
 
+         *) new_libs="$new_libs $deplib" ;;
41536
 
+         esac
41537
 
+         ;;
41538
 
+       *) new_libs="$new_libs $deplib" ;;
41539
 
+       esac
41540
 
+      done
41541
 
+      deplibs="$new_libs"
41542
 
+
41543
 
+      # All the library-specific variables (install_libdir is set above).
41544
 
+      library_names=
41545
 
+      old_library=
41546
 
+      dlname=
41547
 
+
41548
 
+      # Test again, we may have decided not to build it any more
41549
 
+      if test "$build_libtool_libs" = yes; then
41550
 
+       if test "$hardcode_into_libs" = yes; then
41551
 
+         # Hardcode the library paths
41552
 
+         hardcode_libdirs=
41553
 
+         dep_rpath=
41554
 
+         rpath="$finalize_rpath"
41555
 
+         test "$mode" != relink && rpath="$compile_rpath$rpath"
41556
 
+         for libdir in $rpath; do
41557
 
+           if test -n "$hardcode_libdir_flag_spec"; then
41558
 
+             if test -n "$hardcode_libdir_separator"; then
41559
 
+               if test -z "$hardcode_libdirs"; then
41560
 
+                 hardcode_libdirs="$libdir"
41561
 
+               else
41562
 
+                 # Just accumulate the unique libdirs.
41563
 
+                 case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
41564
 
+                 *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
41565
 
+                   ;;
41566
 
+                 *)
41567
 
+                   hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
41568
 
+                   ;;
41569
 
+                 esac
41570
 
+               fi
41571
 
+             else
41572
 
+               eval flag=\"$hardcode_libdir_flag_spec\"
41573
 
+               dep_rpath="$dep_rpath $flag"
41574
 
+             fi
41575
 
+           elif test -n "$runpath_var"; then
41576
 
+             case "$perm_rpath " in
41577
 
+             *" $libdir "*) ;;
41578
 
+             *) perm_rpath="$perm_rpath $libdir" ;;
41579
 
+             esac
41580
 
+           fi
41581
 
+         done
41582
 
+         # Substitute the hardcoded libdirs into the rpath.
41583
 
+         if test -n "$hardcode_libdir_separator" &&
41584
 
+            test -n "$hardcode_libdirs"; then
41585
 
+           libdir="$hardcode_libdirs"
41586
 
+           if test -n "$hardcode_libdir_flag_spec_ld"; then
41587
 
+             eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\"
41588
 
+           else
41589
 
+             eval dep_rpath=\"$hardcode_libdir_flag_spec\"
41590
 
+           fi
41591
 
+         fi
41592
 
+         if test -n "$runpath_var" && test -n "$perm_rpath"; then
41593
 
+           # We should set the runpath_var.
41594
 
+           rpath=
41595
 
+           for dir in $perm_rpath; do
41596
 
+             rpath="$rpath$dir:"
41597
 
+           done
41598
 
+           eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var"
41599
 
+         fi
41600
 
+         test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs"
41601
 
+       fi
41602
 
+
41603
 
+       shlibpath="$finalize_shlibpath"
41604
 
+       test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath"
41605
 
+       if test -n "$shlibpath"; then
41606
 
+         eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var"
41607
 
+       fi
41608
 
+
41609
 
+       # Get the real and link names of the library.
41610
 
+       eval shared_ext=\"$shrext_cmds\"
41611
 
+       eval library_names=\"$library_names_spec\"
41612
 
+       set dummy $library_names
41613
 
+       shift
41614
 
+       realname="$1"
41615
 
+       shift
41616
 
+
41617
 
+       if test -n "$soname_spec"; then
41618
 
+         eval soname=\"$soname_spec\"
41619
 
+       else
41620
 
+         soname="$realname"
41621
 
+       fi
41622
 
+       if test -z "$dlname"; then
41623
 
+         dlname=$soname
41624
 
+       fi
41625
 
+
41626
 
+       lib="$output_objdir/$realname"
41627
 
+       linknames=
41628
 
+       for link
41629
 
+       do
41630
 
+         linknames="$linknames $link"
41631
 
+       done
41632
 
+
41633
 
+       # Use standard objects if they are pic
41634
 
+       test -z "$pic_flag" && libobjs=`$ECHO "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
41635
 
+       test "X$libobjs" = "X " && libobjs=
41636
 
+
41637
 
+       delfiles=
41638
 
+       if test -n "$export_symbols" && test -n "$include_expsyms"; then
41639
 
+         $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp"
41640
 
+         export_symbols="$output_objdir/$libname.uexp"
41641
 
+         delfiles="$delfiles $export_symbols"
41642
 
+       fi
41643
 
+
41644
 
+       orig_export_symbols=
41645
 
+       case $host_os in
41646
 
+       cygwin* | mingw* | cegcc*)
41647
 
+         if test -n "$export_symbols" && test -z "$export_symbols_regex"; then
41648
 
+           # exporting using user supplied symfile
41649
 
+           if test "x`$SED 1q $export_symbols`" != xEXPORTS; then
41650
 
+             # and it's NOT already a .def file. Must figure out
41651
 
+             # which of the given symbols are data symbols and tag
41652
 
+             # them as such. So, trigger use of export_symbols_cmds.
41653
 
+             # export_symbols gets reassigned inside the "prepare
41654
 
+             # the list of exported symbols" if statement, so the
41655
 
+             # include_expsyms logic still works.
41656
 
+             orig_export_symbols="$export_symbols"
41657
 
+             export_symbols=
41658
 
+             always_export_symbols=yes
41659
 
+           fi
41660
 
+         fi
41661
 
+         ;;
41662
 
+       esac
41663
 
+
41664
 
+       # Prepare the list of exported symbols
41665
 
+       if test -z "$export_symbols"; then
41666
 
+         if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then
41667
 
+           func_verbose "generating symbol list for \`$libname.la'"
41668
 
+           export_symbols="$output_objdir/$libname.exp"
41669
 
+           $opt_dry_run || $RM $export_symbols
41670
 
+           cmds=$export_symbols_cmds
41671
 
+           save_ifs="$IFS"; IFS='~'
41672
 
+           for cmd in $cmds; do
41673
 
+             IFS="$save_ifs"
41674
 
+             eval cmd=\"$cmd\"
41675
 
+             func_len " $cmd"
41676
 
+             len=$func_len_result
41677
 
+             if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
41678
 
+               func_show_eval "$cmd" 'exit $?'
41679
 
+               skipped_export=false
41680
 
+             else
41681
 
+               # The command line is too long to execute in one step.
41682
 
+               func_verbose "using reloadable object file for export list..."
41683
 
+               skipped_export=:
41684
 
+               # Break out early, otherwise skipped_export may be
41685
 
+               # set to false by a later but shorter cmd.
41686
 
+               break
41687
 
+             fi
41688
 
+           done
41689
 
+           IFS="$save_ifs"
41690
 
+           if test -n "$export_symbols_regex" && test "X$skipped_export" != "X:"; then
41691
 
+             func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
41692
 
+             func_show_eval '$MV "${export_symbols}T" "$export_symbols"'
41693
 
+           fi
41694
 
+         fi
41695
 
+       fi
41696
 
+
41697
 
+       if test -n "$export_symbols" && test -n "$include_expsyms"; then
41698
 
+         tmp_export_symbols="$export_symbols"
41699
 
+         test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols"
41700
 
+         $opt_dry_run || eval '$ECHO "X$include_expsyms" | $Xsed | $SP2NL >> "$tmp_export_symbols"'
41701
 
+       fi
41702
 
+
41703
 
+       if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then
41704
 
+         # The given exports_symbols file has to be filtered, so filter it.
41705
 
+         func_verbose "filter symbol list for \`$libname.la' to tag DATA exports"
41706
 
+         # FIXME: $output_objdir/$libname.filter potentially contains lots of
41707
 
+         # 's' commands which not all seds can handle. GNU sed should be fine
41708
 
+         # though. Also, the filter scales superlinearly with the number of
41709
 
+         # global variables. join(1) would be nice here, but unfortunately
41710
 
+         # isn't a blessed tool.
41711
 
+         $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter
41712
 
+         delfiles="$delfiles $export_symbols $output_objdir/$libname.filter"
41713
 
+         export_symbols=$output_objdir/$libname.def
41714
 
+         $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
41715
 
+       fi
41716
 
+
41717
 
+       tmp_deplibs=
41718
 
+       for test_deplib in $deplibs; do
41719
 
+         case " $convenience " in
41720
 
+         *" $test_deplib "*) ;;
41721
 
+         *)
41722
 
+           tmp_deplibs="$tmp_deplibs $test_deplib"
41723
 
+           ;;
41724
 
+         esac
41725
 
+       done
41726
 
+       deplibs="$tmp_deplibs"
41727
 
+
41728
 
+       if test -n "$convenience"; then
41729
 
+         if test -n "$whole_archive_flag_spec" &&
41730
 
+           test "$compiler_needs_object" = yes &&
41731
 
+           test -z "$libobjs"; then
41732
 
+           # extract the archives, so we have objects to list.
41733
 
+           # TODO: could optimize this to just extract one archive.
41734
 
+           whole_archive_flag_spec=
41735
 
+         fi
41736
 
+         if test -n "$whole_archive_flag_spec"; then
41737
 
+           save_libobjs=$libobjs
41738
 
+           eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
41739
 
+           test "X$libobjs" = "X " && libobjs=
41740
 
+         else
41741
 
+           gentop="$output_objdir/${outputname}x"
41742
 
+           generated="$generated $gentop"
41743
 
+
41744
 
+           func_extract_archives $gentop $convenience
41745
 
+           libobjs="$libobjs $func_extract_archives_result"
41746
 
+           test "X$libobjs" = "X " && libobjs=
41747
 
+         fi
41748
 
+       fi
41749
 
+
41750
 
+       if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then
41751
 
+         eval flag=\"$thread_safe_flag_spec\"
41752
 
+         linker_flags="$linker_flags $flag"
41753
 
+       fi
41754
 
+
41755
 
+       # Make a backup of the uninstalled library when relinking
41756
 
+       if test "$mode" = relink; then
41757
 
+         $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $?
41758
 
+       fi
41759
 
+
41760
 
+       # Do each of the archive commands.
41761
 
+       if test "$module" = yes && test -n "$module_cmds" ; then
41762
 
+         if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
41763
 
+           eval test_cmds=\"$module_expsym_cmds\"
41764
 
+           cmds=$module_expsym_cmds
41765
 
+         else
41766
 
+           eval test_cmds=\"$module_cmds\"
41767
 
+           cmds=$module_cmds
41768
 
+         fi
41769
 
+       else
41770
 
+         if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
41771
 
+           eval test_cmds=\"$archive_expsym_cmds\"
41772
 
+           cmds=$archive_expsym_cmds
41773
 
+         else
41774
 
+           eval test_cmds=\"$archive_cmds\"
41775
 
+           cmds=$archive_cmds
41776
 
+         fi
41777
 
+       fi
41778
 
+
41779
 
+       if test "X$skipped_export" != "X:" &&
41780
 
+          func_len " $test_cmds" &&
41781
 
+          len=$func_len_result &&
41782
 
+          test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
41783
 
+         :
41784
 
+       else
41785
 
+         # The command line is too long to link in one step, link piecewise
41786
 
+         # or, if using GNU ld and skipped_export is not :, use a linker
41787
 
+         # script.
41788
 
+
41789
 
+         # Save the value of $output and $libobjs because we want to
41790
 
+         # use them later.  If we have whole_archive_flag_spec, we
41791
 
+         # want to use save_libobjs as it was before
41792
 
+         # whole_archive_flag_spec was expanded, because we can't
41793
 
+         # assume the linker understands whole_archive_flag_spec.
41794
 
+         # This may have to be revisited, in case too many
41795
 
+         # convenience libraries get linked in and end up exceeding
41796
 
+         # the spec.
41797
 
+         if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then
41798
 
+           save_libobjs=$libobjs
41799
 
+         fi
41800
 
+         save_output=$output
41801
 
+         output_la=`$ECHO "X$output" | $Xsed -e "$basename"`
41802
 
+
41803
 
+         # Clear the reloadable object creation command queue and
41804
 
+         # initialize k to one.
41805
 
+         test_cmds=
41806
 
+         concat_cmds=
41807
 
+         objlist=
41808
 
+         last_robj=
41809
 
+         k=1
41810
 
+
41811
 
+         if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then
41812
 
+           output=${output_objdir}/${output_la}.lnkscript
41813
 
+           func_verbose "creating GNU ld script: $output"
41814
 
+           $ECHO 'INPUT (' > $output
41815
 
+           for obj in $save_libobjs
41816
 
+           do
41817
 
+             $ECHO "$obj" >> $output
41818
 
+           done
41819
 
+           $ECHO ')' >> $output
41820
 
+           delfiles="$delfiles $output"
41821
 
+         elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then
41822
 
+           output=${output_objdir}/${output_la}.lnk
41823
 
+           func_verbose "creating linker input file list: $output"
41824
 
+           : > $output
41825
 
+           set x $save_libobjs
41826
 
+           shift
41827
 
+           firstobj=
41828
 
+           if test "$compiler_needs_object" = yes; then
41829
 
+             firstobj="$1 "
41830
 
+             shift
41831
 
+           fi
41832
 
+           for obj
41833
 
+           do
41834
 
+             $ECHO "$obj" >> $output
41835
 
+           done
41836
 
+           delfiles="$delfiles $output"
41837
 
+           output=$firstobj\"$file_list_spec$output\"
41838
 
+         else
41839
 
+           if test -n "$save_libobjs"; then
41840
 
+             func_verbose "creating reloadable object files..."
41841
 
+             output=$output_objdir/$output_la-${k}.$objext
41842
 
+             eval test_cmds=\"$reload_cmds\"
41843
 
+             func_len " $test_cmds"
41844
 
+             len0=$func_len_result
41845
 
+             len=$len0
41846
 
+
41847
 
+             # Loop over the list of objects to be linked.
41848
 
+             for obj in $save_libobjs
41849
 
+             do
41850
 
+               func_len " $obj"
41851
 
+               func_arith $len + $func_len_result
41852
 
+               len=$func_arith_result
41853
 
+               if test "X$objlist" = X ||
41854
 
+                  test "$len" -lt "$max_cmd_len"; then
41855
 
+                 func_append objlist " $obj"
41856
 
+               else
41857
 
+                 # The command $test_cmds is almost too long, add a
41858
 
+                 # command to the queue.
41859
 
+                 if test "$k" -eq 1 ; then
41860
 
+                   # The first file doesn't have a previous command to add.
41861
 
+                   eval concat_cmds=\"$reload_cmds $objlist $last_robj\"
41862
 
+                 else
41863
 
+                   # All subsequent reloadable object files will link in
41864
 
+                   # the last one created.
41865
 
+                   eval concat_cmds=\"\$concat_cmds~$reload_cmds $objlist $last_robj~\$RM $last_robj\"
41866
 
+                 fi
41867
 
+                 last_robj=$output_objdir/$output_la-${k}.$objext
41868
 
+                 func_arith $k + 1
41869
 
+                 k=$func_arith_result
41870
 
+                 output=$output_objdir/$output_la-${k}.$objext
41871
 
+                 objlist=$obj
41872
 
+                 func_len " $last_robj"
41873
 
+                 func_arith $len0 + $func_len_result
41874
 
+                 len=$func_arith_result
41875
 
+               fi
41876
 
+             done
41877
 
+             # Handle the remaining objects by creating one last
41878
 
+             # reloadable object file.  All subsequent reloadable object
41879
 
+             # files will link in the last one created.
41880
 
+             test -z "$concat_cmds" || concat_cmds=$concat_cmds~
41881
 
+             eval concat_cmds=\"\${concat_cmds}$reload_cmds $objlist $last_robj\"
41882
 
+             if test -n "$last_robj"; then
41883
 
+               eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\"
41884
 
+             fi
41885
 
+             delfiles="$delfiles $output"
41886
 
+
41887
 
+           else
41888
 
+             output=
41889
 
+           fi
41890
 
+
41891
 
+           if ${skipped_export-false}; then
41892
 
+             func_verbose "generating symbol list for \`$libname.la'"
41893
 
+             export_symbols="$output_objdir/$libname.exp"
41894
 
+             $opt_dry_run || $RM $export_symbols
41895
 
+             libobjs=$output
41896
 
+             # Append the command to create the export file.
41897
 
+             test -z "$concat_cmds" || concat_cmds=$concat_cmds~
41898
 
+             eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\"
41899
 
+             if test -n "$last_robj"; then
41900
 
+               eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\"
41901
 
+             fi
41902
 
+           fi
41903
 
+
41904
 
+           test -n "$save_libobjs" &&
41905
 
+             func_verbose "creating a temporary reloadable object file: $output"
41906
 
+
41907
 
+           # Loop through the commands generated above and execute them.
41908
 
+           save_ifs="$IFS"; IFS='~'
41909
 
+           for cmd in $concat_cmds; do
41910
 
+             IFS="$save_ifs"
41911
 
+             $opt_silent || {
41912
 
+                 func_quote_for_expand "$cmd"
41913
 
+                 eval "func_echo $func_quote_for_expand_result"
41914
 
+             }
41915
 
+             $opt_dry_run || eval "$cmd" || {
41916
 
+               lt_exit=$?
41917
 
+
41918
 
+               # Restore the uninstalled library and exit
41919
 
+               if test "$mode" = relink; then
41920
 
+                 ( cd "$output_objdir" && \
41921
 
+                   $RM "${realname}T" && \
41922
 
+                   $MV "${realname}U" "$realname" )
41923
 
+               fi
41924
 
+
41925
 
+               exit $lt_exit
41926
 
+             }
41927
 
+           done
41928
 
+           IFS="$save_ifs"
41929
 
+
41930
 
+           if test -n "$export_symbols_regex" && ${skipped_export-false}; then
41931
 
+             func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
41932
 
+             func_show_eval '$MV "${export_symbols}T" "$export_symbols"'
41933
 
+           fi
41934
 
+         fi
41935
 
+
41936
 
+          if ${skipped_export-false}; then
41937
 
+           if test -n "$export_symbols" && test -n "$include_expsyms"; then
41938
 
+             tmp_export_symbols="$export_symbols"
41939
 
+             test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols"
41940
 
+             $opt_dry_run || eval '$ECHO "X$include_expsyms" | $Xsed | $SP2NL >> "$tmp_export_symbols"'
41941
 
+           fi
41942
 
+
41943
 
+           if test -n "$orig_export_symbols"; then
41944
 
+             # The given exports_symbols file has to be filtered, so filter it.
41945
 
+             func_verbose "filter symbol list for \`$libname.la' to tag DATA exports"
41946
 
+             # FIXME: $output_objdir/$libname.filter potentially contains lots of
41947
 
+             # 's' commands which not all seds can handle. GNU sed should be fine
41948
 
+             # though. Also, the filter scales superlinearly with the number of
41949
 
+             # global variables. join(1) would be nice here, but unfortunately
41950
 
+             # isn't a blessed tool.
41951
 
+             $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter
41952
 
+             delfiles="$delfiles $export_symbols $output_objdir/$libname.filter"
41953
 
+             export_symbols=$output_objdir/$libname.def
41954
 
+             $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
41955
 
+           fi
41956
 
+         fi
41957
 
+
41958
 
+         libobjs=$output
41959
 
+         # Restore the value of output.
41960
 
+         output=$save_output
41961
 
+
41962
 
+         if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then
41963
 
+           eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
41964
 
+           test "X$libobjs" = "X " && libobjs=
41965
 
+         fi
41966
 
+         # Expand the library linking commands again to reset the
41967
 
+         # value of $libobjs for piecewise linking.
41968
 
+
41969
 
+         # Do each of the archive commands.
41970
 
+         if test "$module" = yes && test -n "$module_cmds" ; then
41971
 
+           if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
41972
 
+             cmds=$module_expsym_cmds
41973
 
+           else
41974
 
+             cmds=$module_cmds
41975
 
+           fi
41976
 
+         else
41977
 
+           if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
41978
 
+             cmds=$archive_expsym_cmds
41979
 
+           else
41980
 
+             cmds=$archive_cmds
41981
 
+           fi
41982
 
+         fi
41983
 
+       fi
41984
 
+
41985
 
+       if test -n "$delfiles"; then
41986
 
+         # Append the command to remove temporary files to $cmds.
41987
 
+         eval cmds=\"\$cmds~\$RM $delfiles\"
41988
 
+       fi
41989
 
+
41990
 
+       # Add any objects from preloaded convenience libraries
41991
 
+       if test -n "$dlprefiles"; then
41992
 
+         gentop="$output_objdir/${outputname}x"
41993
 
+         generated="$generated $gentop"
41994
 
+
41995
 
+         func_extract_archives $gentop $dlprefiles
41996
 
+         libobjs="$libobjs $func_extract_archives_result"
41997
 
+         test "X$libobjs" = "X " && libobjs=
41998
 
+       fi
41999
 
+
42000
 
+       save_ifs="$IFS"; IFS='~'
42001
 
+       for cmd in $cmds; do
42002
 
+         IFS="$save_ifs"
42003
 
+         eval cmd=\"$cmd\"
42004
 
+         $opt_silent || {
42005
 
+           func_quote_for_expand "$cmd"
42006
 
+           eval "func_echo $func_quote_for_expand_result"
42007
 
+         }
42008
 
+         $opt_dry_run || eval "$cmd" || {
42009
 
+           lt_exit=$?
42010
 
+
42011
 
+           # Restore the uninstalled library and exit
42012
 
+           if test "$mode" = relink; then
42013
 
+             ( cd "$output_objdir" && \
42014
 
+               $RM "${realname}T" && \
42015
 
+               $MV "${realname}U" "$realname" )
42016
 
+           fi
42017
 
+
42018
 
+           exit $lt_exit
42019
 
+         }
42020
 
+       done
42021
 
+       IFS="$save_ifs"
42022
 
+
42023
 
+       # Restore the uninstalled library and exit
42024
 
+       if test "$mode" = relink; then
42025
 
+         $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $?
42026
 
+
42027
 
+         if test -n "$convenience"; then
42028
 
+           if test -z "$whole_archive_flag_spec"; then
42029
 
+             func_show_eval '${RM}r "$gentop"'
42030
 
+           fi
42031
 
+         fi
42032
 
+
42033
 
+         exit $EXIT_SUCCESS
42034
 
+       fi
42035
 
+
42036
 
+       # Create links to the real library.
42037
 
+       for linkname in $linknames; do
42038
 
+         if test "$realname" != "$linkname"; then
42039
 
+           func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?'
42040
 
+         fi
42041
 
+       done
42042
 
+
42043
 
+       # If -module or -export-dynamic was specified, set the dlname.
42044
 
+       if test "$module" = yes || test "$export_dynamic" = yes; then
42045
 
+         # On all known operating systems, these are identical.
42046
 
+         dlname="$soname"
42047
 
+       fi
42048
 
+      fi
42049
 
+      ;;
42050
 
+
42051
 
+    obj)
42052
 
+      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
42053
 
+       func_warning "\`-dlopen' is ignored for objects"
42054
 
+      fi
42055
 
+
42056
 
+      case " $deplibs" in
42057
 
+      *\ -l* | *\ -L*)
42058
 
+       func_warning "\`-l' and \`-L' are ignored for objects" ;;
42059
 
+      esac
42060
 
+
42061
 
+      test -n "$rpath" && \
42062
 
+       func_warning "\`-rpath' is ignored for objects"
42063
 
+
42064
 
+      test -n "$xrpath" && \
42065
 
+       func_warning "\`-R' is ignored for objects"
42066
 
+
42067
 
+      test -n "$vinfo" && \
42068
 
+       func_warning "\`-version-info' is ignored for objects"
42069
 
+
42070
 
+      test -n "$release" && \
42071
 
+       func_warning "\`-release' is ignored for objects"
42072
 
+
42073
 
+      case $output in
42074
 
+      *.lo)
42075
 
+       test -n "$objs$old_deplibs" && \
42076
 
+         func_fatal_error "cannot build library object \`$output' from non-libtool objects"
42077
 
+
42078
 
+       libobj=$output
42079
 
+       func_lo2o "$libobj"
42080
 
+       obj=$func_lo2o_result
42081
 
+       ;;
42082
 
+      *)
42083
 
+       libobj=
42084
 
+       obj="$output"
42085
 
+       ;;
42086
 
+      esac
42087
 
+
42088
 
+      # Delete the old objects.
42089
 
+      $opt_dry_run || $RM $obj $libobj
42090
 
+
42091
 
+      # Objects from convenience libraries.  This assumes
42092
 
+      # single-version convenience libraries.  Whenever we create
42093
 
+      # different ones for PIC/non-PIC, this we'll have to duplicate
42094
 
+      # the extraction.
42095
 
+      reload_conv_objs=
42096
 
+      gentop=
42097
 
+      # reload_cmds runs $LD directly, so let us get rid of
42098
 
+      # -Wl from whole_archive_flag_spec and hope we can get by with
42099
 
+      # turning comma into space..
42100
 
+      wl=
42101
 
+
42102
 
+      if test -n "$convenience"; then
42103
 
+       if test -n "$whole_archive_flag_spec"; then
42104
 
+         eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\"
42105
 
+         reload_conv_objs=$reload_objs\ `$ECHO "X$tmp_whole_archive_flags" | $Xsed -e 's|,| |g'`
42106
 
+       else
42107
 
+         gentop="$output_objdir/${obj}x"
42108
 
+         generated="$generated $gentop"
42109
 
+
42110
 
+         func_extract_archives $gentop $convenience
42111
 
+         reload_conv_objs="$reload_objs $func_extract_archives_result"
42112
 
+       fi
42113
 
+      fi
42114
 
+
42115
 
+      # Create the old-style object.
42116
 
+      reload_objs="$objs$old_deplibs "`$ECHO "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test
42117
 
+
42118
 
+      output="$obj"
42119
 
+      func_execute_cmds "$reload_cmds" 'exit $?'
42120
 
+
42121
 
+      # Exit if we aren't doing a library object file.
42122
 
+      if test -z "$libobj"; then
42123
 
+       if test -n "$gentop"; then
42124
 
+         func_show_eval '${RM}r "$gentop"'
42125
 
+       fi
42126
 
+
42127
 
+       exit $EXIT_SUCCESS
42128
 
+      fi
42129
 
+
42130
 
+      if test "$build_libtool_libs" != yes; then
42131
 
+       if test -n "$gentop"; then
42132
 
+         func_show_eval '${RM}r "$gentop"'
42133
 
+       fi
42134
 
+
42135
 
+       # Create an invalid libtool object if no PIC, so that we don't
42136
 
+       # accidentally link it into a program.
42137
 
+       # $show "echo timestamp > $libobj"
42138
 
+       # $opt_dry_run || eval "echo timestamp > $libobj" || exit $?
42139
 
+       exit $EXIT_SUCCESS
42140
 
+      fi
42141
 
+
42142
 
+      if test -n "$pic_flag" || test "$pic_mode" != default; then
42143
 
+       # Only do commands if we really have different PIC objects.
42144
 
+       reload_objs="$libobjs $reload_conv_objs"
42145
 
+       output="$libobj"
42146
 
+       func_execute_cmds "$reload_cmds" 'exit $?'
42147
 
+      fi
42148
 
+
42149
 
+      if test -n "$gentop"; then
42150
 
+       func_show_eval '${RM}r "$gentop"'
42151
 
+      fi
42152
 
+
42153
 
+      exit $EXIT_SUCCESS
42154
 
+      ;;
42155
 
+
42156
 
+    prog)
42157
 
+      case $host in
42158
 
+       *cygwin*) func_stripname '' '.exe' "$output"
42159
 
+                 output=$func_stripname_result.exe;;
42160
 
+      esac
42161
 
+      test -n "$vinfo" && \
42162
 
+       func_warning "\`-version-info' is ignored for programs"
42163
 
+
42164
 
+      test -n "$release" && \
42165
 
+       func_warning "\`-release' is ignored for programs"
42166
 
+
42167
 
+      test "$preload" = yes \
42168
 
+        && test "$dlopen_support" = unknown \
42169
 
+       && test "$dlopen_self" = unknown \
42170
 
+       && test "$dlopen_self_static" = unknown && \
42171
 
+         func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support."
42172
 
+
42173
 
+      case $host in
42174
 
+      *-*-rhapsody* | *-*-darwin1.[012])
42175
 
+       # On Rhapsody replace the C library is the System framework
42176
 
+       compile_deplibs=`$ECHO "X $compile_deplibs" | $Xsed -e 's/ -lc / System.ltframework /'`
42177
 
+       finalize_deplibs=`$ECHO "X $finalize_deplibs" | $Xsed -e 's/ -lc / System.ltframework /'`
42178
 
+       ;;
42179
 
+      esac
42180
 
+
42181
 
+      case $host in
42182
 
+      *-*-darwin*)
42183
 
+       # Don't allow lazy linking, it breaks C++ global constructors
42184
 
+       # But is supposedly fixed on 10.4 or later (yay!).
42185
 
+       if test "$tagname" = CXX ; then
42186
 
+         case ${MACOSX_DEPLOYMENT_TARGET-10.0} in
42187
 
+           10.[0123])
42188
 
+             compile_command="$compile_command ${wl}-bind_at_load"
42189
 
+             finalize_command="$finalize_command ${wl}-bind_at_load"
42190
 
+           ;;
42191
 
+         esac
42192
 
+       fi
42193
 
+       # Time to change all our "foo.ltframework" stuff back to "-framework foo"
42194
 
+       compile_deplibs=`$ECHO "X $compile_deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
42195
 
+       finalize_deplibs=`$ECHO "X $finalize_deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
42196
 
+       ;;
42197
 
+      esac
42198
 
+
42199
 
+
42200
 
+      # move library search paths that coincide with paths to not yet
42201
 
+      # installed libraries to the beginning of the library search list
42202
 
+      new_libs=
42203
 
+      for path in $notinst_path; do
42204
 
+       case " $new_libs " in
42205
 
+       *" -L$path/$objdir "*) ;;
42206
 
+       *)
42207
 
+         case " $compile_deplibs " in
42208
 
+         *" -L$path/$objdir "*)
42209
 
+           new_libs="$new_libs -L$path/$objdir" ;;
42210
 
+         esac
42211
 
+         ;;
42212
 
+       esac
42213
 
+      done
42214
 
+      for deplib in $compile_deplibs; do
42215
 
+       case $deplib in
42216
 
+       -L*)
42217
 
+         case " $new_libs " in
42218
 
+         *" $deplib "*) ;;
42219
 
+         *) new_libs="$new_libs $deplib" ;;
42220
 
+         esac
42221
 
+         ;;
42222
 
+       *) new_libs="$new_libs $deplib" ;;
42223
 
+       esac
42224
 
+      done
42225
 
+      compile_deplibs="$new_libs"
42226
 
+
42227
 
+
42228
 
+      compile_command="$compile_command $compile_deplibs"
42229
 
+      finalize_command="$finalize_command $finalize_deplibs"
42230
 
+
42231
 
+      if test -n "$rpath$xrpath"; then
42232
 
+       # If the user specified any rpath flags, then add them.
42233
 
+       for libdir in $rpath $xrpath; do
42234
 
+         # This is the magic to use -rpath.
42235
 
+         case "$finalize_rpath " in
42236
 
+         *" $libdir "*) ;;
42237
 
+         *) finalize_rpath="$finalize_rpath $libdir" ;;
42238
 
+         esac
42239
 
+       done
42240
 
+      fi
42241
 
+
42242
 
+      # Now hardcode the library paths
42243
 
+      rpath=
42244
 
+      hardcode_libdirs=
42245
 
+      for libdir in $compile_rpath $finalize_rpath; do
42246
 
+       if test -n "$hardcode_libdir_flag_spec"; then
42247
 
+         if test -n "$hardcode_libdir_separator"; then
42248
 
+           if test -z "$hardcode_libdirs"; then
42249
 
+             hardcode_libdirs="$libdir"
42250
 
+           else
42251
 
+             # Just accumulate the unique libdirs.
42252
 
+             case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
42253
 
+             *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
42254
 
+               ;;
42255
 
+             *)
42256
 
+               hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
42257
 
+               ;;
42258
 
+             esac
42259
 
+           fi
42260
 
+         else
42261
 
+           eval flag=\"$hardcode_libdir_flag_spec\"
42262
 
+           rpath="$rpath $flag"
42263
 
+         fi
42264
 
+       elif test -n "$runpath_var"; then
42265
 
+         case "$perm_rpath " in
42266
 
+         *" $libdir "*) ;;
42267
 
+         *) perm_rpath="$perm_rpath $libdir" ;;
42268
 
+         esac
42269
 
+       fi
42270
 
+       case $host in
42271
 
+       *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
42272
 
+         testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'`
42273
 
+         case :$dllsearchpath: in
42274
 
+         *":$libdir:"*) ;;
42275
 
+         ::) dllsearchpath=$libdir;;
42276
 
+         *) dllsearchpath="$dllsearchpath:$libdir";;
42277
 
+         esac
42278
 
+         case :$dllsearchpath: in
42279
 
+         *":$testbindir:"*) ;;
42280
 
+         ::) dllsearchpath=$testbindir;;
42281
 
+         *) dllsearchpath="$dllsearchpath:$testbindir";;
42282
 
+         esac
42283
 
+         ;;
42284
 
+       esac
42285
 
+      done
42286
 
+      # Substitute the hardcoded libdirs into the rpath.
42287
 
+      if test -n "$hardcode_libdir_separator" &&
42288
 
+        test -n "$hardcode_libdirs"; then
42289
 
+       libdir="$hardcode_libdirs"
42290
 
+       eval rpath=\" $hardcode_libdir_flag_spec\"
42291
 
+      fi
42292
 
+      compile_rpath="$rpath"
42293
 
+
42294
 
+      rpath=
42295
 
+      hardcode_libdirs=
42296
 
+      for libdir in $finalize_rpath; do
42297
 
+       if test -n "$hardcode_libdir_flag_spec"; then
42298
 
+         if test -n "$hardcode_libdir_separator"; then
42299
 
+           if test -z "$hardcode_libdirs"; then
42300
 
+             hardcode_libdirs="$libdir"
42301
 
+           else
42302
 
+             # Just accumulate the unique libdirs.
42303
 
+             case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
42304
 
+             *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
42305
 
+               ;;
42306
 
+             *)
42307
 
+               hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
42308
 
+               ;;
42309
 
+             esac
42310
 
+           fi
42311
 
+         else
42312
 
+           eval flag=\"$hardcode_libdir_flag_spec\"
42313
 
+           rpath="$rpath $flag"
42314
 
+         fi
42315
 
+       elif test -n "$runpath_var"; then
42316
 
+         case "$finalize_perm_rpath " in
42317
 
+         *" $libdir "*) ;;
42318
 
+         *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;;
42319
 
+         esac
42320
 
+       fi
42321
 
+      done
42322
 
+      # Substitute the hardcoded libdirs into the rpath.
42323
 
+      if test -n "$hardcode_libdir_separator" &&
42324
 
+        test -n "$hardcode_libdirs"; then
42325
 
+       libdir="$hardcode_libdirs"
42326
 
+       eval rpath=\" $hardcode_libdir_flag_spec\"
42327
 
+      fi
42328
 
+      finalize_rpath="$rpath"
42329
 
+
42330
 
+      if test -n "$libobjs" && test "$build_old_libs" = yes; then
42331
 
+       # Transform all the library objects into standard objects.
42332
 
+       compile_command=`$ECHO "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
42333
 
+       finalize_command=`$ECHO "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
42334
 
+      fi
42335
 
+
42336
 
+      func_generate_dlsyms "$outputname" "@PROGRAM@" "no"
42337
 
+
42338
 
+      # template prelinking step
42339
 
+      if test -n "$prelink_cmds"; then
42340
 
+       func_execute_cmds "$prelink_cmds" 'exit $?'
42341
 
+      fi
42342
 
+
42343
 
+      wrappers_required=yes
42344
 
+      case $host in
42345
 
+      *cygwin* | *mingw* )
42346
 
+        if test "$build_libtool_libs" != yes; then
42347
 
+          wrappers_required=no
42348
 
+        fi
42349
 
+        ;;
42350
 
+      *cegcc)
42351
 
+        # Disable wrappers for cegcc, we are cross compiling anyway.
42352
 
+        wrappers_required=no
42353
 
+        ;;
42354
 
+      *)
42355
 
+        if test "$need_relink" = no || test "$build_libtool_libs" != yes; then
42356
 
+          wrappers_required=no
42357
 
+        fi
42358
 
+        ;;
42359
 
+      esac
42360
 
+      if test "$wrappers_required" = no; then
42361
 
+       # Replace the output file specification.
42362
 
+       compile_command=`$ECHO "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'`
42363
 
+       link_command="$compile_command$compile_rpath"
42364
 
+
42365
 
+       # We have no uninstalled library dependencies, so finalize right now.
42366
 
+       exit_status=0
42367
 
+       func_show_eval "$link_command" 'exit_status=$?'
42368
 
+
42369
 
+       # Delete the generated files.
42370
 
+       if test -f "$output_objdir/${outputname}S.${objext}"; then
42371
 
+         func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"'
42372
 
+       fi
42373
 
+
42374
 
+       exit $exit_status
42375
 
+      fi
42376
 
+
42377
 
+      if test -n "$compile_shlibpath$finalize_shlibpath"; then
42378
 
+       compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command"
42379
 
+      fi
42380
 
+      if test -n "$finalize_shlibpath"; then
42381
 
+       finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command"
42382
 
+      fi
42383
 
+
42384
 
+      compile_var=
42385
 
+      finalize_var=
42386
 
+      if test -n "$runpath_var"; then
42387
 
+       if test -n "$perm_rpath"; then
42388
 
+         # We should set the runpath_var.
42389
 
+         rpath=
42390
 
+         for dir in $perm_rpath; do
42391
 
+           rpath="$rpath$dir:"
42392
 
+         done
42393
 
+         compile_var="$runpath_var=\"$rpath\$$runpath_var\" "
42394
 
+       fi
42395
 
+       if test -n "$finalize_perm_rpath"; then
42396
 
+         # We should set the runpath_var.
42397
 
+         rpath=
42398
 
+         for dir in $finalize_perm_rpath; do
42399
 
+           rpath="$rpath$dir:"
42400
 
+         done
42401
 
+         finalize_var="$runpath_var=\"$rpath\$$runpath_var\" "
42402
 
+       fi
42403
 
+      fi
42404
 
+
42405
 
+      if test "$no_install" = yes; then
42406
 
+       # We don't need to create a wrapper script.
42407
 
+       link_command="$compile_var$compile_command$compile_rpath"
42408
 
+       # Replace the output file specification.
42409
 
+       link_command=`$ECHO "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'`
42410
 
+       # Delete the old output file.
42411
 
+       $opt_dry_run || $RM $output
42412
 
+       # Link the executable and exit
42413
 
+       func_show_eval "$link_command" 'exit $?'
42414
 
+       exit $EXIT_SUCCESS
42415
 
+      fi
42416
 
+
42417
 
+      if test "$hardcode_action" = relink; then
42418
 
+       # Fast installation is not supported
42419
 
+       link_command="$compile_var$compile_command$compile_rpath"
42420
 
+       relink_command="$finalize_var$finalize_command$finalize_rpath"
42421
 
+
42422
 
+       func_warning "this platform does not like uninstalled shared libraries"
42423
 
+       func_warning "\`$output' will be relinked during installation"
42424
 
+      else
42425
 
+       if test "$fast_install" != no; then
42426
 
+         link_command="$finalize_var$compile_command$finalize_rpath"
42427
 
+         if test "$fast_install" = yes; then
42428
 
+           relink_command=`$ECHO "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'`
42429
 
+         else
42430
 
+           # fast_install is set to needless
42431
 
+           relink_command=
42432
 
+         fi
42433
 
+       else
42434
 
+         link_command="$compile_var$compile_command$compile_rpath"
42435
 
+         relink_command="$finalize_var$finalize_command$finalize_rpath"
42436
 
+       fi
42437
 
+      fi
42438
 
+
42439
 
+      # Replace the output file specification.
42440
 
+      link_command=`$ECHO "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'`
42441
 
+
42442
 
+      # Delete the old output files.
42443
 
+      $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname
42444
 
+
42445
 
+      func_show_eval "$link_command" 'exit $?'
42446
 
+
42447
 
+      # Now create the wrapper script.
42448
 
+      func_verbose "creating $output"
42449
 
+
42450
 
+      # Quote the relink command for shipping.
42451
 
+      if test -n "$relink_command"; then
42452
 
+       # Preserve any variables that may affect compiler behavior
42453
 
+       for var in $variables_saved_for_relink; do
42454
 
+         if eval test -z \"\${$var+set}\"; then
42455
 
+           relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command"
42456
 
+         elif eval var_value=\$$var; test -z "$var_value"; then
42457
 
+           relink_command="$var=; export $var; $relink_command"
42458
 
+         else
42459
 
+           func_quote_for_eval "$var_value"
42460
 
+           relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
42461
 
+         fi
42462
 
+       done
42463
 
+       relink_command="(cd `pwd`; $relink_command)"
42464
 
+       relink_command=`$ECHO "X$relink_command" | $Xsed -e "$sed_quote_subst"`
42465
 
+      fi
42466
 
+
42467
 
+      # Quote $ECHO for shipping.
42468
 
+      if test "X$ECHO" = "X$SHELL $progpath --fallback-echo"; then
42469
 
+       case $progpath in
42470
 
+       [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $progpath --fallback-echo";;
42471
 
+       *) qecho="$SHELL `pwd`/$progpath --fallback-echo";;
42472
 
+       esac
42473
 
+       qecho=`$ECHO "X$qecho" | $Xsed -e "$sed_quote_subst"`
42474
 
+      else
42475
 
+       qecho=`$ECHO "X$ECHO" | $Xsed -e "$sed_quote_subst"`
42476
 
+      fi
42477
 
+
42478
 
+      # Only actually do things if not in dry run mode.
42479
 
+      $opt_dry_run || {
42480
 
+       # win32 will think the script is a binary if it has
42481
 
+       # a .exe suffix, so we strip it off here.
42482
 
+       case $output in
42483
 
+         *.exe) func_stripname '' '.exe' "$output"
42484
 
+                output=$func_stripname_result ;;
42485
 
+       esac
42486
 
+       # test for cygwin because mv fails w/o .exe extensions
42487
 
+       case $host in
42488
 
+         *cygwin*)
42489
 
+           exeext=.exe
42490
 
+           func_stripname '' '.exe' "$outputname"
42491
 
+           outputname=$func_stripname_result ;;
42492
 
+         *) exeext= ;;
42493
 
+       esac
42494
 
+       case $host in
42495
 
+         *cygwin* | *mingw* )
42496
 
+           func_dirname_and_basename "$output" "" "."
42497
 
+           output_name=$func_basename_result
42498
 
+           output_path=$func_dirname_result
42499
 
+           cwrappersource="$output_path/$objdir/lt-$output_name.c"
42500
 
+           cwrapper="$output_path/$output_name.exe"
42501
 
+           $RM $cwrappersource $cwrapper
42502
 
+           trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15
42503
 
+
42504
 
+           func_emit_cwrapperexe_src > $cwrappersource
42505
 
+
42506
 
+           # The wrapper executable is built using the $host compiler,
42507
 
+           # because it contains $host paths and files. If cross-
42508
 
+           # compiling, it, like the target executable, must be
42509
 
+           # executed on the $host or under an emulation environment.
42510
 
+           $opt_dry_run || {
42511
 
+             $LTCC $LTCFLAGS -o $cwrapper $cwrappersource
42512
 
+             $STRIP $cwrapper
42513
 
+           }
42514
 
+
42515
 
+           # Now, create the wrapper script for func_source use:
42516
 
+           func_ltwrapper_scriptname $cwrapper
42517
 
+           $RM $func_ltwrapper_scriptname_result
42518
 
+           trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15
42519
 
+           $opt_dry_run || {
42520
 
+             # note: this script will not be executed, so do not chmod.
42521
 
+             if test "x$build" = "x$host" ; then
42522
 
+               $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result
42523
 
+             else
42524
 
+               func_emit_wrapper no > $func_ltwrapper_scriptname_result
42525
 
+             fi
42526
 
+           }
42527
 
+         ;;
42528
 
+         * )
42529
 
+           $RM $output
42530
 
+           trap "$RM $output; exit $EXIT_FAILURE" 1 2 15
42531
 
+
42532
 
+           func_emit_wrapper no > $output
42533
 
+           chmod +x $output
42534
 
+         ;;
42535
 
+       esac
42536
 
+      }
42537
 
+      exit $EXIT_SUCCESS
42538
 
+      ;;
42539
 
+    esac
42540
 
+
42541
 
+    # See if we need to build an old-fashioned archive.
42542
 
+    for oldlib in $oldlibs; do
42543
 
+
42544
 
+      if test "$build_libtool_libs" = convenience; then
42545
 
+       oldobjs="$libobjs_save $symfileobj"
42546
 
+       addlibs="$convenience"
42547
 
+       build_libtool_libs=no
42548
 
+      else
42549
 
+       if test "$build_libtool_libs" = module; then
42550
 
+         oldobjs="$libobjs_save"
42551
 
+         build_libtool_libs=no
42552
 
+       else
42553
 
+         oldobjs="$old_deplibs $non_pic_objects"
42554
 
+         if test "$preload" = yes && test -f "$symfileobj"; then
42555
 
+           oldobjs="$oldobjs $symfileobj"
42556
 
+         fi
42557
 
+       fi
42558
 
+       addlibs="$old_convenience"
42559
 
+      fi
42560
 
+
42561
 
+      if test -n "$addlibs"; then
42562
 
+       gentop="$output_objdir/${outputname}x"
42563
 
+       generated="$generated $gentop"
42564
 
+
42565
 
+       func_extract_archives $gentop $addlibs
42566
 
+       oldobjs="$oldobjs $func_extract_archives_result"
42567
 
+      fi
42568
 
+
42569
 
+      # Do each command in the archive commands.
42570
 
+      if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then
42571
 
+       cmds=$old_archive_from_new_cmds
42572
 
+      else
42573
 
+
42574
 
+       # Add any objects from preloaded convenience libraries
42575
 
+       if test -n "$dlprefiles"; then
42576
 
+         gentop="$output_objdir/${outputname}x"
42577
 
+         generated="$generated $gentop"
42578
 
+
42579
 
+         func_extract_archives $gentop $dlprefiles
42580
 
+         oldobjs="$oldobjs $func_extract_archives_result"
42581
 
+       fi
42582
 
+
42583
 
+       # POSIX demands no paths to be encoded in archives.  We have
42584
 
+       # to avoid creating archives with duplicate basenames if we
42585
 
+       # might have to extract them afterwards, e.g., when creating a
42586
 
+       # static archive out of a convenience library, or when linking
42587
 
+       # the entirety of a libtool archive into another (currently
42588
 
+       # not supported by libtool).
42589
 
+       if (for obj in $oldobjs
42590
 
+           do
42591
 
+             func_basename "$obj"
42592
 
+             $ECHO "$func_basename_result"
42593
 
+           done | sort | sort -uc >/dev/null 2>&1); then
42594
 
+         :
42595
 
+       else
42596
 
+         $ECHO "copying selected object files to avoid basename conflicts..."
42597
 
+         gentop="$output_objdir/${outputname}x"
42598
 
+         generated="$generated $gentop"
42599
 
+         func_mkdir_p "$gentop"
42600
 
+         save_oldobjs=$oldobjs
42601
 
+         oldobjs=
42602
 
+         counter=1
42603
 
+         for obj in $save_oldobjs
42604
 
+         do
42605
 
+           func_basename "$obj"
42606
 
+           objbase="$func_basename_result"
42607
 
+           case " $oldobjs " in
42608
 
+           " ") oldobjs=$obj ;;
42609
 
+           *[\ /]"$objbase "*)
42610
 
+             while :; do
42611
 
+               # Make sure we don't pick an alternate name that also
42612
 
+               # overlaps.
42613
 
+               newobj=lt$counter-$objbase
42614
 
+               func_arith $counter + 1
42615
 
+               counter=$func_arith_result
42616
 
+               case " $oldobjs " in
42617
 
+               *[\ /]"$newobj "*) ;;
42618
 
+               *) if test ! -f "$gentop/$newobj"; then break; fi ;;
42619
 
+               esac
42620
 
+             done
42621
 
+             func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj"
42622
 
+             oldobjs="$oldobjs $gentop/$newobj"
42623
 
+             ;;
42624
 
+           *) oldobjs="$oldobjs $obj" ;;
42625
 
+           esac
42626
 
+         done
42627
 
+       fi
42628
 
+       eval cmds=\"$old_archive_cmds\"
42629
 
+
42630
 
+       func_len " $cmds"
42631
 
+       len=$func_len_result
42632
 
+       if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
42633
 
+         cmds=$old_archive_cmds
42634
 
+       else
42635
 
+         # the command line is too long to link in one step, link in parts
42636
 
+         func_verbose "using piecewise archive linking..."
42637
 
+         save_RANLIB=$RANLIB
42638
 
+         RANLIB=:
42639
 
+         objlist=
42640
 
+         concat_cmds=
42641
 
+         save_oldobjs=$oldobjs
42642
 
+         oldobjs=
42643
 
+         # Is there a better way of finding the last object in the list?
42644
 
+         for obj in $save_oldobjs
42645
 
+         do
42646
 
+           last_oldobj=$obj
42647
 
+         done
42648
 
+         eval test_cmds=\"$old_archive_cmds\"
42649
 
+         func_len " $test_cmds"
42650
 
+         len0=$func_len_result
42651
 
+         len=$len0
42652
 
+         for obj in $save_oldobjs
42653
 
+         do
42654
 
+           func_len " $obj"
42655
 
+           func_arith $len + $func_len_result
42656
 
+           len=$func_arith_result
42657
 
+           func_append objlist " $obj"
42658
 
+           if test "$len" -lt "$max_cmd_len"; then
42659
 
+             :
42660
 
+           else
42661
 
+             # the above command should be used before it gets too long
42662
 
+             oldobjs=$objlist
42663
 
+             if test "$obj" = "$last_oldobj" ; then
42664
 
+               RANLIB=$save_RANLIB
42665
 
+             fi
42666
 
+             test -z "$concat_cmds" || concat_cmds=$concat_cmds~
42667
 
+             eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\"
42668
 
+             objlist=
42669
 
+             len=$len0
42670
 
+           fi
42671
 
+         done
42672
 
+         RANLIB=$save_RANLIB
42673
 
+         oldobjs=$objlist
42674
 
+         if test "X$oldobjs" = "X" ; then
42675
 
+           eval cmds=\"\$concat_cmds\"
42676
 
+         else
42677
 
+           eval cmds=\"\$concat_cmds~\$old_archive_cmds\"
42678
 
+         fi
42679
 
+       fi
42680
 
+      fi
42681
 
+      func_execute_cmds "$cmds" 'exit $?'
42682
 
+    done
42683
 
+
42684
 
+    test -n "$generated" && \
42685
 
+      func_show_eval "${RM}r$generated"
42686
 
+
42687
 
+    # Now create the libtool archive.
42688
 
+    case $output in
42689
 
+    *.la)
42690
 
+      old_library=
42691
 
+      test "$build_old_libs" = yes && old_library="$libname.$libext"
42692
 
+      func_verbose "creating $output"
42693
 
+
42694
 
+      # Preserve any variables that may affect compiler behavior
42695
 
+      for var in $variables_saved_for_relink; do
42696
 
+       if eval test -z \"\${$var+set}\"; then
42697
 
+         relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command"
42698
 
+       elif eval var_value=\$$var; test -z "$var_value"; then
42699
 
+         relink_command="$var=; export $var; $relink_command"
42700
 
+       else
42701
 
+         func_quote_for_eval "$var_value"
42702
 
+         relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
42703
 
+       fi
42704
 
+      done
42705
 
+      # Quote the link command for shipping.
42706
 
+      relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)"
42707
 
+      relink_command=`$ECHO "X$relink_command" | $Xsed -e "$sed_quote_subst"`
42708
 
+      if test "$hardcode_automatic" = yes ; then
42709
 
+       relink_command=
42710
 
+      fi
42711
 
+
42712
 
+      # Only create the output if not a dry run.
42713
 
+      $opt_dry_run || {
42714
 
+       for installed in no yes; do
42715
 
+         if test "$installed" = yes; then
42716
 
+           if test -z "$install_libdir"; then
42717
 
+             break
42718
 
+           fi
42719
 
+           output="$output_objdir/$outputname"i
42720
 
+           # Replace all uninstalled libtool libraries with the installed ones
42721
 
+           newdependency_libs=
42722
 
+           for deplib in $dependency_libs; do
42723
 
+             case $deplib in
42724
 
+             *.la)
42725
 
+               func_basename "$deplib"
42726
 
+               name="$func_basename_result"
42727
 
+               eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
42728
 
+               test -z "$libdir" && \
42729
 
+                 func_fatal_error "\`$deplib' is not a valid libtool archive"
42730
 
+               newdependency_libs="$newdependency_libs $libdir/$name"
42731
 
+               ;;
42732
 
+             *) newdependency_libs="$newdependency_libs $deplib" ;;
42733
 
+             esac
42734
 
+           done
42735
 
+           dependency_libs="$newdependency_libs"
42736
 
+           newdlfiles=
42737
 
+
42738
 
+           for lib in $dlfiles; do
42739
 
+             case $lib in
42740
 
+             *.la)
42741
 
+               func_basename "$lib"
42742
 
+               name="$func_basename_result"
42743
 
+               eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
42744
 
+               test -z "$libdir" && \
42745
 
+                 func_fatal_error "\`$lib' is not a valid libtool archive"
42746
 
+               newdlfiles="$newdlfiles $libdir/$name"
42747
 
+               ;;
42748
 
+             *) newdlfiles="$newdlfiles $lib" ;;
42749
 
+             esac
42750
 
+           done
42751
 
+           dlfiles="$newdlfiles"
42752
 
+           newdlprefiles=
42753
 
+           for lib in $dlprefiles; do
42754
 
+             case $lib in
42755
 
+             *.la)
42756
 
+               # Only pass preopened files to the pseudo-archive (for
42757
 
+               # eventual linking with the app. that links it) if we
42758
 
+               # didn't already link the preopened objects directly into
42759
 
+               # the library:
42760
 
+               func_basename "$lib"
42761
 
+               name="$func_basename_result"
42762
 
+               eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
42763
 
+               test -z "$libdir" && \
42764
 
+                 func_fatal_error "\`$lib' is not a valid libtool archive"
42765
 
+               newdlprefiles="$newdlprefiles $libdir/$name"
42766
 
+               ;;
42767
 
+             esac
42768
 
+           done
42769
 
+           dlprefiles="$newdlprefiles"
42770
 
+         else
42771
 
+           newdlfiles=
42772
 
+           for lib in $dlfiles; do
42773
 
+             case $lib in
42774
 
+               [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
42775
 
+               *) abs=`pwd`"/$lib" ;;
42776
 
+             esac
42777
 
+             newdlfiles="$newdlfiles $abs"
42778
 
+           done
42779
 
+           dlfiles="$newdlfiles"
42780
 
+           newdlprefiles=
42781
 
+           for lib in $dlprefiles; do
42782
 
+             case $lib in
42783
 
+               [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
42784
 
+               *) abs=`pwd`"/$lib" ;;
42785
 
+             esac
42786
 
+             newdlprefiles="$newdlprefiles $abs"
42787
 
+           done
42788
 
+           dlprefiles="$newdlprefiles"
42789
 
+         fi
42790
 
+         $RM $output
42791
 
+         # place dlname in correct position for cygwin
42792
 
+         tdlname=$dlname
42793
 
+         case $host,$output,$installed,$module,$dlname in
42794
 
+           *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;;
42795
 
+         esac
42796
 
+         $ECHO > $output "\
42797
 
+# $outputname - a libtool library file
42798
 
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
42799
 
+#
42800
 
+# Please DO NOT delete this file!
42801
 
+# It is necessary for linking the library.
42802
 
+
42803
 
+# The name that we can dlopen(3).
42804
 
+dlname='$tdlname'
42805
 
+
42806
 
+# Names of this library.
42807
 
+library_names='$library_names'
42808
 
+
42809
 
+# The name of the static archive.
42810
 
+old_library='$old_library'
42811
 
+
42812
 
+# Linker flags that can not go in dependency_libs.
42813
 
+inherited_linker_flags='$new_inherited_linker_flags'
42814
 
+
42815
 
+# Libraries that this one depends upon.
42816
 
+dependency_libs='$dependency_libs'
42817
 
+
42818
 
+# Names of additional weak libraries provided by this library
42819
 
+weak_library_names='$weak_libs'
42820
 
+
42821
 
+# Version information for $libname.
42822
 
+current=$current
42823
 
+age=$age
42824
 
+revision=$revision
42825
 
+
42826
 
+# Is this an already installed library?
42827
 
+installed=$installed
42828
 
+
42829
 
+# Should we warn about portability when linking against -modules?
42830
 
+shouldnotlink=$module
42831
 
+
42832
 
+# Files to dlopen/dlpreopen
42833
 
+dlopen='$dlfiles'
42834
 
+dlpreopen='$dlprefiles'
42835
 
+
42836
 
+# Directory that this library needs to be installed in:
42837
 
+libdir='$install_libdir'"
42838
 
+         if test "$installed" = no && test "$need_relink" = yes; then
42839
 
+           $ECHO >> $output "\
42840
 
+relink_command=\"$relink_command\""
42841
 
+         fi
42842
 
+       done
42843
 
+      }
42844
 
+
42845
 
+      # Do a symbolic link so that the libtool archive can be found in
42846
 
+      # LD_LIBRARY_PATH before the program is installed.
42847
 
+      func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?'
42848
 
+      ;;
42849
 
+    esac
42850
 
+    exit $EXIT_SUCCESS
42851
 
+}
42852
 
+
42853
 
+{ test "$mode" = link || test "$mode" = relink; } &&
42854
 
+    func_mode_link ${1+"$@"}
42855
 
+
42856
 
+
42857
 
+# func_mode_uninstall arg...
42858
 
+func_mode_uninstall ()
42859
 
+{
42860
 
+    $opt_debug
42861
 
+    RM="$nonopt"
42862
 
+    files=
42863
 
+    rmforce=
42864
 
+    exit_status=0
42865
 
+
42866
 
+    # This variable tells wrapper scripts just to set variables rather
42867
 
+    # than running their programs.
42868
 
+    libtool_install_magic="$magic"
42869
 
+
42870
 
+    for arg
42871
 
+    do
42872
 
+      case $arg in
42873
 
+      -f) RM="$RM $arg"; rmforce=yes ;;
42874
 
+      -*) RM="$RM $arg" ;;
42875
 
+      *) files="$files $arg" ;;
42876
 
+      esac
42877
 
+    done
42878
 
+
42879
 
+    test -z "$RM" && \
42880
 
+      func_fatal_help "you must specify an RM program"
42881
 
+
42882
 
+    rmdirs=
42883
 
+
42884
 
+    origobjdir="$objdir"
42885
 
+    for file in $files; do
42886
 
+      func_dirname "$file" "" "."
42887
 
+      dir="$func_dirname_result"
42888
 
+      if test "X$dir" = X.; then
42889
 
+       objdir="$origobjdir"
42890
 
+      else
42891
 
+       objdir="$dir/$origobjdir"
42892
 
+      fi
42893
 
+      func_basename "$file"
42894
 
+      name="$func_basename_result"
42895
 
+      test "$mode" = uninstall && objdir="$dir"
42896
 
+
42897
 
+      # Remember objdir for removal later, being careful to avoid duplicates
42898
 
+      if test "$mode" = clean; then
42899
 
+       case " $rmdirs " in
42900
 
+         *" $objdir "*) ;;
42901
 
+         *) rmdirs="$rmdirs $objdir" ;;
42902
 
+       esac
42903
 
+      fi
42904
 
+
42905
 
+      # Don't error if the file doesn't exist and rm -f was used.
42906
 
+      if { test -L "$file"; } >/dev/null 2>&1 ||
42907
 
+        { test -h "$file"; } >/dev/null 2>&1 ||
42908
 
+        test -f "$file"; then
42909
 
+       :
42910
 
+      elif test -d "$file"; then
42911
 
+       exit_status=1
42912
 
+       continue
42913
 
+      elif test "$rmforce" = yes; then
42914
 
+       continue
42915
 
+      fi
42916
 
+
42917
 
+      rmfiles="$file"
42918
 
+
42919
 
+      case $name in
42920
 
+      *.la)
42921
 
+       # Possibly a libtool archive, so verify it.
42922
 
+       if func_lalib_p "$file"; then
42923
 
+         func_source $dir/$name
42924
 
+
42925
 
+         # Delete the libtool libraries and symlinks.
42926
 
+         for n in $library_names; do
42927
 
+           rmfiles="$rmfiles $objdir/$n"
42928
 
+         done
42929
 
+         test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library"
42930
 
+
42931
 
+         case "$mode" in
42932
 
+         clean)
42933
 
+           case "  $library_names " in
42934
 
+           # "  " in the beginning catches empty $dlname
42935
 
+           *" $dlname "*) ;;
42936
 
+           *) rmfiles="$rmfiles $objdir/$dlname" ;;
42937
 
+           esac
42938
 
+           test -n "$libdir" && rmfiles="$rmfiles $objdir/$name $objdir/${name}i"
42939
 
+           ;;
42940
 
+         uninstall)
42941
 
+           if test -n "$library_names"; then
42942
 
+             # Do each command in the postuninstall commands.
42943
 
+             func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1'
42944
 
+           fi
42945
 
+
42946
 
+           if test -n "$old_library"; then
42947
 
+             # Do each command in the old_postuninstall commands.
42948
 
+             func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1'
42949
 
+           fi
42950
 
+           # FIXME: should reinstall the best remaining shared library.
42951
 
+           ;;
42952
 
+         esac
42953
 
+       fi
42954
 
+       ;;
42955
 
+
42956
 
+      *.lo)
42957
 
+       # Possibly a libtool object, so verify it.
42958
 
+       if func_lalib_p "$file"; then
42959
 
+
42960
 
+         # Read the .lo file
42961
 
+         func_source $dir/$name
42962
 
+
42963
 
+         # Add PIC object to the list of files to remove.
42964
 
+         if test -n "$pic_object" &&
42965
 
+            test "$pic_object" != none; then
42966
 
+           rmfiles="$rmfiles $dir/$pic_object"
42967
 
+         fi
42968
 
+
42969
 
+         # Add non-PIC object to the list of files to remove.
42970
 
+         if test -n "$non_pic_object" &&
42971
 
+            test "$non_pic_object" != none; then
42972
 
+           rmfiles="$rmfiles $dir/$non_pic_object"
42973
 
+         fi
42974
 
+       fi
42975
 
+       ;;
42976
 
+
42977
 
+      *)
42978
 
+       if test "$mode" = clean ; then
42979
 
+         noexename=$name
42980
 
+         case $file in
42981
 
+         *.exe)
42982
 
+           func_stripname '' '.exe' "$file"
42983
 
+           file=$func_stripname_result
42984
 
+           func_stripname '' '.exe' "$name"
42985
 
+           noexename=$func_stripname_result
42986
 
+           # $file with .exe has already been added to rmfiles,
42987
 
+           # add $file without .exe
42988
 
+           rmfiles="$rmfiles $file"
42989
 
+           ;;
42990
 
+         esac
42991
 
+         # Do a test to see if this is a libtool program.
42992
 
+         if func_ltwrapper_p "$file"; then
42993
 
+           if func_ltwrapper_executable_p "$file"; then
42994
 
+             func_ltwrapper_scriptname "$file"
42995
 
+             relink_command=
42996
 
+             func_source $func_ltwrapper_scriptname_result
42997
 
+             rmfiles="$rmfiles $func_ltwrapper_scriptname_result"
42998
 
+           else
42999
 
+             relink_command=
43000
 
+             func_source $dir/$noexename
43001
 
+           fi
43002
 
+
43003
 
+           # note $name still contains .exe if it was in $file originally
43004
 
+           # as does the version of $file that was added into $rmfiles
43005
 
+           rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}"
43006
 
+           if test "$fast_install" = yes && test -n "$relink_command"; then
43007
 
+             rmfiles="$rmfiles $objdir/lt-$name"
43008
 
+           fi
43009
 
+           if test "X$noexename" != "X$name" ; then
43010
 
+             rmfiles="$rmfiles $objdir/lt-${noexename}.c"
43011
 
+           fi
43012
 
+         fi
43013
 
+       fi
43014
 
+       ;;
43015
 
+      esac
43016
 
+      func_show_eval "$RM $rmfiles" 'exit_status=1'
43017
 
+    done
43018
 
+    objdir="$origobjdir"
43019
 
+
43020
 
+    # Try to remove the ${objdir}s in the directories where we deleted files
43021
 
+    for dir in $rmdirs; do
43022
 
+      if test -d "$dir"; then
43023
 
+       func_show_eval "rmdir $dir >/dev/null 2>&1"
43024
 
+      fi
43025
 
+    done
43026
 
+
43027
 
+    exit $exit_status
43028
 
+}
43029
 
+
43030
 
+{ test "$mode" = uninstall || test "$mode" = clean; } &&
43031
 
+    func_mode_uninstall ${1+"$@"}
43032
 
+
43033
 
+test -z "$mode" && {
43034
 
+  help="$generic_help"
43035
 
+  func_fatal_help "you must specify a MODE"
43036
 
+}
43037
 
+
43038
 
+test -z "$exec_cmd" && \
43039
 
+  func_fatal_help "invalid operation mode \`$mode'"
43040
 
+
43041
 
+if test -n "$exec_cmd"; then
43042
 
+  eval exec "$exec_cmd"
43043
 
+  exit $EXIT_FAILURE
43044
 
+fi
43045
 
+
43046
 
+exit $exit_status
43047
 
+
43048
 
+
43049
 
+# The TAGs below are defined such that we never get into a situation
43050
 
+# in which we disable both kinds of libraries.  Given conflicting
43051
 
+# choices, we go for a static library, that is the most portable,
43052
 
+# since we can't tell whether shared libraries were disabled because
43053
 
+# the user asked for that or because the platform doesn't support
43054
 
+# them.  This is particularly important on AIX, because we don't
43055
 
+# support having both static and shared libraries enabled at the same
43056
 
+# time on that platform, so we default to a shared-only configuration.
43057
 
+# If a disable-shared tag is given, we'll fallback to a static-only
43058
 
+# configuration.  But we'll never go from static-only to shared-only.
43059
 
+
43060
 
+# ### BEGIN LIBTOOL TAG CONFIG: disable-shared
43061
 
+build_libtool_libs=no
43062
 
+build_old_libs=yes
43063
 
+# ### END LIBTOOL TAG CONFIG: disable-shared
43064
 
+
43065
 
+# ### BEGIN LIBTOOL TAG CONFIG: disable-static
43066
 
+build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac`
43067
 
+# ### END LIBTOOL TAG CONFIG: disable-static
43068
 
+
43069
 
+# Local Variables:
43070
 
+# mode:shell-script
43071
 
+# sh-indentation:2
43072
 
+# End:
43073
 
+# vi:sw=2
43074
 
+
43075
 
diff -urN dovecot-1.2.4/dovecot-libsieve/Makefile.am dovecot-1.2.4.debian/dovecot-libsieve/Makefile.am
43076
 
--- dovecot-1.2.4/dovecot-libsieve/Makefile.am  1970-01-01 01:00:00.000000000 +0100
43077
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/Makefile.am   2009-08-21 00:52:15.000000000 +0200
43078
 
@@ -0,0 +1,128 @@
43079
 
+SUBDIRS = src
43080
 
+
43081
 
+unfinished = doc/man/sieve-filter.1
43082
 
+
43083
 
+if BUILD_UNFINISHED
43084
 
+unfinished_mans = $(unfinished)
43085
 
+else
43086
 
+unfinished_dist = $(unfinished)
43087
 
+endif
43088
 
+
43089
 
+EXTRA_DIST = \
43090
 
+       tests \
43091
 
+       examples/* \
43092
 
+       doc/rfc \
43093
 
+       doc/devel \
43094
 
+       COPYING.LGPL \
43095
 
+       ChangeLog \
43096
 
+       $(unfinished_dist)
43097
 
+
43098
 
+dist_man_MANS = \
43099
 
+       doc/man/sievec.1 \
43100
 
+       doc/man/sieved.1 \
43101
 
+       doc/man/sieve-test.1 \
43102
 
+       $(unfinished_mans)
43103
 
+
43104
 
+if MAINTAINER_MODE
43105
 
+ChangeLog: .hg/dirstate
43106
 
+       hg log --style=changelog > ChangeLog
43107
 
+endif
43108
 
+
43109
 
+# Testsuite tests
43110
 
+
43111
 
+TESTSUITE_BIN = $(top_srcdir)/src/testsuite/testsuite
43112
 
+
43113
 
+if TESTSUITE_VALGRIND
43114
 
+TEST_BIN = valgrind -q --error-exitcode=1 --show-reachable=yes --leak-check=full $(TESTSUITE_BIN) 
43115
 
+else
43116
 
+TEST_BIN = $(TESTSUITE_BIN)
43117
 
+endif
43118
 
+
43119
 
+test_cases = \
43120
 
+       tests/testsuite.svtest\
43121
 
+       tests/control-structures.svtest \
43122
 
+       tests/compile/compile.svtest \
43123
 
+       tests/compile/errors.svtest \
43124
 
+       tests/execute/errors.svtest \
43125
 
+       tests/execute/actions.svtest \
43126
 
+       tests/execute/smtp.svtest \
43127
 
+       tests/execute/mailstore.svtest \
43128
 
+       tests/execute/examples.svtest \
43129
 
+       tests/exists.svtest \
43130
 
+       tests/header.svtest \
43131
 
+       tests/address.svtest \
43132
 
+       tests/lexer.svtest \
43133
 
+       tests/comparators/core.svtest \
43134
 
+       tests/match-types/is.svtest \
43135
 
+       tests/match-types/contains.svtest \
43136
 
+       tests/match-types/matches.svtest \
43137
 
+       tests/extensions/encoded-character.svtest \
43138
 
+       tests/extensions/envelope.svtest \
43139
 
+       tests/extensions/variables/basic.svtest \
43140
 
+       tests/extensions/variables/match.svtest \
43141
 
+       tests/extensions/variables/modifiers.svtest \
43142
 
+       tests/extensions/variables/quoting.svtest \
43143
 
+       tests/extensions/variables/string.svtest \
43144
 
+       tests/extensions/variables/errors.svtest \
43145
 
+       tests/extensions/variables/regex.svtest \
43146
 
+       tests/extensions/include/errors.svtest \
43147
 
+       tests/extensions/include/variables.svtest \
43148
 
+       tests/extensions/include/once.svtest \
43149
 
+       tests/extensions/include/twice.svtest \
43150
 
+       tests/extensions/include/rfc.svtest \
43151
 
+       tests/extensions/include/execute.svtest \
43152
 
+       tests/extensions/imap4flags/basic.svtest \
43153
 
+       tests/extensions/imap4flags/hasflag.svtest \
43154
 
+       tests/extensions/imap4flags/errors.svtest \
43155
 
+       tests/extensions/imap4flags/execute.svtest \
43156
 
+       tests/extensions/imap4flags/flagstore.svtest \
43157
 
+       tests/extensions/body/basic.svtest \
43158
 
+       tests/extensions/body/match-values.svtest \
43159
 
+       tests/extensions/regex/basic.svtest \
43160
 
+       tests/extensions/regex/match-values.svtest \
43161
 
+       tests/extensions/regex/errors.svtest \
43162
 
+       tests/extensions/reject/execute.svtest \
43163
 
+       tests/extensions/reject/smtp.svtest \
43164
 
+       tests/extensions/relational/basic.svtest \
43165
 
+       tests/extensions/relational/rfc.svtest \
43166
 
+       tests/extensions/relational/errors.svtest \
43167
 
+       tests/extensions/subaddress/basic.svtest \
43168
 
+       tests/extensions/subaddress/rfc.svtest \
43169
 
+       tests/extensions/vacation/errors.svtest \
43170
 
+       tests/extensions/vacation/execute.svtest \
43171
 
+       tests/extensions/vacation/message.svtest \
43172
 
+       tests/extensions/vacation/smtp.svtest \
43173
 
+       tests/extensions/enotify/basic.svtest \
43174
 
+       tests/extensions/enotify/encodeurl.svtest \
43175
 
+       tests/extensions/enotify/valid_notify_method.svtest \
43176
 
+       tests/extensions/enotify/notify_method_capability.svtest \
43177
 
+       tests/extensions/enotify/errors.svtest \
43178
 
+       tests/extensions/enotify/execute.svtest \
43179
 
+       tests/extensions/enotify/mailto.svtest \
43180
 
+       tests/extensions/environment/basic.svtest \
43181
 
+       tests/extensions/environment/rfc.svtest \
43182
 
+       tests/extensions/mailbox/execute.svtest \
43183
 
+       tests/extensions/date/basic.svtest \
43184
 
+       tests/extensions/date/date-parts.svtest \
43185
 
+       tests/extensions/date/zones.svtest \
43186
 
+       tests/multiscript/basic.svtest \
43187
 
+       tests/deprecated/notify/basic.svtest \
43188
 
+       tests/deprecated/notify/mailto.svtest \
43189
 
+       tests/deprecated/notify/errors.svtest \
43190
 
+       tests/deprecated/notify/execute.svtest
43191
 
+
43192
 
+if HAVE_DOVECOT_LIBS
43193
 
+
43194
 
+$(test_cases):
43195
 
+       @$(TEST_BIN) $@
43196
 
+
43197
 
+.PHONY: $(test_cases)
43198
 
+
43199
 
+test: $(test_cases)
43200
 
+
43201
 
+else
43202
 
+
43203
 
+test:
43204
 
+       @echo "Cannot compile or execute the testsuite without the Dovecot sources."
43205
 
+
43206
 
+endif  
43207
 
diff -urN dovecot-1.2.4/dovecot-libsieve/missing dovecot-1.2.4.debian/dovecot-libsieve/missing
43208
 
--- dovecot-1.2.4/dovecot-libsieve/missing      1970-01-01 01:00:00.000000000 +0100
43209
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/missing       2008-07-18 12:31:10.000000000 +0200
43210
 
@@ -0,0 +1,367 @@
43211
 
+#! /bin/sh
43212
 
+# Common stub for a few missing GNU programs while installing.
43213
 
+
43214
 
+scriptversion=2006-05-10.23
43215
 
+
43216
 
+# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006
43217
 
+#   Free Software Foundation, Inc.
43218
 
+# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
43219
 
+
43220
 
+# This program is free software; you can redistribute it and/or modify
43221
 
+# it under the terms of the GNU General Public License as published by
43222
 
+# the Free Software Foundation; either version 2, or (at your option)
43223
 
+# any later version.
43224
 
+
43225
 
+# This program is distributed in the hope that it will be useful,
43226
 
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
43227
 
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
43228
 
+# GNU General Public License for more details.
43229
 
+
43230
 
+# You should have received a copy of the GNU General Public License
43231
 
+# along with this program; if not, write to the Free Software
43232
 
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
43233
 
+# 02110-1301, USA.
43234
 
+
43235
 
+# As a special exception to the GNU General Public License, if you
43236
 
+# distribute this file as part of a program that contains a
43237
 
+# configuration script generated by Autoconf, you may include it under
43238
 
+# the same distribution terms that you use for the rest of that program.
43239
 
+
43240
 
+if test $# -eq 0; then
43241
 
+  echo 1>&2 "Try \`$0 --help' for more information"
43242
 
+  exit 1
43243
 
+fi
43244
 
+
43245
 
+run=:
43246
 
+sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p'
43247
 
+sed_minuso='s/.* -o \([^ ]*\).*/\1/p'
43248
 
+
43249
 
+# In the cases where this matters, `missing' is being run in the
43250
 
+# srcdir already.
43251
 
+if test -f configure.ac; then
43252
 
+  configure_ac=configure.ac
43253
 
+else
43254
 
+  configure_ac=configure.in
43255
 
+fi
43256
 
+
43257
 
+msg="missing on your system"
43258
 
+
43259
 
+case $1 in
43260
 
+--run)
43261
 
+  # Try to run requested program, and just exit if it succeeds.
43262
 
+  run=
43263
 
+  shift
43264
 
+  "$@" && exit 0
43265
 
+  # Exit code 63 means version mismatch.  This often happens
43266
 
+  # when the user try to use an ancient version of a tool on
43267
 
+  # a file that requires a minimum version.  In this case we
43268
 
+  # we should proceed has if the program had been absent, or
43269
 
+  # if --run hadn't been passed.
43270
 
+  if test $? = 63; then
43271
 
+    run=:
43272
 
+    msg="probably too old"
43273
 
+  fi
43274
 
+  ;;
43275
 
+
43276
 
+  -h|--h|--he|--hel|--help)
43277
 
+    echo "\
43278
 
+$0 [OPTION]... PROGRAM [ARGUMENT]...
43279
 
+
43280
 
+Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
43281
 
+error status if there is no known handling for PROGRAM.
43282
 
+
43283
 
+Options:
43284
 
+  -h, --help      display this help and exit
43285
 
+  -v, --version   output version information and exit
43286
 
+  --run           try to run the given command, and emulate it if it fails
43287
 
+
43288
 
+Supported PROGRAM values:
43289
 
+  aclocal      touch file \`aclocal.m4'
43290
 
+  autoconf     touch file \`configure'
43291
 
+  autoheader   touch file \`config.h.in'
43292
 
+  autom4te     touch the output file, or create a stub one
43293
 
+  automake     touch all \`Makefile.in' files
43294
 
+  bison        create \`y.tab.[ch]', if possible, from existing .[ch]
43295
 
+  flex         create \`lex.yy.c', if possible, from existing .c
43296
 
+  help2man     touch the output file
43297
 
+  lex          create \`lex.yy.c', if possible, from existing .c
43298
 
+  makeinfo     touch the output file
43299
 
+  tar          try tar, gnutar, gtar, then tar without non-portable flags
43300
 
+  yacc         create \`y.tab.[ch]', if possible, from existing .[ch]
43301
 
+
43302
 
+Send bug reports to <bug-automake@gnu.org>."
43303
 
+    exit $?
43304
 
+    ;;
43305
 
+
43306
 
+  -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
43307
 
+    echo "missing $scriptversion (GNU Automake)"
43308
 
+    exit $?
43309
 
+    ;;
43310
 
+
43311
 
+  -*)
43312
 
+    echo 1>&2 "$0: Unknown \`$1' option"
43313
 
+    echo 1>&2 "Try \`$0 --help' for more information"
43314
 
+    exit 1
43315
 
+    ;;
43316
 
+
43317
 
+esac
43318
 
+
43319
 
+# Now exit if we have it, but it failed.  Also exit now if we
43320
 
+# don't have it and --version was passed (most likely to detect
43321
 
+# the program).
43322
 
+case $1 in
43323
 
+  lex|yacc)
43324
 
+    # Not GNU programs, they don't have --version.
43325
 
+    ;;
43326
 
+
43327
 
+  tar)
43328
 
+    if test -n "$run"; then
43329
 
+       echo 1>&2 "ERROR: \`tar' requires --run"
43330
 
+       exit 1
43331
 
+    elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
43332
 
+       exit 1
43333
 
+    fi
43334
 
+    ;;
43335
 
+
43336
 
+  *)
43337
 
+    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
43338
 
+       # We have it, but it failed.
43339
 
+       exit 1
43340
 
+    elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
43341
 
+       # Could not run --version or --help.  This is probably someone
43342
 
+       # running `$TOOL --version' or `$TOOL --help' to check whether
43343
 
+       # $TOOL exists and not knowing $TOOL uses missing.
43344
 
+       exit 1
43345
 
+    fi
43346
 
+    ;;
43347
 
+esac
43348
 
+
43349
 
+# If it does not exist, or fails to run (possibly an outdated version),
43350
 
+# try to emulate it.
43351
 
+case $1 in
43352
 
+  aclocal*)
43353
 
+    echo 1>&2 "\
43354
 
+WARNING: \`$1' is $msg.  You should only need it if
43355
 
+         you modified \`acinclude.m4' or \`${configure_ac}'.  You might want
43356
 
+         to install the \`Automake' and \`Perl' packages.  Grab them from
43357
 
+         any GNU archive site."
43358
 
+    touch aclocal.m4
43359
 
+    ;;
43360
 
+
43361
 
+  autoconf)
43362
 
+    echo 1>&2 "\
43363
 
+WARNING: \`$1' is $msg.  You should only need it if
43364
 
+         you modified \`${configure_ac}'.  You might want to install the
43365
 
+         \`Autoconf' and \`GNU m4' packages.  Grab them from any GNU
43366
 
+         archive site."
43367
 
+    touch configure
43368
 
+    ;;
43369
 
+
43370
 
+  autoheader)
43371
 
+    echo 1>&2 "\
43372
 
+WARNING: \`$1' is $msg.  You should only need it if
43373
 
+         you modified \`acconfig.h' or \`${configure_ac}'.  You might want
43374
 
+         to install the \`Autoconf' and \`GNU m4' packages.  Grab them
43375
 
+         from any GNU archive site."
43376
 
+    files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
43377
 
+    test -z "$files" && files="config.h"
43378
 
+    touch_files=
43379
 
+    for f in $files; do
43380
 
+      case $f in
43381
 
+      *:*) touch_files="$touch_files "`echo "$f" |
43382
 
+                                      sed -e 's/^[^:]*://' -e 's/:.*//'`;;
43383
 
+      *) touch_files="$touch_files $f.in";;
43384
 
+      esac
43385
 
+    done
43386
 
+    touch $touch_files
43387
 
+    ;;
43388
 
+
43389
 
+  automake*)
43390
 
+    echo 1>&2 "\
43391
 
+WARNING: \`$1' is $msg.  You should only need it if
43392
 
+         you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
43393
 
+         You might want to install the \`Automake' and \`Perl' packages.
43394
 
+         Grab them from any GNU archive site."
43395
 
+    find . -type f -name Makefile.am -print |
43396
 
+          sed 's/\.am$/.in/' |
43397
 
+          while read f; do touch "$f"; done
43398
 
+    ;;
43399
 
+
43400
 
+  autom4te)
43401
 
+    echo 1>&2 "\
43402
 
+WARNING: \`$1' is needed, but is $msg.
43403
 
+         You might have modified some files without having the
43404
 
+         proper tools for further handling them.
43405
 
+         You can get \`$1' as part of \`Autoconf' from any GNU
43406
 
+         archive site."
43407
 
+
43408
 
+    file=`echo "$*" | sed -n "$sed_output"`
43409
 
+    test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
43410
 
+    if test -f "$file"; then
43411
 
+       touch $file
43412
 
+    else
43413
 
+       test -z "$file" || exec >$file
43414
 
+       echo "#! /bin/sh"
43415
 
+       echo "# Created by GNU Automake missing as a replacement of"
43416
 
+       echo "#  $ $@"
43417
 
+       echo "exit 0"
43418
 
+       chmod +x $file
43419
 
+       exit 1
43420
 
+    fi
43421
 
+    ;;
43422
 
+
43423
 
+  bison|yacc)
43424
 
+    echo 1>&2 "\
43425
 
+WARNING: \`$1' $msg.  You should only need it if
43426
 
+         you modified a \`.y' file.  You may need the \`Bison' package
43427
 
+         in order for those modifications to take effect.  You can get
43428
 
+         \`Bison' from any GNU archive site."
43429
 
+    rm -f y.tab.c y.tab.h
43430
 
+    if test $# -ne 1; then
43431
 
+        eval LASTARG="\${$#}"
43432
 
+       case $LASTARG in
43433
 
+       *.y)
43434
 
+           SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
43435
 
+           if test -f "$SRCFILE"; then
43436
 
+                cp "$SRCFILE" y.tab.c
43437
 
+           fi
43438
 
+           SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
43439
 
+           if test -f "$SRCFILE"; then
43440
 
+                cp "$SRCFILE" y.tab.h
43441
 
+           fi
43442
 
+         ;;
43443
 
+       esac
43444
 
+    fi
43445
 
+    if test ! -f y.tab.h; then
43446
 
+       echo >y.tab.h
43447
 
+    fi
43448
 
+    if test ! -f y.tab.c; then
43449
 
+       echo 'main() { return 0; }' >y.tab.c
43450
 
+    fi
43451
 
+    ;;
43452
 
+
43453
 
+  lex|flex)
43454
 
+    echo 1>&2 "\
43455
 
+WARNING: \`$1' is $msg.  You should only need it if
43456
 
+         you modified a \`.l' file.  You may need the \`Flex' package
43457
 
+         in order for those modifications to take effect.  You can get
43458
 
+         \`Flex' from any GNU archive site."
43459
 
+    rm -f lex.yy.c
43460
 
+    if test $# -ne 1; then
43461
 
+        eval LASTARG="\${$#}"
43462
 
+       case $LASTARG in
43463
 
+       *.l)
43464
 
+           SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
43465
 
+           if test -f "$SRCFILE"; then
43466
 
+                cp "$SRCFILE" lex.yy.c
43467
 
+           fi
43468
 
+         ;;
43469
 
+       esac
43470
 
+    fi
43471
 
+    if test ! -f lex.yy.c; then
43472
 
+       echo 'main() { return 0; }' >lex.yy.c
43473
 
+    fi
43474
 
+    ;;
43475
 
+
43476
 
+  help2man)
43477
 
+    echo 1>&2 "\
43478
 
+WARNING: \`$1' is $msg.  You should only need it if
43479
 
+        you modified a dependency of a manual page.  You may need the
43480
 
+        \`Help2man' package in order for those modifications to take
43481
 
+        effect.  You can get \`Help2man' from any GNU archive site."
43482
 
+
43483
 
+    file=`echo "$*" | sed -n "$sed_output"`
43484
 
+    test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
43485
 
+    if test -f "$file"; then
43486
 
+       touch $file
43487
 
+    else
43488
 
+       test -z "$file" || exec >$file
43489
 
+       echo ".ab help2man is required to generate this page"
43490
 
+       exit 1
43491
 
+    fi
43492
 
+    ;;
43493
 
+
43494
 
+  makeinfo)
43495
 
+    echo 1>&2 "\
43496
 
+WARNING: \`$1' is $msg.  You should only need it if
43497
 
+         you modified a \`.texi' or \`.texinfo' file, or any other file
43498
 
+         indirectly affecting the aspect of the manual.  The spurious
43499
 
+         call might also be the consequence of using a buggy \`make' (AIX,
43500
 
+         DU, IRIX).  You might want to install the \`Texinfo' package or
43501
 
+         the \`GNU make' package.  Grab either from any GNU archive site."
43502
 
+    # The file to touch is that specified with -o ...
43503
 
+    file=`echo "$*" | sed -n "$sed_output"`
43504
 
+    test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
43505
 
+    if test -z "$file"; then
43506
 
+      # ... or it is the one specified with @setfilename ...
43507
 
+      infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
43508
 
+      file=`sed -n '
43509
 
+       /^@setfilename/{
43510
 
+         s/.* \([^ ]*\) *$/\1/
43511
 
+         p
43512
 
+         q
43513
 
+       }' $infile`
43514
 
+      # ... or it is derived from the source name (dir/f.texi becomes f.info)
43515
 
+      test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info
43516
 
+    fi
43517
 
+    # If the file does not exist, the user really needs makeinfo;
43518
 
+    # let's fail without touching anything.
43519
 
+    test -f $file || exit 1
43520
 
+    touch $file
43521
 
+    ;;
43522
 
+
43523
 
+  tar)
43524
 
+    shift
43525
 
+
43526
 
+    # We have already tried tar in the generic part.
43527
 
+    # Look for gnutar/gtar before invocation to avoid ugly error
43528
 
+    # messages.
43529
 
+    if (gnutar --version > /dev/null 2>&1); then
43530
 
+       gnutar "$@" && exit 0
43531
 
+    fi
43532
 
+    if (gtar --version > /dev/null 2>&1); then
43533
 
+       gtar "$@" && exit 0
43534
 
+    fi
43535
 
+    firstarg="$1"
43536
 
+    if shift; then
43537
 
+       case $firstarg in
43538
 
+       *o*)
43539
 
+           firstarg=`echo "$firstarg" | sed s/o//`
43540
 
+           tar "$firstarg" "$@" && exit 0
43541
 
+           ;;
43542
 
+       esac
43543
 
+       case $firstarg in
43544
 
+       *h*)
43545
 
+           firstarg=`echo "$firstarg" | sed s/h//`
43546
 
+           tar "$firstarg" "$@" && exit 0
43547
 
+           ;;
43548
 
+       esac
43549
 
+    fi
43550
 
+
43551
 
+    echo 1>&2 "\
43552
 
+WARNING: I can't seem to be able to run \`tar' with the given arguments.
43553
 
+         You may want to install GNU tar or Free paxutils, or check the
43554
 
+         command line arguments."
43555
 
+    exit 1
43556
 
+    ;;
43557
 
+
43558
 
+  *)
43559
 
+    echo 1>&2 "\
43560
 
+WARNING: \`$1' is needed, and is $msg.
43561
 
+         You might have modified some files without having the
43562
 
+         proper tools for further handling them.  Check the \`README' file,
43563
 
+         it often tells you about the needed prerequisites for installing
43564
 
+         this package.  You may also peek at any GNU archive site, in case
43565
 
+         some other package would contain this missing \`$1' program."
43566
 
+    exit 1
43567
 
+    ;;
43568
 
+esac
43569
 
+
43570
 
+exit 0
43571
 
+
43572
 
+# Local variables:
43573
 
+# eval: (add-hook 'write-file-hooks 'time-stamp)
43574
 
+# time-stamp-start: "scriptversion="
43575
 
+# time-stamp-format: "%:y-%02m-%02d.%02H"
43576
 
+# time-stamp-end: "$"
43577
 
+# End:
43578
 
diff -urN dovecot-1.2.4/dovecot-libsieve/NEWS dovecot-1.2.4.debian/dovecot-libsieve/NEWS
43579
 
--- dovecot-1.2.4/dovecot-libsieve/NEWS 1970-01-01 01:00:00.000000000 +0100
43580
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/NEWS  2009-08-21 01:04:01.000000000 +0200
43581
 
@@ -0,0 +1,253 @@
43582
 
+v0.1.12 21-08-2009 Stephan Bosch <stephan@rename-it.nl>
43583
 
+
43584
 
+       + Testsuite: added support for testing binaries stored on disk.
43585
 
+       + Implemented the new date extension. This allows matching against date
43586
 
+         values in header fields and the current date at the time of script
43587
 
+         evaluation.
43588
 
+
43589
 
+v0.1.11 08-08-2009 Stephan Bosch <stephan@rename-it.nl>
43590
 
+
43591
 
+       + Built skeleton implementation for the date extension (RFC 5260). It
43592
 
+         compiles, but it does not do anything useful yet. Therefore, it is not
43593
 
+         part of the default compilation. 
43594
 
+       - Fixed ARM portability issues caused by char type not being signed on that
43595
 
+         platform. Reading optional operands from a binary would fail for action
43596
 
+         side effects. Also, an accidental mixup of an int return type with bool
43597
 
+         caused the interpreter to continue on ARM even though an error occured.  
43598
 
+       - Removed direct stdint.h includes to prevent portability issues.
43599
 
+       - Fixed segfault bug in the handling of script open failures.
43600
 
+       - Include: improved user error messages and system log messages.
43601
 
+       - Fixed copy-paste mixup between sieve_after and sieve_before settings in the
43602
 
+         LDA Sieve plugin. If only a sieve_after script was active, nothing would 
43603
 
+         have been executed. Patch by Mike Abbott.
43604
 
+       - Include: fixed a bug in HOME substitution in the sieve_dir path. Surfaced
43605
 
+         in ManageSieve.
43606
 
+
43607
 
+v0.1.10 03-08-2009 Stephan Bosch <stephan@rename-it.nl>
43608
 
+
43609
 
+       * Changed action execution of fileinto and keep. These changes depend on
43610
 
+         API additions in Dovecot, making this release depend on Dovecot v1.2.2 
43611
 
+         or newer.
43612
 
+       * Further developed the sieve-filter command line tool. This required a few
43613
 
+         changes to the action execution of the Sieve engine. The tool was 
43614
 
+         successfully tested on folders with a few 100k spam messages. However, 
43615
 
+         the commandline options are still incomplete, a man page is missing and it
43616
 
+         needs much more testing before I can recommend anyone to use this tool. 
43617
 
+       + Added support for the mailbox extension. This allows checking whether a 
43618
 
+         mailbox exists using the mailboxexists command and it adds the :create 
43619
 
+         argument to the fileinto command to create the mailbox when it is missing. 
43620
 
+         The :create feature is useless unless the Deliver LDA is run with the -n 
43621
 
+         option.
43622
 
+       + Improved the testsuite with tests for message delivery. Messages stored
43623
 
+         using keep and fileinto can be fed back into the Sieve engine for
43624
 
+         verification. This includes testing of applied IMAP flags.
43625
 
+       + Updated the man pages with the new method of specifying the supported 
43626
 
+         extensions using + and - (for the -x parameter of the sieve tools)
43627
 
+       + Further developed the deprecated notify extension. A dummy for the denotify
43628
 
+         command exists, meaning that its use does not cause an error anymore. 
43629
 
+       - Fixed a bug in the derivation of the binary path from the script path. A 
43630
 
+         bare filename would yield a path relative to root.
43631
 
+       - Fixed a bug in the value matching code. The context data now uses a proper
43632
 
+         pool in stead of the data stack. Bug reported by Jan Sechser.
43633
 
+       - Fixed assertion fail in the include extension caused by missing 
43634
 
+         initialization upon binary load. This bug surfaces only for stored
43635
 
+         binaries. Bug reported by Tom Hendrikx.
43636
 
+       - Fixed include error message for failed :global include. It mentioned the 
43637
 
+         wrong config parameter.
43638
 
+       - Fixed broken wiki reference in an error message of the plugin about the
43639
 
+         'sieve' setting.
43640
 
+       - Fixed behavior of fileinto when delivering into a namespace prefix.
43641
 
+         Previous fix used the wrong storage.
43642
 
+
43643
 
+v0.1.9 22-07-2009  Stephan Bosch <stephan@rename-it.nl>
43644
 
+
43645
 
+       * Removed the unfinished sieve-filter tool from the default build. It is now 
43646
 
+         only built when the --with-unfinished-features switch is supplied during 
43647
 
+         configure.
43648
 
+       + Started building support for the ereject version of the reject action, 
43649
 
+         which has a preference to use an SMTP/LMTP protocol error in stead of a 
43650
 
+         bounce message. This is to be used to make the Sieve plugin honour Deliver's
43651
 
+         -e parameter. This is not yet finished and not built by default. 
43652
 
+       + Improved 'Permission denied' error messages just like Dovecot does,
43653
 
+         precisely specifying what permission is missing to access or create a file.
43654
 
+       + Added additional headers to the list of allowed headers for the address 
43655
 
+         test. The restrictive nature of the address test is not always appropriate. 
43656
 
+         Still thinking of a better, less restrictive implementation.
43657
 
+       + Made the deprecated notify extension compatible with the old CMUSieve
43658
 
+         plugin. However, the denotify command and the $text$ substitution are not
43659
 
+         yet supported. 
43660
 
+       + Made the discard action log a message to avoid confusion about disappearing 
43661
 
+         messages.
43662
 
+       - Fixed behavior of fileinto when delivering into a namespace prefix. It now
43663
 
+         uses silent delivery into INBOX as fallback.
43664
 
+       - Fixed logging of folder namespace prefix upon delivery into a prefixed 
43665
 
+         namespace. Formerly it only logged the bare folder name.
43666
 
+       - Fixed a potential segfault in the argument validation. It didn't surface
43667
 
+         because no command could have a :tag followed by an associated parameter as
43668
 
+         last argument.
43669
 
+       - Fixed segfault bug occuring in envelope test when performed on null (<>) 
43670
 
+         envelope path. The fix involves a rather large restructuring of the code to 
43671
 
+         make sure envelope addresses are properly handled everywhere (bug reported
43672
 
+         by Nikita Koshikov)
43673
 
+       - Envelope: fixed bug in application of address parts; failure to obtain 
43674
 
+         the part would cause inappropriate match success (bug reported by Ron Lee)
43675
 
+       - Fixed extension conflict checks during validation. It could sometimes
43676
 
+         produce useless errormessages. This is currently only used by the 
43677
 
+         deprecated extensions.
43678
 
+       - Forgot to remove old explicit storage library dependency (patch by 
43679
 
+         Arkadiusz Miskiewicz).
43680
 
+       - Fixed compiler warnings on certain platforms regarding the use fwrite for 
43681
 
+         outgoing message construction
43682
 
+
43683
 
+v0.1.8 12-07-2009  Stephan Bosch <stephan@rename-it.nl>
43684
 
+
43685
 
+       - Fixed AIX compile problem. For portability, the typeof operator is
43686
 
+         not used anymore. 
43687
 
+       + Added partial support for the deprecated notify extension. However, it
43688
 
+         turns out that the implementation provided by cmusieve is even older (2001),
43689
 
+         meaning that this is currently not backwards compatible with cmusieve.
43690
 
+
43691
 
+v0.1.7 05-07-2009  Stephan Bosch <stephan@rename-it.nl>
43692
 
+
43693
 
+       + Added support for CRLF line breaks in strbuf error handler to fix a
43694
 
+         ManageSieve problem.
43695
 
+       + Improved consistency of sieve tool documentation and fixed missing
43696
 
+         parameters in internal tool help output.
43697
 
+       + Enhanced extensions configuration, allowing to specify the enabled
43698
 
+         extensions relatively to the default (patch by Steffen Kaiser).
43699
 
+       - Forgot to initialize script execution status in Sieve plugin, causing 
43700
 
+         segfaults on compile errors in specific conditions.
43701
 
+       - Fixed logging in Sieve plugin for execution of default main script (went 
43702
 
+         to STDERR).
43703
 
+                                                                               
43704
 
+v0.1.6 18-06-2009  Stephan Bosch <stephan@rename-it.nl>
43705
 
+
43706
 
+       * Adjusted to changes in Dovecot to make it compile against v1.2.rc5
43707
 
+       * Made default of sieve_dir setting match the ManageSieve implementation.
43708
 
+       - Fixed a few problems in de body extension that caused assert failures in
43709
 
+         specific situations.  
43710
 
+
43711
 
+v0.1.5 18-04-2009  Stephan Bosch <stephan@rename-it.nl>
43712
 
+
43713
 
+       * Ported the implementation of the Sieve include extension to the latest 
43714
 
+         draft. This means that the import and export commands are replaced by a new 
43715
 
+         command called global. The import and export commands are now DEPRICATED and
43716
 
+         are mere aliases for the global command. The new specification also adds the
43717
 
+         :once modifier to the include command. The also newly specified global.* 
43718
 
+         variable namespace is not implemented yet as support for variable namespaces
43719
 
+         is currently missing.
43720
 
+       * Did a major rework of the multiscript support for better error handling and
43721
 
+         made sure that persistent global scripts (sieve_before/sieve_after) are
43722
 
+         always executed, even when the user does not have a script of his own and 
43723
 
+         a global default is missing. 
43724
 
+       + Provided basic support for the environment extension. Currenly, the name,
43725
 
+         version and host items are useful. Others are pending.
43726
 
+       + Improved error message that is presented when an unknown Sieve extension is
43727
 
+         provided as argument to the require command. It now notifies the user that
43728
 
+         Sieve core commands do not need to be specified in require.
43729
 
+       - Fixed bug in includes at levels deeper than one.
43730
 
+       - Fixed bug in address matching that was caused by the failure to handle group 
43731
 
+         specifications. In dovecot, these are marked by address items with NULL 
43732
 
+         elements, which causes a segfault if not considered. The group 'undisclosed-
43733
 
+         recipients:;' in particular triggered this bug. Bug reported by Bernhard
43734
 
+         Schmidt.        
43735
 
+
43736
 
+v0.1.4 21-03-2009  Stephan Bosch <stephan@rename-it.nl>
43737
 
+
43738
 
+       * Started work on the sieve-filter tool. With this command line tool it will 
43739
 
+         be possible to (re-)apply Sieve filters on a mail folder. It is currently
43740
 
+         undocumented and far from functional.
43741
 
+       + Added a custom debug extension that provides the possibility to print debug 
43742
 
+         messages from scripts executed by the Sieve tools.
43743
 
+       - Fixed issue with opening relative paths as a mail file. Bug reported by Ian
43744
 
+         P. Christian.
43745
 
+       - Fixed MAC OSX compile problem. Turns out the extern modifier was missing at
43746
 
+         multiple places. Bug reported by Edgar Fuss.
43747
 
+       - Fixed Solaris compile problem: removed unecessary and unportable linker
43748
 
+         flags that caused compile to fail. Bug reported by Andrés Yacopino.
43749
 
+
43750
 
+v0.1.3 12-02-2009  Stephan Bosch <stephan@rename-it.nl>
43751
 
+
43752
 
+       * Adapted to changes in Dovecot, making this release dependent on Dovecot
43753
 
+         >= 1.2.beta1
43754
 
+       * Made mail address comparison fully case-insensitive. This is particularly
43755
 
+         noticeable for the :addresses argument of the vacation command. 
43756
 
+       + Finished enotify extension. Currently, only the mailto notification method
43757
 
+         is implemented. All still needs to be tested thoroughly.
43758
 
+       + Implemented multiscript support. It is now possible to execute multiple
43759
 
+         Sieve scripts sequentially. Administrator-controlled scripts can be
43760
 
+         executed before and after the user's script. Still needs to be tested
43761
 
+         thoroughly.
43762
 
+       + Implemented support for configuring the available Sieve extensions.
43763
 
+       + Made the subaddress extension (partially) configurable using the
43764
 
+         sieve_subaddress_sep setting, which allows specifying a (multi-charater)
43765
 
+         separator other than '+'.
43766
 
+       + Compiler now warns about invalid header field names used for the header and
43767
 
+         address tests.
43768
 
+       + Vacation extension now properly generates a References header for the 
43769
 
+         response message.
43770
 
+       + Added testing of basic result execution to the test suite. Also added 
43771
 
+         supportfor testing the outgoing messages produced by the Sieve interpreter. 
43772
 
+       + Included execution of the actual result in the sieve-test command line tool.
43773
 
+         The undocumented sieve-exec tool that existed for this is now removed as 
43774
 
+         planned.
43775
 
+       + Added support for the now obsolete 'imapflags' extension for backwards
43776
 
+         compatibility with CMUSieve. This also implements the mark/unmark commands.
43777
 
+       - Fixed bugs in the regex extension: 1) if an optional match value did not in 
43778
 
+         fact match, subsequent match values would get unexpected indexes. 2) fixed
43779
 
+         segfault bug occuring when regex is freed.
43780
 
+       - Fixed bug in the use of the :from agrument for the vacation command. If this
43781
 
+         address included a phrase part, the response would not be a valid RFC822
43782
 
+         message.
43783
 
+       - Plugged a theoretical security hole occuring when a directory is opened as a 
43784
 
+         Sieve binary.
43785
 
+       - Cleaned up and fixed various log messages.
43786
 
+       - Fixed bug in the outgoing address verification. Addresses ending in ',' were 
43787
 
+         erroneously accepted.
43788
 
+
43789
 
+v0.1.2 26-11-2008  Stephan Bosch <stephan@rename-it.nl>
43790
 
+
43791
 
+       - Fixed important bug in the redirect action (and probably other actions like
43792
 
+         reject and vacation that only send messages). This was a bug in the handling
43793
 
+         of context information during the execution of actions. It caused the sieve 
43794
 
+         interpreter to crash with a segfault when redirect was executed. 
43795
 
+
43796
 
+v0.1.1 24-11-2008  Stephan Bosch <stephan@rename-it.nl>
43797
 
+
43798
 
+       * Re-enabled support for compiling against dovecot headers. Much like 
43799
 
+         cmusieve, command line tools like sievec and sieved are not compiled in this 
43800
 
+         case.
43801
 
+       * Started implementation of enotify extension. Not anywhere near finished
43802
 
+         though. 
43803
 
+       * Adapted to changes in Dovecot on various occasions, making this release
43804
 
+         dependent on Dovecot >= v1.2.alpa4.
43805
 
+
43806
 
+       + Improved logging of errors at specific occasions and added debug messages to
43807
 
+         find script execution problems quicker. 
43808
 
+       + Removed code duplication between command line tools and the test suite. 
43809
 
+         Also restructured the sources of the tools.
43810
 
+       + Added UTF-8 to UTF-7 folder name conversion for compatibility with IMAP.
43811
 
+       + Created man pages for the command line tools. These are automatically 
43812
 
+         installed upon 'make install'
43813
 
+       + Incorporated Valgrind support into the testsuite and fixed a few memory
43814
 
+         leaks in the process.
43815
 
+       - Fixed compile error surfacing for gcc3.4. Forgot mask argument for the 
43816
 
+         open() system call when the O_CREAT flag is specified. Bug found by 
43817
 
+         Sergey Ivanov.
43818
 
+       - Fixed bug in the sievec tool. -d output was always written to stdout.
43819
 
+       - Fixed important bug in the imap4flags extension. When no :flags argument is 
43820
 
+         specified, the previous version would always use the final value of the
43821
 
+         internal variable to set the flags. This means that modifications to the 
43822
 
+         internal variable also affected the bare fileinto/keep actions executed 
43823
 
+         earlier. This does not comply to the RFC. 
43824
 
+       - Fixed bug in the include extension's import/export commands. Duplicate
43825
 
+         import/exports caused problems.
43826
 
+       - Fixed bug in the handling of non-existent scripts. Errors were sometimes 
43827
 
+         ignored. 
43828
 
+       - Dovecot omitted unfolding multi-line headers. This was added to the cmusieve
43829
 
+         plugin after the code was incorporated into the new implementation. This is
43830
 
+         now mplicitly fixed by concurrent change in Dovecot. 
43831
 
+
43832
 
+v0.1.0 23-10-2008  Stephan Bosch <stephan@rename-it.nl>
43833
 
+
43834
 
+       * Initial release
43835
 
diff -urN dovecot-1.2.4/dovecot-libsieve/README dovecot-1.2.4.debian/dovecot-libsieve/README
43836
 
--- dovecot-1.2.4/dovecot-libsieve/README       1970-01-01 01:00:00.000000000 +0100
43837
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/README        2009-08-21 00:52:15.000000000 +0200
43838
 
@@ -0,0 +1,196 @@
43839
 
+Sieve implementation for Dovecot v1.2
43840
 
+
43841
 
+Introduction
43842
 
+------------
43843
 
+
43844
 
+Sieve is a machine language specifically tailored for internet message 
43845
 
+filtering. This package compiles into a Sieve plugin for the Dovecot local 
43846
 
+delivery agent called Deliver. The plugin adds Sieve filtering support to the 
43847
 
+delivery process.  
43848
 
+
43849
 
+Previously, the same functionality was provided by the cmusieve plugin for 
43850
 
+Dovecot. This old plugin is based on the CMU Sieve implementation included with
43851
 
+the Cyrus project. This new package provides a complete rewrite of the Sieve 
43852
 
+engine integrating it tightly with Dovecot. The actual execution of the Sieve 
43853
 
+actions is based on the original cmusieve plugin, but only on the code added to 
43854
 
+interface the CMU Sieve implementation with Dovocot. 
43855
 
+
43856
 
+The main reason for rewriting the Sieve engine is to provide more reliable 
43857
 
+script execution and to provide better error messages to users and system 
43858
 
+administrators. Also, since the Sieve language evolves quickly, with new 
43859
 
+language extensions published every year, the aim is to provide support for 
43860
 
+quickly extending the engine with new features. 
43861
 
+
43862
 
+Features
43863
 
+--------
43864
 
+
43865
 
+* Well-structured 3-stage compiler:
43866
 
43867
 
+  Uses dovecot framework and avoids using lex/yacc. Compiler doesn't bail on 
43868
 
+  first error, but tries to find more. Produced errors are aimed to be useful 
43869
 
+  and generally user-comprehensible. Things like 'Generic error' are a nuisance 
43870
 
+  of the past. 
43871
 
+
43872
 
+* Highly extendable with new Sieve capabilities: 
43873
 
+
43874
 
+  This keeps the possibility of plugins in mind. It should eventually provide 
43875
 
+  the necessary infrastructure for at least all currently known (proposed) 
43876
 
+  extensions. The goal is to keep the extension interface provided by sieve 
43877
 
+  engine as generic as possible, i.e. without explicit support for specific 
43878
 
+  extensions. New similar extensions can then use the same interface methods 
43879
 
+  without changes to the sieve engine code. If an extension is not loaded using 
43880
 
+  the require command, the compiler truly does not know of its existance. 
43881
 
+
43882
 
+* Supports all extensions provided by the original CMUSieve plugin:
43883
 
43884
 
+  In addition, it has support for the new and very useful variables extension
43885
 
+  (see next section). 
43886
 
+
43887
 
+  NOTE: The original CMUSieve plugin is based on old specifications of the 
43888
 
+  imap4flags and enotify extension. Among other subtle differences, these 
43889
 
+  extensions were known as 'imapflags' and 'notify' for the CMU Sieve plugin.
43890
 
+  Support for the old imapflags extension is provided for backwards compatibility.
43891
 
+
43892
 
+* Supports executing multiple scrips sequentially.
43893
 
+  
43894
 
+  Using this feature it is possible to execute administrator-controlled Sieve
43895
 
+  scripts before and after the user's Sieve script is executed. As long as the
43896
 
+  verdict is at least (implicit) keep, the execution will continue with the next
43897
 
+  script. Multiple scripts can be executed before or after the user's script by 
43898
 
+  specifying directories containing sieve files.
43899
 
+
43900
 
+* Supported by ManageSieve service:
43901
 
+
43902
 
+  This Sieve implementation is supported by the ManageSieve implementation for 
43903
 
+  Dovecot v1.2. Therefore, ManageSieve support can be added to Dovecot for the
43904
 
+  new Sieve plugin just as for the cmusieve plugin.
43905
 
+
43906
 
+* Test suite included:
43907
 
+       
43908
 
+  This package includes a test suite to automatically asses whether the compiled 
43909
 
+  sieve engine works correctly. The test suite is an extension to the Sieve 
43910
 
+  language and is therefore easily extended with new tests. Currently, the 
43911
 
+  test suite is mostly limited to testing script processing. The performed actions 
43912
 
+  are not tested fully yet. 
43913
 
+
43914
 
+Implementation Status
43915
 
+---------------------
43916
 
+
43917
 
+The the core of the language (as specified in RFC 5228) is fully supported. In 
43918
 
+addition to that, this Sieve implementation features various extensions. The 
43919
 
+following list outlines the implementation status of each supported extension:
43920
 
+       
43921
 
+  Base specification (RFC5228):
43922
 
+    fileinto: full
43923
 
+    reject: full (without Dovecot LMTP currently no refuse support)
43924
 
+    envelope: full
43925
 
+    encoded-character: full
43926
 
+
43927
 
+  Other RFCs/drafts:
43928
 
+    subaddress: full (limited configurability)
43929
 
+    comparator-i;ascii-numeric: full
43930
 
+    relational: full 
43931
 
+    copy: full
43932
 
+    regex: mostly full; but suboptimal and no UTF-8
43933
 
+    body: mostly full, but text body-transform implementation is simple
43934
 
+        and some issues make it still not completely RFC incompliant. 
43935
 
+    include: almost full; global namespace missing 
43936
 
+    vacation: mostly full; handling of utf-8 in headers is non-existant
43937
 
+    imap4flags: full (old imapflags supported for backwards compatibility)
43938
 
+    variables: mostly full; currently no support for future namespaces 
43939
 
+    notify: full, mailto support only; needs to be tested more
43940
 
+       environment: basic
43941
 
+       mailbox: almost full, but mailboxexists command lacks ACL support
43942
 
+       date: full
43943
 
+
43944
 
+All implemented extensions are like the engine itself currently experimental. 
43945
 
+A status of 'full' does not necessarily mean that the extension is bug-free or 
43946
 
+even fully RFC-compliant. Check the TODO file for open issues.
43947
 
43948
 
+Many more extensions to the language exist. Not all of these extensions are 
43949
 
+useful for Dovecot in particular, but many of them are. Currently, the author 
43950
 
+has taken notice of the following extensions:
43951
 
+
43952
 
+    date,index: planned
43953
 
+    editheader: planned, needs additional support from Dovecot though.
43954
 
+    mimeloop: planned
43955
 
+
43956
 
+These extensions will be added as soon as the necessary infrastructure is 
43957
 
+available. 
43958
 
+
43959
 
+Compiling and Configuring
43960
 
+-------------------------
43961
 
+
43962
 
+Refer to INSTALL file.
43963
 
+
43964
 
+Using
43965
 
+-----
43966
 
+
43967
 
+The main purpose of this package is to replace the existing cmusieve plugin that 
43968
 
+is currently available for Dovecot's deliver. With this respect it is currently 
43969
 
+not very different from the cmusieve plugin implementation.
43970
 
+
43971
 
+Unlike cmusieve, this sieve module logs runtime errors to <scriptfile>.log if 
43972
 
+it can and not <scriptfile>.err. It appends new timestamped log entries to the 
43973
 
+end of the logfile. If the log grows too large (currently > 10kB), the logfile 
43974
 
+is rotated to <scriptfile>.log.0 and <scriptfile>.log starts out empty again. 
43975
 
+
43976
 
+The cmusieve plugin compiled the script into a file with an appended 'c', e.g. 
43977
 
+'test.sievec'. This new implementation recognizes scripts to have the .sieve 
43978
 
+extension. The binary is (by default) written to a file with extension .svbin. 
43979
 
+This means that the default .dovecot.sieve is compiled into .dovecot.svbin. 
43980
 
+Included scripts are currently always compiled into the main binary, meaning 
43981
 
+that no other files are written and no permission to do so is necessary for the 
43982
 
+global script directories. 
43983
 
+
43984
 
+To test the sieve engine outside deliver, it is useful to try the commands that 
43985
 
+exist in the src/sieve-tools/ directory of this package. After installation, 
43986
 
+these are available at your $prefix/bin directory. The following commands are 
43987
 
+installed:
43988
 
+
43989
 
+sievec     - Compiles sieve scripts into a binary representation for later 
43990
 
+             execution.
43991
 
+
43992
 
+sieve-test - This is a universal Sieve test tool for testing the effect of a
43993
 
+             Sieve script on a particular message. It allows compiling, running 
43994
 
+             and testing Sieve scripts. It can either be used to display the
43995
 
+             actions that would be performed on the provided test message or it
43996
 
+             can be used to test the actual delivery of the message and show the
43997
 
+             messages that would normally be sent through SMTP.
43998
 
+
43999
 
+sieved     - Dumps the content of a Sieve binary file for (development) 
44000
 
+             debugging purposes.
44001
 
+
44002
 
+When installed, man pages are also available for these commands. In this package
44003
 
+the man pages are present in doc/man and can be viewed before install using e.g.: 
44004
 
+
44005
 
+man -l doc/man/sieve-test.1
44006
 
+
44007
 
+Various example scripts are bundled in the directory 'examples'. These scripts
44008
 
+were downloaded from various locations. View the top comment in the scripts for 
44009
 
+url and author information.
44010
 
+
44011
 
+Known issues
44012
 
+------------
44013
 
+
44014
 
+Most open issues are outlined in the TODO file. The more generic ones are (re-)
44015
 
+listed here:
44016
 
+
44017
 
+- Compile errors are sometimes a bit obscure and long. This needs work. 
44018
 
+  Suggestions for improvement are welcome. 
44019
 
+- The documentation needs work.
44020
 
+
44021
 
+Authors
44022
 
+-------
44023
 
+
44024
 
+Refer to AUTHORS file.
44025
 
+
44026
 
+Contact Info
44027
 
+------------
44028
 
+
44029
 
+Stephan Bosch <stephan at rename-it dot nl>
44030
 
+IRC: Freenode, #dovecot, S[r]us
44031
 
+
44032
 
+Please use the Dovecot mailing list <dovecot at dovecot.org> for questions about 
44033
 
+this package. You can post to the list without subscribing, the mail then waits 
44034
 
+in a moderator queue for a while. See http://dovecot.org/mailinglists.html
44035
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/cmd-discard.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/cmd-discard.c
44036
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/cmd-discard.c  1970-01-01 01:00:00.000000000 +0100
44037
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/cmd-discard.c   2009-07-17 01:03:08.000000000 +0200
44038
 
@@ -0,0 +1,160 @@
44039
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
44040
 
+ */
44041
 
+
44042
 
+#include "lib.h"
44043
 
+#include "str-sanitize.h"
44044
 
+
44045
 
+#include "sieve-common.h"
44046
 
+#include "sieve-commands.h"
44047
 
+#include "sieve-code.h"
44048
 
+#include "sieve-dump.h"
44049
 
+#include "sieve-actions.h"
44050
 
+#include "sieve-validator.h" 
44051
 
+#include "sieve-generator.h"
44052
 
+#include "sieve-interpreter.h"
44053
 
+#include "sieve-result.h"
44054
 
+
44055
 
+/* 
44056
 
+ * Discard command 
44057
 
+ * 
44058
 
+ * Syntax
44059
 
+ *   discard
44060
 
+ */    
44061
 
+
44062
 
+static bool cmd_discard_generate
44063
 
+       (const struct sieve_codegen_env *cgenv, 
44064
 
+               struct sieve_command_context *ctx ATTR_UNUSED); 
44065
 
+
44066
 
+const struct sieve_command cmd_discard = { 
44067
 
+       "discard", 
44068
 
+       SCT_COMMAND, 
44069
 
+       0, 0, FALSE, FALSE,
44070
 
+       NULL, NULL, NULL, 
44071
 
+       cmd_discard_generate, 
44072
 
+       NULL 
44073
 
+};
44074
 
+
44075
 
+/*
44076
 
+ * Discard operation
44077
 
+ */
44078
 
+
44079
 
+static bool cmd_discard_operation_dump
44080
 
+       (const struct sieve_operation *op,
44081
 
+       const struct sieve_dumptime_env *denv, sieve_size_t *address);
44082
 
+static int cmd_discard_operation_execute
44083
 
+       (const struct sieve_operation *op, 
44084
 
+               const struct sieve_runtime_env *renv, sieve_size_t *address);
44085
 
+
44086
 
+const struct sieve_operation cmd_discard_operation = { 
44087
 
+       "DISCARD",
44088
 
+       NULL,
44089
 
+       SIEVE_OPERATION_DISCARD,
44090
 
+       cmd_discard_operation_dump, 
44091
 
+       cmd_discard_operation_execute 
44092
 
+};
44093
 
+
44094
 
+/* 
44095
 
+ * Discard actions
44096
 
+ */
44097
 
+
44098
 
+static void act_discard_print
44099
 
+       (const struct sieve_action *action, const struct sieve_result_print_env *rpenv,
44100
 
+               void *context, bool *keep);     
44101
 
+static bool act_discard_commit
44102
 
+       (const struct sieve_action *action, 
44103
 
+               const struct sieve_action_exec_env *aenv, void *tr_context, bool *keep);
44104
 
+               
44105
 
+const struct sieve_action act_discard = {
44106
 
+       "discard",
44107
 
+       0,
44108
 
+       NULL, NULL, NULL,
44109
 
+       act_discard_print,
44110
 
+       NULL, NULL,
44111
 
+       act_discard_commit,
44112
 
+       NULL
44113
 
+};
44114
 
+
44115
 
+/*
44116
 
+ * Code generation
44117
 
+ */
44118
 
44119
 
+static bool cmd_discard_generate
44120
 
+(const struct sieve_codegen_env *cgenv, 
44121
 
+       struct sieve_command_context *ctx ATTR_UNUSED) 
44122
 
+{
44123
 
+       sieve_operation_emit_code(cgenv->sbin, &cmd_discard_operation);
44124
 
+
44125
 
+       /* Emit line number */
44126
 
+    sieve_code_source_line_emit(cgenv->sbin, sieve_command_source_line(ctx));
44127
 
+
44128
 
+       return TRUE;
44129
 
+}
44130
 
+
44131
 
+/* 
44132
 
+ * Code dump
44133
 
+ */
44134
 
+
44135
 
+static bool cmd_discard_operation_dump
44136
 
+(const struct sieve_operation *op ATTR_UNUSED,
44137
 
+    const struct sieve_dumptime_env *denv, sieve_size_t *address)
44138
 
+{
44139
 
+    sieve_code_dumpf(denv, "DISCARD");
44140
 
+    sieve_code_descend(denv);
44141
 
+
44142
 
+    /* Source line */
44143
 
+    if ( !sieve_code_source_line_dump(denv, address) )
44144
 
+        return FALSE;
44145
 
+
44146
 
+    return sieve_code_dumper_print_optional_operands(denv, address);
44147
 
+}
44148
 
+
44149
 
+/*
44150
 
+ * Interpretation
44151
 
+ */
44152
 
+
44153
 
+static int cmd_discard_operation_execute
44154
 
+(const struct sieve_operation *op ATTR_UNUSED,
44155
 
+       const struct sieve_runtime_env *renv ATTR_UNUSED, 
44156
 
+       sieve_size_t *address ATTR_UNUSED)
44157
 
+{      
44158
 
+       unsigned int source_line;
44159
 
+       
44160
 
+       /* Source line */
44161
 
+    if ( !sieve_code_source_line_read(renv, address, &source_line) ) {
44162
 
+               sieve_runtime_trace_error(renv, "failed to read source line");
44163
 
+        return SIEVE_EXEC_BIN_CORRUPT;
44164
 
+       }
44165
 
+
44166
 
+       sieve_runtime_trace(renv, "DISCARD action");
44167
 
+
44168
 
+       return ( sieve_result_add_action
44169
 
+               (renv, &act_discard, NULL, source_line, NULL, 0) >= 0 );
44170
 
+}
44171
 
+
44172
 
+/*
44173
 
+ * Action implementation
44174
 
+ */
44175
 
44176
 
+static void act_discard_print
44177
 
+(const struct sieve_action *action ATTR_UNUSED, 
44178
 
+       const struct sieve_result_print_env *rpenv, void *context ATTR_UNUSED, 
44179
 
+       bool *keep)     
44180
 
+{
44181
 
+       sieve_result_action_printf(rpenv, "discard");
44182
 
+       
44183
 
+       *keep = FALSE;
44184
 
+}
44185
 
+
44186
 
+static bool act_discard_commit
44187
 
+(const struct sieve_action *action ATTR_UNUSED, 
44188
 
+       const struct sieve_action_exec_env *aenv, 
44189
 
+       void *tr_context ATTR_UNUSED, bool *keep)
44190
 
+{
44191
 
+       sieve_result_log(aenv, 
44192
 
+               "marked message to be discarded if not explicitly delivered "
44193
 
+               "(discard action)");
44194
 
+       *keep = FALSE;
44195
 
+
44196
 
+       return TRUE;
44197
 
+}
44198
 
+
44199
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/cmd-if.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/cmd-if.c
44200
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/cmd-if.c       1970-01-01 01:00:00.000000000 +0100
44201
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/cmd-if.c        2009-01-06 00:15:52.000000000 +0100
44202
 
@@ -0,0 +1,225 @@
44203
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
44204
 
+ */
44205
 
+
44206
 
+#include "sieve-common.h"
44207
 
+#include "sieve-commands.h"
44208
 
+#include "sieve-validator.h"
44209
 
+#include "sieve-generator.h"
44210
 
+#include "sieve-code.h"
44211
 
+#include "sieve-binary.h"
44212
 
+
44213
 
+/*
44214
 
+ * Commands
44215
 
+ */
44216
 
+
44217
 
+/* If command
44218
 
+ *
44219
 
+ * Syntax:   
44220
 
+ *   if <test1: test> <block1: block>
44221
 
+ */
44222
 
+
44223
 
+static bool cmd_if_validate
44224
 
+       (struct sieve_validator *validator, struct sieve_command_context *cmd);
44225
 
+static bool cmd_if_generate
44226
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx);
44227
 
+
44228
 
+const struct sieve_command cmd_if = { 
44229
 
+       "if", 
44230
 
+       SCT_COMMAND, 
44231
 
+       0, 1, TRUE, TRUE,
44232
 
+       NULL, NULL,
44233
 
+       cmd_if_validate, 
44234
 
+       cmd_if_generate, 
44235
 
+       NULL 
44236
 
+};
44237
 
+
44238
 
+/* ElsIf command
44239
 
+ *
44240
 
+ * Santax:
44241
 
+ *   elsif <test2: test> <block2: block>
44242
 
+ */
44243
 
+
44244
 
+static bool cmd_elsif_validate
44245
 
+       (struct sieve_validator *validator, struct sieve_command_context *cmd);
44246
 
+
44247
 
+const struct sieve_command cmd_elsif = {
44248
 
+    "elsif", 
44249
 
+       SCT_COMMAND,
44250
 
+       0, 1, TRUE, TRUE, 
44251
 
+       NULL, NULL, 
44252
 
+       cmd_elsif_validate, 
44253
 
+       cmd_if_generate, 
44254
 
+       NULL 
44255
 
+};
44256
 
+
44257
 
+/* Else command 
44258
 
+ *
44259
 
+ * Syntax:   
44260
 
+ *   else <block>
44261
 
+ */
44262
 
+
44263
 
+static bool cmd_else_generate
44264
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx);
44265
 
+
44266
 
+const struct sieve_command cmd_else = {
44267
 
+    "else", 
44268
 
+       SCT_COMMAND, 
44269
 
+       0, 0, TRUE, TRUE,
44270
 
+       NULL, NULL,
44271
 
+       cmd_elsif_validate, 
44272
 
+       cmd_else_generate, 
44273
 
+       NULL 
44274
 
+};
44275
 
+
44276
 
+/* 
44277
 
+ * Context management
44278
 
+ */
44279
 
+
44280
 
+struct cmd_if_context_data {
44281
 
+       struct cmd_if_context_data *previous;
44282
 
+       struct cmd_if_context_data *next;
44283
 
+       
44284
 
+       bool jump_generated;
44285
 
+       sieve_size_t exit_jump;
44286
 
+};
44287
 
+
44288
 
+static void cmd_if_initialize_context_data
44289
 
+(struct sieve_command_context *cmd, struct cmd_if_context_data *previous) 
44290
 
+{      
44291
 
+       struct cmd_if_context_data *ctx_data;
44292
 
+
44293
 
+       /* Assign context */
44294
 
+       ctx_data = p_new(sieve_command_pool(cmd), struct cmd_if_context_data, 1);
44295
 
+       ctx_data->exit_jump = 0;
44296
 
+       ctx_data->jump_generated = FALSE;
44297
 
+
44298
 
+       /* Update linked list of contexts */
44299
 
+       ctx_data->previous = previous;
44300
 
+       ctx_data->next = NULL;  
44301
 
+       if ( previous != NULL )
44302
 
+               previous->next = ctx_data;
44303
 
+       
44304
 
+       /* Assign to command context */
44305
 
+       cmd->data = ctx_data;
44306
 
+}
44307
 
+
44308
 
+/* 
44309
 
+ * Validation 
44310
 
+ */
44311
 
+
44312
 
+static bool cmd_if_validate
44313
 
+(struct sieve_validator *validator ATTR_UNUSED, struct sieve_command_context *cmd) 
44314
 
+{ 
44315
 
+       /* Start if-command structure */
44316
 
+       cmd_if_initialize_context_data(cmd, NULL);
44317
 
+       
44318
 
+       return TRUE;
44319
 
+}
44320
 
+
44321
 
+static bool cmd_elsif_validate
44322
 
+(struct sieve_validator *validator, struct sieve_command_context *cmd)
44323
 
+{
44324
 
+       struct sieve_command_context *prev_context = 
44325
 
+               sieve_command_prev_context(cmd);
44326
 
+
44327
 
+       /* Check valid command placement */
44328
 
+       if ( prev_context == NULL ||
44329
 
+               ( prev_context->command != &cmd_if &&
44330
 
+                       prev_context->command != &cmd_elsif ) ) 
44331
 
+       {               
44332
 
+               sieve_command_validate_error(validator, cmd, 
44333
 
+                       "the %s command must follow an if or elseif command", 
44334
 
+                       cmd->command->identifier);
44335
 
+               return FALSE;
44336
 
+       }
44337
 
+       
44338
 
+       /* Previous command in this block is 'if' or 'elsif', so we can safely refer 
44339
 
+        * to its context data 
44340
 
+        */
44341
 
+       cmd_if_initialize_context_data(cmd, prev_context->data);
44342
 
+
44343
 
+       return TRUE;
44344
 
+}
44345
 
+
44346
 
+/* 
44347
 
+ * Code generation 
44348
 
+ */
44349
 
+
44350
 
+/* The if command does not generate specific IF-ELSIF-ELSE opcodes, but only uses
44351
 
+ * JMP instructions. This is why the implementation of the if command does not 
44352
 
+ * include an opcode implementation.
44353
 
+ */
44354
 
+
44355
 
+static void cmd_if_resolve_exit_jumps
44356
 
+(struct sieve_binary *sbin, struct cmd_if_context_data *ctx_data) 
44357
 
+{
44358
 
+       struct cmd_if_context_data *if_ctx = ctx_data->previous;
44359
 
+       
44360
 
+       /* Iterate backwards through all if-command contexts and resolve the 
44361
 
+        * exit jumps to the current code position.
44362
 
+        */
44363
 
+       while ( if_ctx != NULL ) {
44364
 
+               if ( if_ctx->jump_generated ) 
44365
 
+                       sieve_binary_resolve_offset(sbin, if_ctx->exit_jump);
44366
 
+               if_ctx = if_ctx->previous;      
44367
 
+       }
44368
 
+}
44369
 
+
44370
 
+static bool cmd_if_generate
44371
 
+(const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx)
44372
 
+{
44373
 
+       struct sieve_binary *sbin = cgenv->sbin;
44374
 
+       struct cmd_if_context_data *ctx_data = (struct cmd_if_context_data *) ctx->data;
44375
 
+       struct sieve_ast_node *test;
44376
 
+       struct sieve_jumplist jmplist;
44377
 
+       
44378
 
+       /* Prepare jumplist */
44379
 
+       sieve_jumplist_init_temp(&jmplist, sbin);
44380
 
+       
44381
 
+       /* Generate test condition */
44382
 
+       test = sieve_ast_test_first(ctx->ast_node);
44383
 
+       if ( !sieve_generate_test(cgenv, test, &jmplist, FALSE) )
44384
 
+               return FALSE;
44385
 
+               
44386
 
+       /* Case true { */
44387
 
+       if ( !sieve_generate_block(cgenv, ctx->ast_node) ) 
44388
 
+               return FALSE;
44389
 
+       
44390
 
+       /* Are we the final command in this if-elsif-else structure? */
44391
 
+       if ( ctx_data->next != NULL ) {
44392
 
+               /* No, generate jump to end of if-elsif-else structure (resolved later) 
44393
 
+                * This of course is not necessary if the {} block contains a command 
44394
 
+                * like stop at top level that unconditionally exits the block already
44395
 
+                * anyway. 
44396
 
+                */
44397
 
+               if ( !sieve_command_block_exits_unconditionally(ctx) ) {
44398
 
+                       sieve_operation_emit_code(sbin, &sieve_jmp_operation);
44399
 
+                       ctx_data->exit_jump = sieve_binary_emit_offset(sbin, 0);
44400
 
+                       ctx_data->jump_generated = TRUE;
44401
 
+               }
44402
 
+       } else {
44403
 
+               /* Yes, Resolve previous exit jumps to this point */
44404
 
+               cmd_if_resolve_exit_jumps(sbin, ctx_data);
44405
 
+       }
44406
 
+       
44407
 
+       /* Case false ... (subsequent elsif/else commands might generate more) */
44408
 
+       sieve_jumplist_resolve(&jmplist);       
44409
 
+               
44410
 
+       return TRUE;
44411
 
+}
44412
 
+
44413
 
+static bool cmd_else_generate
44414
 
+(const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx)
44415
 
+{
44416
 
+       struct cmd_if_context_data *ctx_data = (struct cmd_if_context_data *) ctx->data;
44417
 
+       
44418
 
+       /* Else { */
44419
 
+       if ( !sieve_generate_block(cgenv, ctx->ast_node) ) 
44420
 
+               return FALSE;
44421
 
+               
44422
 
+       /* } End: resolve all exit blocks */    
44423
 
+       cmd_if_resolve_exit_jumps(cgenv->sbin, ctx_data);
44424
 
+               
44425
 
+       return TRUE;
44426
 
+}
44427
 
+
44428
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/cmd-keep.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/cmd-keep.c
44429
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/cmd-keep.c     1970-01-01 01:00:00.000000000 +0100
44430
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/cmd-keep.c      2009-01-06 00:15:52.000000000 +0100
44431
 
@@ -0,0 +1,124 @@
44432
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
44433
 
+ */
44434
 
+
44435
 
+#include "lib.h"
44436
 
+
44437
 
+#include "sieve-common.h"
44438
 
+#include "sieve-commands.h"
44439
 
+#include "sieve-code.h"
44440
 
+#include "sieve-dump.h"
44441
 
+#include "sieve-actions.h"
44442
 
+#include "sieve-validator.h" 
44443
 
+#include "sieve-generator.h"
44444
 
+#include "sieve-interpreter.h"
44445
 
+#include "sieve-result.h"
44446
 
+
44447
 
+/* 
44448
 
+ * Keep command 
44449
 
+ *
44450
 
+ * Syntax:
44451
 
+ *   keep
44452
 
+ */    
44453
 
+
44454
 
+static bool cmd_keep_generate
44455
 
+       (const struct sieve_codegen_env *cgenv, 
44456
 
+               struct sieve_command_context *ctx);
44457
 
+
44458
 
+const struct sieve_command cmd_keep = { 
44459
 
+       "keep", 
44460
 
+       SCT_COMMAND, 
44461
 
+       0, 0, FALSE, FALSE,
44462
 
+       NULL, NULL, NULL, 
44463
 
+       cmd_keep_generate, 
44464
 
+       NULL
44465
 
+};
44466
 
+
44467
 
+/* 
44468
 
+ * Keep operation 
44469
 
+ */
44470
 
+
44471
 
+static bool cmd_keep_operation_dump
44472
 
+       (const struct sieve_operation *op,
44473
 
+       const struct sieve_dumptime_env *denv, sieve_size_t *address);
44474
 
+static int cmd_keep_operation_execute
44475
 
+       (const struct sieve_operation *op, 
44476
 
+               const struct sieve_runtime_env *renv, sieve_size_t *address);
44477
 
+
44478
 
+const struct sieve_operation cmd_keep_operation = { 
44479
 
+       "KEEP",
44480
 
+       NULL,
44481
 
+       SIEVE_OPERATION_KEEP,
44482
 
+       cmd_keep_operation_dump, 
44483
 
+       cmd_keep_operation_execute 
44484
 
+};
44485
 
+
44486
 
+/*
44487
 
+ * Code generation
44488
 
+ */
44489
 
+
44490
 
+static bool cmd_keep_generate
44491
 
+(const struct sieve_codegen_env *cgenv, 
44492
 
+       struct sieve_command_context *ctx ATTR_UNUSED) 
44493
 
+{
44494
 
+       /* Emit opcode */
44495
 
+       sieve_operation_emit_code(cgenv->sbin, &cmd_keep_operation);
44496
 
+
44497
 
+       /* Emit line number */
44498
 
+    sieve_code_source_line_emit(cgenv->sbin, sieve_command_source_line(ctx));
44499
 
+
44500
 
+       /* Generate arguments */
44501
 
+       return sieve_generate_arguments(cgenv, ctx, NULL);
44502
 
+}
44503
 
+
44504
 
+/* 
44505
 
+ * Code dump
44506
 
+ */
44507
 
+
44508
 
+static bool cmd_keep_operation_dump
44509
 
+(const struct sieve_operation *op ATTR_UNUSED,
44510
 
+    const struct sieve_dumptime_env *denv, sieve_size_t *address)
44511
 
+{
44512
 
+    sieve_code_dumpf(denv, "KEEP");
44513
 
+    sieve_code_descend(denv);
44514
 
+
44515
 
+    /* Source line */
44516
 
+    if ( !sieve_code_source_line_dump(denv, address) )
44517
 
+        return FALSE;
44518
 
+
44519
 
+    return sieve_code_dumper_print_optional_operands(denv, address);
44520
 
+}
44521
 
+
44522
 
+/*
44523
 
+ * Interpretation
44524
 
+ */
44525
 
+
44526
 
+static int cmd_keep_operation_execute
44527
 
+(const struct sieve_operation *op ATTR_UNUSED,
44528
 
+       const struct sieve_runtime_env *renv ATTR_UNUSED, 
44529
 
+       sieve_size_t *address ATTR_UNUSED)
44530
 
+{      
44531
 
+       struct sieve_side_effects_list *slist = NULL;
44532
 
+       unsigned int source_line;
44533
 
+       int ret = 0;    
44534
 
+
44535
 
+       /* Source line */
44536
 
+       if ( !sieve_code_source_line_read(renv, address, &source_line) ) {
44537
 
+               sieve_runtime_trace_error(renv, "invalid source line");
44538
 
+        return SIEVE_EXEC_BIN_CORRUPT;
44539
 
+       }
44540
 
+       
44541
 
+       /* Optional operands (side effects only) */
44542
 
+       if ( (ret=sieve_interpreter_handle_optional_operands
44543
 
+               (renv, address, &slist)) <= 0 ) 
44544
 
+               return ret;
44545
 
+
44546
 
+       sieve_runtime_trace(renv, "KEEP action");
44547
 
+       
44548
 
+       /* Add keep action to result. 
44549
 
+        */
44550
 
+       ret = sieve_result_add_keep(renv, slist, source_line);
44551
 
+       
44552
 
+       return ( ret >= 0 );
44553
 
+}
44554
 
+
44555
 
+
44556
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/cmd-redirect.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/cmd-redirect.c
44557
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/cmd-redirect.c 1970-01-01 01:00:00.000000000 +0100
44558
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/cmd-redirect.c  2009-07-21 03:02:37.000000000 +0200
44559
 
@@ -0,0 +1,386 @@
44560
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
44561
 
+ */
44562
 
+
44563
 
+#include "lib.h"
44564
 
+#include "ioloop.h"
44565
 
+#include "str-sanitize.h"
44566
 
+#include "istream.h"
44567
 
+#include "istream-crlf.h"
44568
 
+#include "istream-header-filter.h"
44569
 
+
44570
 
+#include "rfc2822.h"
44571
 
+
44572
 
+#include "sieve-common.h"
44573
 
+#include "sieve-limits.h"
44574
 
+#include "sieve-address.h"
44575
 
+#include "sieve-commands.h"
44576
 
+#include "sieve-code.h"
44577
 
+#include "sieve-actions.h"
44578
 
+#include "sieve-validator.h" 
44579
 
+#include "sieve-generator.h"
44580
 
+#include "sieve-interpreter.h"
44581
 
+#include "sieve-code-dumper.h"
44582
 
+#include "sieve-result.h"
44583
 
+#include "sieve-message.h"
44584
 
+
44585
 
+#include <stdio.h>
44586
 
+
44587
 
+/* 
44588
 
+ * Configuration 
44589
 
+ */
44590
 
+
44591
 
+#define CMD_REDIRECT_DUPLICATE_KEEP (3600 * 24)
44592
 
+
44593
 
+/* 
44594
 
+ * Redirect command 
44595
 
+ * 
44596
 
+ * Syntax
44597
 
+ *   redirect <address: string>
44598
 
+ */
44599
 
+
44600
 
+static bool cmd_redirect_validate
44601
 
+       (struct sieve_validator *validator, struct sieve_command_context *cmd);
44602
 
+static bool cmd_redirect_generate
44603
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx);
44604
 
+
44605
 
+const struct sieve_command cmd_redirect = { 
44606
 
+       "redirect", 
44607
 
+       SCT_COMMAND,
44608
 
+       1, 0, FALSE, FALSE, 
44609
 
+       NULL, NULL,
44610
 
+       cmd_redirect_validate, 
44611
 
+       cmd_redirect_generate, 
44612
 
+       NULL 
44613
 
+};
44614
 
+
44615
 
+/* 
44616
 
+ * Redirect operation 
44617
 
+ */
44618
 
+
44619
 
+static bool cmd_redirect_operation_dump
44620
 
+       (const struct sieve_operation *op,
44621
 
+               const struct sieve_dumptime_env *denv, sieve_size_t *address);
44622
 
+static int cmd_redirect_operation_execute
44623
 
+       (const struct sieve_operation *op, 
44624
 
+               const struct sieve_runtime_env *renv, sieve_size_t *address);
44625
 
+
44626
 
+const struct sieve_operation cmd_redirect_operation = { 
44627
 
+       "REDIRECT",
44628
 
+       NULL, 
44629
 
+       SIEVE_OPERATION_REDIRECT,
44630
 
+       cmd_redirect_operation_dump, 
44631
 
+       cmd_redirect_operation_execute 
44632
 
+};
44633
 
+
44634
 
+/* 
44635
 
+ * Redirect action 
44636
 
+ */
44637
 
+
44638
 
+static bool act_redirect_equals
44639
 
+       (const struct sieve_script_env *senv, const void *ctx1, const void *ctx2);
44640
 
+static int act_redirect_check_duplicate
44641
 
+       (const struct sieve_runtime_env *renv,
44642
 
+               const struct sieve_action_data *act, 
44643
 
+               const struct sieve_action_data *act_other);
44644
 
+static void act_redirect_print
44645
 
+       (const struct sieve_action *action, const struct sieve_result_print_env *rpenv,
44646
 
+               void *context, bool *keep);     
44647
 
+static bool act_redirect_commit
44648
 
+       (const struct sieve_action *action, const struct sieve_action_exec_env *aenv,
44649
 
+               void *tr_context, bool *keep);
44650
 
+               
44651
 
+const struct sieve_action act_redirect = {
44652
 
+       "redirect",
44653
 
+       SIEVE_ACTFLAG_TRIES_DELIVER,
44654
 
+       act_redirect_equals,
44655
 
+       act_redirect_check_duplicate, 
44656
 
+       NULL,
44657
 
+       act_redirect_print,
44658
 
+       NULL, NULL,
44659
 
+       act_redirect_commit,
44660
 
+       NULL
44661
 
+};
44662
 
+
44663
 
+struct act_redirect_context {
44664
 
+       const char *to_address;
44665
 
+};
44666
 
+
44667
 
+/* 
44668
 
+ * Validation 
44669
 
+ */
44670
 
+
44671
 
+static bool cmd_redirect_validate
44672
 
+(struct sieve_validator *validator, struct sieve_command_context *cmd) 
44673
 
+{
44674
 
+       struct sieve_ast_argument *arg = cmd->first_positional;
44675
 
+
44676
 
+       /* Check and activate address argument */
44677
 
+
44678
 
+       if ( !sieve_validate_positional_argument
44679
 
+               (validator, cmd, arg, "address", 1, SAAT_STRING) ) {
44680
 
+               return FALSE;
44681
 
+       }
44682
 
+       
44683
 
+       if ( !sieve_validator_argument_activate(validator, cmd, arg, FALSE) )
44684
 
+               return FALSE;
44685
 
+
44686
 
+       /* We can only assess the validity of the outgoing address when it is 
44687
 
+        * a string literal. For runtime-generated strings this needs to be 
44688
 
+        * done at runtime (FIXME!)
44689
 
+     */
44690
 
+       if ( sieve_argument_is_string_literal(arg) ) {
44691
 
+               string_t *address = sieve_ast_argument_str(arg);
44692
 
+               const char *error;
44693
 
+               const char *norm_address;
44694
 
+
44695
 
+               T_BEGIN {
44696
 
+                       /* Verify and normalize the address to 'local_part@domain' */
44697
 
+                       norm_address = sieve_address_normalize(address, &error);
44698
 
+               
44699
 
+                       if ( norm_address == NULL ) {
44700
 
+                               sieve_argument_validate_error(validator, arg, 
44701
 
+                                       "specified redirect address '%s' is invalid: %s",
44702
 
+                                       str_sanitize(str_c(address),128), error);
44703
 
+                       } else {
44704
 
+                               /* Replace string literal in AST */
44705
 
+                               sieve_ast_argument_string_setc(arg, norm_address);
44706
 
+                       }
44707
 
+               } T_END;
44708
 
+
44709
 
+               return ( norm_address != NULL );
44710
 
+       }               
44711
 
+
44712
 
+       return TRUE;
44713
 
+}
44714
 
+
44715
 
+/*
44716
 
+ * Code generation
44717
 
+ */
44718
 
44719
 
+static bool cmd_redirect_generate
44720
 
+(const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx) 
44721
 
+{
44722
 
+       sieve_operation_emit_code(cgenv->sbin, &cmd_redirect_operation);
44723
 
+
44724
 
+       /* Emit line number */
44725
 
+       sieve_code_source_line_emit(cgenv->sbin, sieve_command_source_line(ctx));
44726
 
+
44727
 
+       /* Generate arguments */
44728
 
+       return sieve_generate_arguments(cgenv, ctx, NULL);
44729
 
+}
44730
 
+
44731
 
+/* 
44732
 
+ * Code dump
44733
 
+ */
44734
 
44735
 
+static bool cmd_redirect_operation_dump
44736
 
+(const struct sieve_operation *op ATTR_UNUSED,
44737
 
+       const struct sieve_dumptime_env *denv, sieve_size_t *address)
44738
 
+{
44739
 
+       sieve_code_dumpf(denv, "REDIRECT");
44740
 
+       sieve_code_descend(denv);
44741
 
+
44742
 
+       /* Source line */
44743
 
+    if ( !sieve_code_source_line_dump(denv, address) )
44744
 
+        return FALSE;
44745
 
+
44746
 
+       if ( !sieve_code_dumper_print_optional_operands(denv, address) )
44747
 
+               return FALSE;
44748
 
+
44749
 
+       return sieve_opr_string_dump(denv, address, "reason");
44750
 
+}
44751
 
+
44752
 
+/*
44753
 
+ * Intepretation
44754
 
+ */
44755
 
+
44756
 
+static int cmd_redirect_operation_execute
44757
 
+(const struct sieve_operation *op ATTR_UNUSED,
44758
 
+       const struct sieve_runtime_env *renv, sieve_size_t *address)
44759
 
+{
44760
 
+       struct sieve_side_effects_list *slist = NULL;
44761
 
+       struct act_redirect_context *act;
44762
 
+       string_t *redirect;
44763
 
+       unsigned int source_line;
44764
 
+       pool_t pool;
44765
 
+       int ret = 0;
44766
 
+
44767
 
+       /* Source line */
44768
 
+    if ( !sieve_code_source_line_read(renv, address, &source_line) ) {
44769
 
+               sieve_runtime_trace_error(renv, "invalid source line");
44770
 
+        return SIEVE_EXEC_BIN_CORRUPT;
44771
 
+       }
44772
 
+
44773
 
+       /* Optional operands (side effects) */
44774
 
+       if ( (ret=sieve_interpreter_handle_optional_operands
44775
 
+               (renv, address, &slist)) <= 0 )
44776
 
+               return ret;
44777
 
+
44778
 
+       /* Read the address */
44779
 
+       if ( !sieve_opr_string_read(renv, address, &redirect) ) {
44780
 
+               sieve_runtime_trace_error(renv, "invalid address string");
44781
 
+               return SIEVE_EXEC_BIN_CORRUPT;
44782
 
+       }
44783
 
+
44784
 
+       /* FIXME: perform address normalization if the string is not a string literal
44785
 
+        */
44786
 
+
44787
 
+       sieve_runtime_trace(renv, "REDIRECT action (\"%s\")", str_sanitize(str_c(redirect), 64));
44788
 
+       
44789
 
+       /* Add redirect action to the result */
44790
 
+
44791
 
+       pool = sieve_result_pool(renv->result);
44792
 
+       act = p_new(pool, struct act_redirect_context, 1);
44793
 
+       act->to_address = p_strdup(pool, str_c(redirect));
44794
 
+       
44795
 
+       ret = sieve_result_add_action
44796
 
+               (renv, &act_redirect, slist, source_line, (void *) act, sieve_max_redirects);
44797
 
+       
44798
 
+       return ( ret >= 0 );
44799
 
+}
44800
 
+
44801
 
+/*
44802
 
+ * Action implementation
44803
 
+ */
44804
 
+
44805
 
+static bool act_redirect_equals
44806
 
+(const struct sieve_script_env *senv ATTR_UNUSED, 
44807
 
+       const void *ctx1, const void *ctx2)
44808
 
+{
44809
 
+       struct act_redirect_context *rd_ctx1 = 
44810
 
+               (struct act_redirect_context *) ctx1;
44811
 
+       struct act_redirect_context *rd_ctx2 = 
44812
 
+               (struct act_redirect_context *) ctx2;
44813
 
+
44814
 
+       /* Address is already normalized */
44815
 
+       return ( sieve_address_compare
44816
 
+               (rd_ctx1->to_address, rd_ctx2->to_address, TRUE) == 0 );
44817
 
+}
44818
 
44819
 
+static int act_redirect_check_duplicate
44820
 
+(const struct sieve_runtime_env *renv ATTR_UNUSED,
44821
 
+       const struct sieve_action_data *act, 
44822
 
+       const struct sieve_action_data *act_other)
44823
 
+{
44824
 
+       return ( act_redirect_equals
44825
 
+               (renv->scriptenv, act->context, act_other->context) ? 1 : 0 );
44826
 
+}
44827
 
+
44828
 
+static void act_redirect_print
44829
 
+(const struct sieve_action *action ATTR_UNUSED, 
44830
 
+       const struct sieve_result_print_env *rpenv, void *context, bool *keep)  
44831
 
+{
44832
 
+       struct act_redirect_context *ctx = (struct act_redirect_context *) context;
44833
 
+       
44834
 
+       sieve_result_action_printf(rpenv, "redirect message to: %s", 
44835
 
+               str_sanitize(ctx->to_address, 128));
44836
 
+       
44837
 
+       *keep = FALSE;
44838
 
+}
44839
 
+
44840
 
+static bool act_redirect_send  
44841
 
+(const struct sieve_action_exec_env *aenv, struct act_redirect_context *ctx)
44842
 
+{
44843
 
+       static const char *hide_headers[] = { "Return-Path", "X-Sieve" };
44844
 
+
44845
 
+       const struct sieve_message_data *msgdata = aenv->msgdata;
44846
 
+       const struct sieve_script_env *senv = aenv->scriptenv;
44847
 
+       const char *sender = sieve_message_get_sender(aenv->msgctx);
44848
 
+       struct istream *input, *crlf_input;
44849
 
+       void *smtp_handle;
44850
 
+       FILE *f;
44851
 
+       const unsigned char *data;
44852
 
+       size_t size;
44853
 
+       int ret;
44854
 
+       
44855
 
+       /* Just to be sure */
44856
 
+       if ( senv->smtp_open == NULL || senv->smtp_close == NULL ) {
44857
 
+               sieve_result_warning(aenv, "redirect action has no means to send mail.");
44858
 
+               return TRUE;
44859
 
+       }
44860
 
+       
44861
 
+       if (mail_get_stream(msgdata->mail, NULL, NULL, &input) < 0)
44862
 
+               return FALSE;
44863
 
+               
44864
 
+       /* Open SMTP transport */
44865
 
+       smtp_handle = senv->smtp_open(ctx->to_address, sender, &f);
44866
 
+
44867
 
+       /* Remove unwanted headers */
44868
 
+       input = i_stream_create_header_filter
44869
 
+               (input, HEADER_FILTER_EXCLUDE, hide_headers,
44870
 
+                       N_ELEMENTS(hide_headers), null_header_filter_callback, NULL);
44871
 
+       
44872
 
+       /* Make sure the message contains CRLF consistently */
44873
 
+       crlf_input = i_stream_create_crlf(input);
44874
 
+
44875
 
+       /* Prepend sieve version header (should not affect signatures) */
44876
 
+       rfc2822_header_field_write(f, "X-Sieve", SIEVE_IMPLEMENTATION);
44877
 
+
44878
 
+       /* Pipe the message to the outgoing SMTP transport */
44879
 
+       while ((ret = i_stream_read_data(crlf_input, &data, &size, 0)) > 0) {   
44880
 
+               if (fwrite(data, size, 1, f) == 0)
44881
 
+                       break;
44882
 
+               i_stream_skip(crlf_input, size);
44883
 
+       }
44884
 
+
44885
 
+       i_stream_unref(&crlf_input);
44886
 
+       i_stream_unref(&input);
44887
 
+
44888
 
+       /* Close SMTP transport */
44889
 
+       if ( !senv->smtp_close(smtp_handle) ) {
44890
 
+               sieve_result_error(aenv, 
44891
 
+                       "failed to redirect message to <%s> "
44892
 
+                       "(refer to server log for more information)",
44893
 
+                       str_sanitize(ctx->to_address, 80));
44894
 
+               return FALSE;
44895
 
+       }
44896
 
+       
44897
 
+       return TRUE;
44898
 
+}
44899
 
+
44900
 
+static bool act_redirect_commit
44901
 
+(const struct sieve_action *action ATTR_UNUSED, 
44902
 
+       const struct sieve_action_exec_env *aenv, void *tr_context, bool *keep)
44903
 
+{
44904
 
+       struct act_redirect_context *ctx = (struct act_redirect_context *) tr_context;
44905
 
+       const struct sieve_message_data *msgdata = aenv->msgdata;
44906
 
+       const struct sieve_script_env *senv = aenv->scriptenv;
44907
 
+       const char *dupeid;
44908
 
+       
44909
 
+       /* Prevent mail loops if possible */
44910
 
+       dupeid = msgdata->id == NULL ? 
44911
 
+               NULL : t_strdup_printf("%s-%s", msgdata->id, ctx->to_address);
44912
 
+       if (dupeid != NULL) {
44913
 
+               /* Check whether we've seen this message before */
44914
 
+               if (senv->duplicate_check(dupeid, strlen(dupeid), senv->username)) {
44915
 
+                       sieve_result_log(aenv, "discarded duplicate forward to <%s>",
44916
 
+                               str_sanitize(ctx->to_address, 128));
44917
 
+                       return TRUE;
44918
 
+               }
44919
 
+       }
44920
 
+       
44921
 
+       /* Try to forward the message */
44922
 
+       if ( act_redirect_send(aenv, ctx) ) {
44923
 
+       
44924
 
+               /* Mark this message id as forwarded to the specified destination */
44925
 
+               if (dupeid != NULL) {
44926
 
+                       senv->duplicate_mark(dupeid, strlen(dupeid), senv->username,
44927
 
+                               ioloop_time + CMD_REDIRECT_DUPLICATE_KEEP);
44928
 
+               }
44929
 
+       
44930
 
+               sieve_result_log(aenv, "forwarded to <%s>", 
44931
 
+                       str_sanitize(ctx->to_address, 128));    
44932
 
+
44933
 
+               /* Indicate that message was successfully forwarded */
44934
 
+               aenv->exec_status->message_forwarded = TRUE;
44935
 
+
44936
 
+               /* Cancel implicit keep */
44937
 
+               *keep = FALSE;
44938
 
+
44939
 
+               return TRUE;
44940
 
+       }
44941
 
+  
44942
 
+       return FALSE;
44943
 
+}
44944
 
+
44945
 
+
44946
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/cmd-require.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/cmd-require.c
44947
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/cmd-require.c  1970-01-01 01:00:00.000000000 +0100
44948
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/cmd-require.c   2009-04-18 09:54:24.000000000 +0200
44949
 
@@ -0,0 +1,86 @@
44950
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
44951
 
+ */
44952
 
+
44953
 
+#include "lib.h"
44954
 
+
44955
 
+#include "sieve-common.h"
44956
 
+#include "sieve-commands.h"
44957
 
+#include "sieve-extensions.h"
44958
 
+#include "sieve-validator.h" 
44959
 
+#include "sieve-generator.h"
44960
 
+
44961
 
+/* 
44962
 
+ * Require command
44963
 
+ *
44964
 
+ * Syntax 
44965
 
+ *   Syntax: require <capabilities: string-list>
44966
 
+ */
44967
 
+
44968
 
+static bool cmd_require_validate
44969
 
+       (struct sieve_validator *validator, struct sieve_command_context *cmd);
44970
 
+
44971
 
+const struct sieve_command cmd_require = { 
44972
 
+       "require", 
44973
 
+       SCT_COMMAND, 
44974
 
+       1, 0, FALSE, FALSE,
44975
 
+       NULL, NULL, 
44976
 
+       cmd_require_validate, 
44977
 
+       NULL, NULL
44978
 
+};
44979
 
44980
 
+/* 
44981
 
+ * Validation 
44982
 
+ */
44983
 
+
44984
 
+static bool cmd_require_validate
44985
 
+       (struct sieve_validator *validator, struct sieve_command_context *cmd) 
44986
 
+{
44987
 
+       bool result = TRUE;
44988
 
+       struct sieve_ast_argument *arg;
44989
 
+       struct sieve_command_context *prev_context = 
44990
 
+               sieve_command_prev_context(cmd);
44991
 
+       
44992
 
+       /* Check valid command placement */
44993
 
+       if ( !sieve_command_is_toplevel(cmd) ||
44994
 
+               ( !sieve_command_is_first(cmd) && prev_context != NULL &&
44995
 
+                       prev_context->command != &cmd_require ) ) 
44996
 
+       {       
44997
 
+               sieve_command_validate_error(validator, cmd, 
44998
 
+                       "require commands can only be placed at top level "
44999
 
+                       "at the beginning of the file");
45000
 
+               return FALSE;
45001
 
+       }
45002
 
+       
45003
 
+       /* Check argument and load specified extension(s) */
45004
 
+
45005
 
+       arg = cmd->first_positional;
45006
 
+       if ( sieve_ast_argument_type(arg) == SAAT_STRING ) {
45007
 
+               /* Single string */
45008
 
+               const struct sieve_extension *ext = sieve_validator_extension_load
45009
 
+                       (validator, cmd, arg, sieve_ast_argument_str(arg));     
45010
 
+
45011
 
+               if ( ext == NULL ) result = FALSE;
45012
 
+               
45013
 
+       } else if ( sieve_ast_argument_type(arg) == SAAT_STRING_LIST ) {
45014
 
+               /* String list */
45015
 
+               struct sieve_ast_argument *stritem = sieve_ast_strlist_first(arg);
45016
 
+               
45017
 
+               while ( stritem != NULL ) {
45018
 
+                       const struct sieve_extension *ext = sieve_validator_extension_load
45019
 
+                               (validator, cmd, stritem, sieve_ast_strlist_str(stritem));
45020
 
+
45021
 
+                       if ( ext == NULL ) result = FALSE;
45022
 
+       
45023
 
+                       stritem = sieve_ast_strlist_next(stritem);
45024
 
+               }
45025
 
+       } else {
45026
 
+               /* Something else */
45027
 
+               sieve_argument_validate_error(validator, arg, 
45028
 
+                       "the require command accepts a single string or string list argument, "
45029
 
+                       "but %s was found", 
45030
 
+                       sieve_ast_argument_name(arg));
45031
 
+               return FALSE;
45032
 
+       }
45033
 
+        
45034
 
+       return result;
45035
 
+}
45036
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/cmd-stop.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/cmd-stop.c
45037
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/cmd-stop.c     1970-01-01 01:00:00.000000000 +0100
45038
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/cmd-stop.c      2009-01-06 00:15:52.000000000 +0100
45039
 
@@ -0,0 +1,90 @@
45040
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
45041
 
+ */
45042
 
+
45043
 
+#include "sieve-common.h"
45044
 
+#include "sieve-commands.h"
45045
 
+#include "sieve-code.h"
45046
 
+#include "sieve-generator.h"
45047
 
+#include "sieve-interpreter.h"
45048
 
+
45049
 
+/* 
45050
 
+ * Stop command 
45051
 
+ * 
45052
 
+ * Syntax
45053
 
+ *   stop
45054
 
+ */    
45055
 
+
45056
 
+static bool cmd_stop_generate
45057
 
+       (const struct sieve_codegen_env *cgenv, 
45058
 
+               struct sieve_command_context *ctx ATTR_UNUSED);
45059
 
+static bool cmd_stop_validate
45060
 
+       (struct sieve_validator *validator, struct sieve_command_context *ctx);
45061
 
+       
45062
 
+const struct sieve_command cmd_stop = { 
45063
 
+       "stop", 
45064
 
+       SCT_COMMAND, 
45065
 
+       0, 0, FALSE, FALSE,
45066
 
+       NULL, NULL,  
45067
 
+       cmd_stop_validate, 
45068
 
+       cmd_stop_generate, 
45069
 
+       NULL 
45070
 
+};
45071
 
+
45072
 
+/* 
45073
 
+ * Stop operation
45074
 
+ */
45075
 
+
45076
 
+static int opc_stop_execute
45077
 
+       (const struct sieve_operation *op, 
45078
 
+               const struct sieve_runtime_env *renv, sieve_size_t *address);
45079
 
+
45080
 
+const struct sieve_operation cmd_stop_operation = { 
45081
 
+       "STOP",
45082
 
+       NULL,
45083
 
+       SIEVE_OPERATION_STOP,
45084
 
+       NULL, 
45085
 
+       opc_stop_execute 
45086
 
+};
45087
 
+
45088
 
+/*
45089
 
+ * Command validation
45090
 
+ */
45091
 
45092
 
+static bool cmd_stop_validate
45093
 
+(struct sieve_validator *validator ATTR_UNUSED, 
45094
 
+       struct sieve_command_context *ctx)
45095
 
+{
45096
 
+       sieve_command_exit_block_unconditionally(ctx);
45097
 
+       
45098
 
+       return TRUE;
45099
 
+}
45100
 
+
45101
 
+/*
45102
 
+ * Code generation
45103
 
+ */
45104
 
+
45105
 
+static bool cmd_stop_generate
45106
 
+(const struct sieve_codegen_env *cgenv, 
45107
 
+       struct sieve_command_context *ctx ATTR_UNUSED) 
45108
 
+{
45109
 
+       sieve_operation_emit_code(cgenv->sbin, &cmd_stop_operation);
45110
 
+
45111
 
+       return TRUE;
45112
 
+}
45113
 
+
45114
 
+/*
45115
 
+ * Code execution
45116
 
+ */
45117
 
+
45118
 
+static int opc_stop_execute
45119
 
+(const struct sieve_operation *op ATTR_UNUSED, 
45120
 
+       const struct sieve_runtime_env *renv,  
45121
 
+       sieve_size_t *address ATTR_UNUSED)
45122
 
+{      
45123
 
+       sieve_runtime_trace(renv, "STOP");
45124
 
+       
45125
 
+       sieve_interpreter_interrupt(renv->interp);
45126
 
+
45127
 
+       return SIEVE_EXEC_OK;
45128
 
+}
45129
 
+
45130
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/cmp-i-ascii-casemap.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/cmp-i-ascii-casemap.c
45131
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/cmp-i-ascii-casemap.c  1970-01-01 01:00:00.000000000 +0100
45132
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/cmp-i-ascii-casemap.c   2009-01-06 00:15:52.000000000 +0100
45133
 
@@ -0,0 +1,96 @@
45134
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file 
45135
 
+ */
45136
 
+
45137
 
+/* Comparator 'i;ascii-casemap': 
45138
 
+ *
45139
 
+ */
45140
 
+
45141
 
+#include "lib.h"
45142
 
+
45143
 
+#include "sieve-common.h"
45144
 
+#include "sieve-comparators.h"
45145
 
+
45146
 
+#include <string.h>
45147
 
+#include <stdio.h>
45148
 
+#include <ctype.h>
45149
 
+
45150
 
+/*
45151
 
+ * Forward declarations
45152
 
+ */
45153
 
45154
 
+static int cmp_i_ascii_casemap_compare
45155
 
+       (const struct sieve_comparator *cmp,
45156
 
+               const char *val1, size_t val1_size, const char *val2, size_t val2_size);
45157
 
+static bool cmp_i_ascii_casemap_char_match
45158
 
+       (const struct sieve_comparator *cmp, const char **val1, const char *val1_end, 
45159
 
+               const char **val2, const char *val2_end);
45160
 
+
45161
 
+/*
45162
 
+ * Comparator object
45163
 
+ */
45164
 
45165
 
+const struct sieve_comparator i_ascii_casemap_comparator = {
45166
 
+       SIEVE_OBJECT
45167
 
+               ("i;ascii-casemap", &comparator_operand, SIEVE_COMPARATOR_I_ASCII_CASEMAP),
45168
 
+       SIEVE_COMPARATOR_FLAG_ORDERING | SIEVE_COMPARATOR_FLAG_EQUALITY |
45169
 
+               SIEVE_COMPARATOR_FLAG_SUBSTRING_MATCH | SIEVE_COMPARATOR_FLAG_PREFIX_MATCH,
45170
 
+       cmp_i_ascii_casemap_compare,
45171
 
+       cmp_i_ascii_casemap_char_match,
45172
 
+       sieve_comparator_octet_skip
45173
 
+};
45174
 
+
45175
 
+/*
45176
 
+ * Comparator implementation
45177
 
+ */
45178
 
+
45179
 
+static int cmp_i_ascii_casemap_compare(
45180
 
+       const struct sieve_comparator *cmp ATTR_UNUSED,
45181
 
+       const char *val1, size_t val1_size, const char *val2, size_t val2_size)
45182
 
+{
45183
 
+       int result;
45184
 
+
45185
 
+       if ( val1_size == val2_size ) {
45186
 
+               return strncasecmp(val1, val2, val1_size);
45187
 
+       } 
45188
 
+       
45189
 
+       if ( val1_size > val2_size ) {
45190
 
+               result = strncasecmp(val1, val2, val2_size);
45191
 
+               
45192
 
+               if ( result == 0 ) return 1;
45193
 
+               
45194
 
+               return result;
45195
 
+       } 
45196
 
+
45197
 
+       result = strncasecmp(val1, val2, val1_size);
45198
 
+               
45199
 
+       if ( result == 0 ) return -1;
45200
 
+               
45201
 
+       return result;
45202
 
+}
45203
 
+
45204
 
+static bool cmp_i_ascii_casemap_char_match
45205
 
+       (const struct sieve_comparator *cmp ATTR_UNUSED, 
45206
 
+               const char **val, const char *val_end, 
45207
 
+               const char **key, const char *key_end)
45208
 
+{
45209
 
+       const char *val_begin = *val;
45210
 
+       const char *key_begin = *key;
45211
 
+       
45212
 
+       while ( i_tolower(**val) == i_tolower(**key) &&
45213
 
+               *val < val_end && *key < key_end ) {
45214
 
+               (*val)++;
45215
 
+               (*key)++;
45216
 
+       }
45217
 
+       
45218
 
+       if ( *key < key_end ) {
45219
 
+               /* Reset */
45220
 
+               *val = val_begin;
45221
 
+               *key = key_begin;       
45222
 
+               
45223
 
+               return FALSE;
45224
 
+       }
45225
 
+       
45226
 
+       return TRUE;
45227
 
+}
45228
 
+
45229
 
+
45230
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/cmp-i-octet.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/cmp-i-octet.c
45231
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/cmp-i-octet.c  1970-01-01 01:00:00.000000000 +0100
45232
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/cmp-i-octet.c   2009-01-06 00:15:52.000000000 +0100
45233
 
@@ -0,0 +1,93 @@
45234
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file 
45235
 
+ */
45236
 
+
45237
 
+/* Comparator 'i;octet': 
45238
 
+ *
45239
 
+ */
45240
 
+
45241
 
+#include "lib.h"
45242
 
+
45243
 
+#include "sieve-common.h"
45244
 
+#include "sieve-comparators.h"
45245
 
+
45246
 
+#include <string.h>
45247
 
+#include <stdio.h>
45248
 
+
45249
 
+/*
45250
 
+ * Forward declarations
45251
 
+ */
45252
 
+
45253
 
+static int cmp_i_octet_compare
45254
 
+       (const struct sieve_comparator *cmp,
45255
 
+               const char *val1, size_t val1_size, const char *val2, size_t val2_size);
45256
 
+static bool cmp_i_octet_char_match
45257
 
+       (const struct sieve_comparator *cmp, const char **val1, const char *val1_end, 
45258
 
+               const char **val2, const char *val2_end);
45259
 
+
45260
 
+/*
45261
 
+ * Comparator object
45262
 
+ */
45263
 
+
45264
 
+const struct sieve_comparator i_octet_comparator = {
45265
 
+       SIEVE_OBJECT("i;octet", &comparator_operand, SIEVE_COMPARATOR_I_OCTET),
45266
 
+       SIEVE_COMPARATOR_FLAG_ORDERING | SIEVE_COMPARATOR_FLAG_EQUALITY |
45267
 
+               SIEVE_COMPARATOR_FLAG_SUBSTRING_MATCH | SIEVE_COMPARATOR_FLAG_PREFIX_MATCH,
45268
 
+       cmp_i_octet_compare,
45269
 
+       cmp_i_octet_char_match,
45270
 
+       sieve_comparator_octet_skip     
45271
 
+};
45272
 
+
45273
 
+/*
45274
 
+ * Comparator implementation
45275
 
+ */
45276
 
45277
 
+static int cmp_i_octet_compare(
45278
 
+       const struct sieve_comparator *cmp ATTR_UNUSED,
45279
 
+       const char *val1, size_t val1_size, const char *val2, size_t val2_size)
45280
 
+{
45281
 
+       int result;
45282
 
+
45283
 
+       if ( val1_size == val2_size ) {
45284
 
+               return memcmp((void *) val1, (void *) val2, val1_size);
45285
 
+       } 
45286
 
+       
45287
 
+       if ( val1_size > val2_size ) {
45288
 
+               result = memcmp((void *) val1, (void *) val2, val2_size);
45289
 
+               
45290
 
+               if ( result == 0 ) return 1;
45291
 
+               
45292
 
+               return result;
45293
 
+       } 
45294
 
+
45295
 
+       result = memcmp((void *) val1, (void *) val2, val1_size);
45296
 
+               
45297
 
+       if ( result == 0 ) return -1;
45298
 
+               
45299
 
+       return result;
45300
 
+}
45301
 
+
45302
 
+static bool cmp_i_octet_char_match
45303
 
+       (const struct sieve_comparator *cmp ATTR_UNUSED, 
45304
 
+               const char **val, const char *val_end, 
45305
 
+               const char **key, const char *key_end)
45306
 
+{
45307
 
+       const char *val_begin = *val;
45308
 
+       const char *key_begin = *key;
45309
 
+       
45310
 
+       while ( **val == **key && *val < val_end && *key < key_end ) {
45311
 
+               (*val)++;
45312
 
+               (*key)++;
45313
 
+       }
45314
 
+       
45315
 
+       if ( *key < key_end ) {
45316
 
+               /* Reset */
45317
 
+               *val = val_begin;
45318
 
+               *key = key_begin;       
45319
 
+       
45320
 
+               return FALSE;
45321
 
+       }
45322
 
+       
45323
 
+       return TRUE;
45324
 
+}
45325
 
45326
 
45327
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/ext-encoded-character.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/ext-encoded-character.c
45328
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/ext-encoded-character.c        1970-01-01 01:00:00.000000000 +0100
45329
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/ext-encoded-character.c 2009-01-06 00:15:52.000000000 +0100
45330
 
@@ -0,0 +1,280 @@
45331
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
45332
 
+ */
45333
 
+
45334
 
+/* Extension encoded-character 
45335
 
+ * ---------------------------
45336
 
+ *
45337
 
+ * Authors: Stephan Bosch
45338
 
+ * Specification: RFC5228
45339
 
+ * Implementation: full 
45340
 
+ * Status: experimental, largely untested
45341
 
+ *
45342
 
+ */
45343
 
+
45344
 
+#include "lib.h"
45345
 
+#include "unichar.h"
45346
 
+
45347
 
+#include "sieve-extensions.h"
45348
 
+#include "sieve-commands.h"
45349
 
+#include "sieve-validator.h"
45350
 
+
45351
 
+#include <ctype.h>
45352
 
+
45353
 
+/* 
45354
 
+ * Extension
45355
 
+ */
45356
 
+
45357
 
+static bool ext_encoded_character_validator_load
45358
 
+       (struct sieve_validator *validator);
45359
 
+
45360
 
+static int ext_my_id = -1;
45361
 
+       
45362
 
+struct sieve_extension encoded_character_extension = { 
45363
 
+       "encoded-character", 
45364
 
+       &ext_my_id,
45365
 
+       NULL, NULL,
45366
 
+       ext_encoded_character_validator_load, 
45367
 
+       NULL, NULL, NULL, NULL, NULL,
45368
 
+       SIEVE_EXT_DEFINE_NO_OPERATIONS, 
45369
 
+       SIEVE_EXT_DEFINE_NO_OPERANDS
45370
 
+};
45371
 
+
45372
 
+/*
45373
 
+ * Encoded string argument
45374
 
+ */
45375
 
+
45376
 
+bool arg_encoded_string_validate
45377
 
+       (struct sieve_validator *validator, struct sieve_ast_argument **arg, 
45378
 
+               struct sieve_command_context *context);
45379
 
+
45380
 
+const struct sieve_argument encoded_string_argument = { 
45381
 
+       "@encoded-string", 
45382
 
+       NULL, NULL,
45383
 
+       arg_encoded_string_validate, 
45384
 
+       NULL, NULL 
45385
 
+};
45386
 
+
45387
 
+/* Parsing */
45388
 
+
45389
 
+static bool _skip_whitespace
45390
 
+       (const char **in, const char *inend)
45391
 
+{
45392
 
+       while ( *in < inend ) {
45393
 
+               if ( **in == '\r' ) {
45394
 
+                       (*in)++;
45395
 
+                       if ( **in != '\n' )
45396
 
+                               return FALSE;
45397
 
+                       continue;
45398
 
+               }
45399
 
+               
45400
 
+               /* (Loose LF is non-standard) */
45401
 
+               if ( **in != ' ' && **in != '\n' && **in != '\t' ) 
45402
 
+                       break;
45403
 
+                       
45404
 
+               (*in)++;
45405
 
+       }
45406
 
+       
45407
 
+       return TRUE;
45408
 
+}
45409
 
+
45410
 
+static bool _parse_hexint
45411
 
+(const char **in, const char *inend, int max_digits, unsigned int *result)
45412
 
+{
45413
 
+       int digit = 0;
45414
 
+       *result = 0;
45415
 
+               
45416
 
+       while ( *in < inend && (max_digits == 0 || digit < max_digits) ) {
45417
 
+       
45418
 
+               if ( (**in) >= '0' && (**in) <= '9' ) 
45419
 
+                       *result = ((*result) << 4) + (**in) - ((unsigned int) '0');
45420
 
+               else if ( (**in) >= 'a' && (**in) <= 'f' )
45421
 
+                       *result = ((*result) << 4) + (**in) - ((unsigned int) 'a') + 0x0a;
45422
 
+               else if ( (**in) >= 'A' && (**in) <= 'F' )
45423
 
+                       *result = ((*result) << 4) + (**in) - ((unsigned int) 'A') + 0x0a;
45424
 
+               else
45425
 
+                       return ( digit > 0 );
45426
 
+       
45427
 
+               (*in)++;
45428
 
+               digit++;
45429
 
+       }
45430
 
+       
45431
 
+       if ( digit == max_digits ) {
45432
 
+               /* Hex digit _MUST_ end here */
45433
 
+               if ( (**in >= '0' && **in <= '9')       || (**in >= 'a' && **in <= 'f') ||
45434
 
+                       (**in >= 'A' && **in <= 'F') )
45435
 
+                       return FALSE;
45436
 
+                       
45437
 
+               return TRUE;
45438
 
+       }
45439
 
+       
45440
 
+       return ( digit > 0 );
45441
 
+}
45442
 
+
45443
 
+static bool _decode_hex
45444
 
+(const char **in, const char *inend, string_t *result) 
45445
 
+{
45446
 
+       int values = 0;
45447
 
+       
45448
 
+       while ( *in < inend ) {
45449
 
+               unsigned int hexpair;
45450
 
+               
45451
 
+               if ( !_skip_whitespace(in, inend) ) return FALSE;
45452
 
+               
45453
 
+               if ( !_parse_hexint(in, inend, 2, &hexpair) ) break;
45454
 
+               
45455
 
+               str_append_c(result, (unsigned char) hexpair);
45456
 
+               values++;
45457
 
+       }
45458
 
+       
45459
 
+       return ( values > 0 );
45460
 
+}
45461
 
+
45462
 
+static int _decode_unicode
45463
 
+(const char **in, const char *inend, string_t *result, unsigned int *error_hex) 
45464
 
+{
45465
 
+       int values = 0;
45466
 
+       bool valid = TRUE;
45467
 
+       
45468
 
+       while ( *in < inend ) {
45469
 
+               unsigned int unicode_hex;
45470
 
+               
45471
 
+               if ( !_skip_whitespace(in, inend) ) return FALSE;
45472
 
+               
45473
 
+               if ( !_parse_hexint(in, inend, 0, &unicode_hex) ) break;
45474
 
+
45475
 
+               if ( (unicode_hex <= 0xD7FF) || 
45476
 
+                       (unicode_hex >= 0xE000 && unicode_hex <= 0x10FFFF)      ) 
45477
 
+                       uni_ucs4_to_utf8_c((unichar_t) unicode_hex, result);
45478
 
+               else {
45479
 
+                       if ( valid ) *error_hex = unicode_hex;
45480
 
+                       valid = FALSE;
45481
 
+               }       
45482
 
+               values++;
45483
 
+       }
45484
 
+       
45485
 
+       return ( values > 0 );
45486
 
+}
45487
 
+
45488
 
+bool arg_encoded_string_validate
45489
 
+(struct sieve_validator *validator, struct sieve_ast_argument **arg, 
45490
 
+               struct sieve_command_context *cmd)
45491
 
+{
45492
 
+       bool result = TRUE;
45493
 
+       enum { ST_NONE, ST_OPEN, ST_TYPE, ST_CLOSE } 
45494
 
+               state = ST_NONE;
45495
 
+       string_t *str = sieve_ast_argument_str(*arg);
45496
 
+       string_t *tmpstr, *newstr = NULL;
45497
 
+       const char *p, *mark, *strstart, *substart = NULL;
45498
 
+       const char *strval = (const char *) str_data(str);
45499
 
+       const char *strend = strval + str_len(str);
45500
 
+       unsigned int error_hex = 0;
45501
 
+
45502
 
+       T_BEGIN {               
45503
 
+               tmpstr = t_str_new(32); 
45504
 
+                       
45505
 
+               p = strval;
45506
 
+               strstart = p;
45507
 
+               while ( result && p < strend ) {
45508
 
+                       switch ( state ) {
45509
 
+                       /* Normal string */
45510
 
+                       case ST_NONE:
45511
 
+                               if ( *p == '$' ) {
45512
 
+                                       substart = p;
45513
 
+                                       state = ST_OPEN;
45514
 
+                               }
45515
 
+                               p++;
45516
 
+                               break;
45517
 
+                       /* Parsed '$' */
45518
 
+                       case ST_OPEN:
45519
 
+                               if ( *p == '{' ) {
45520
 
+                                       state = ST_TYPE;
45521
 
+                                       p++;
45522
 
+                               } else 
45523
 
+                                       state = ST_NONE;
45524
 
+                               break;
45525
 
+                       /* Parsed '${' */
45526
 
+                       case ST_TYPE:
45527
 
+                               mark = p;
45528
 
+                               /* Scan for 'hex' or 'unicode' */
45529
 
+                               while ( p < strend && i_isalpha(*p) ) p++;
45530
 
+                                       
45531
 
+                               if ( *p != ':' ) {
45532
 
+                                       state = ST_NONE;
45533
 
+                                       break;
45534
 
+                               }
45535
 
+                               
45536
 
+                               state = ST_CLOSE;
45537
 
+                               
45538
 
+                               str_truncate(tmpstr, 0);
45539
 
+                               if ( strncasecmp(mark, "hex", p - mark) == 0 ) {
45540
 
+                                       /* Hexadecimal */
45541
 
+                                       p++;
45542
 
+                                       if ( !_decode_hex(&p, strend, tmpstr) )
45543
 
+                                               state = ST_NONE;
45544
 
+                               } else if ( strncasecmp(mark, "unicode", p - mark) == 0 ) {
45545
 
+                                       /* Unicode */
45546
 
+                                       p++;
45547
 
+                                       if ( !_decode_unicode(&p, strend, tmpstr, &error_hex) )
45548
 
+                                               state = ST_NONE;
45549
 
+                               } else {        
45550
 
+                                       /* Invalid encoding */
45551
 
+                                       p++;
45552
 
+                                       state = ST_NONE;
45553
 
+                               }
45554
 
+                               break;
45555
 
+                       case ST_CLOSE:
45556
 
+                               if ( *p == '}' ) {                              
45557
 
+                                       /* We now know that the substitution is valid */        
45558
 
+
45559
 
+                                       if ( error_hex != 0 ) {
45560
 
+                                               sieve_argument_validate_error(validator, *arg, 
45561
 
+                                                       "invalid unicode character 0x%08x in encoded character substitution",
45562
 
+                                                       error_hex);
45563
 
+                                               result = FALSE;
45564
 
+                                               break;
45565
 
+                                       }
45566
 
+                                       
45567
 
+                                       if ( newstr == NULL ) {
45568
 
+                                               newstr = str_new(sieve_ast_pool((*arg)->ast), str_len(str)*2);
45569
 
+                                       }
45570
 
+                                       
45571
 
+                                       str_append_n(newstr, strstart, substart-strstart);
45572
 
+                                       str_append_str(newstr, tmpstr);
45573
 
+                                       
45574
 
+                                       strstart = p + 1;
45575
 
+                                       substart = strstart;
45576
 
+                                       
45577
 
+                                       p++;    
45578
 
+                               } 
45579
 
+                               state = ST_NONE;
45580
 
+                       }
45581
 
+               }
45582
 
+       } T_END;
45583
 
+
45584
 
+       if ( !result ) return FALSE;
45585
 
+       
45586
 
+       if ( newstr != NULL ) {
45587
 
+               if ( strstart != strend )
45588
 
+                       str_append_n(newstr, strstart, strend-strstart);        
45589
 
+       
45590
 
+               sieve_ast_argument_string_set(*arg, newstr);
45591
 
+       }
45592
 
+       
45593
 
+       /* Pass the processed string to a (possible) next layer of processing */
45594
 
+       return sieve_validator_argument_activate_super
45595
 
+               (validator, cmd, *arg, TRUE);
45596
 
+}
45597
 
+
45598
 
+/* 
45599
 
+ * Extension implementation
45600
 
+ */
45601
 
+
45602
 
+static bool ext_encoded_character_validator_load
45603
 
+(struct sieve_validator *validator ATTR_UNUSED)
45604
 
+{
45605
 
+       /* Override the constant string argument with our own */
45606
 
+       sieve_validator_argument_override(validator, SAT_CONST_STRING, 
45607
 
+               &encoded_string_argument); 
45608
 
+       
45609
 
+       return TRUE;
45610
 
+}
45611
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/ext-envelope.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/ext-envelope.c
45612
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/ext-envelope.c 1970-01-01 01:00:00.000000000 +0100
45613
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/ext-envelope.c  2009-07-30 00:45:42.000000000 +0200
45614
 
@@ -0,0 +1,523 @@
45615
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
45616
 
+ */
45617
 
+
45618
 
+/* Extension envelope 
45619
 
+ * ------------------
45620
 
+ *
45621
 
+ * Authors: Stephan Bosch
45622
 
+ * Specification: RFC5228
45623
 
+ * Implementation: full
45624
 
+ * Status: experimental, largely untested
45625
 
+ *
45626
 
+ */
45627
 
+
45628
 
+#include "lib.h"
45629
 
+#include "str-sanitize.h"
45630
 
+#include "array.h"
45631
 
+
45632
 
+#include "sieve-common.h"
45633
 
+#include "sieve-extensions.h"
45634
 
+#include "sieve-commands.h"
45635
 
+#include "sieve-code.h"
45636
 
+#include "sieve-address.h"
45637
 
+#include "sieve-comparators.h"
45638
 
+#include "sieve-match-types.h"
45639
 
+#include "sieve-address-parts.h"
45640
 
+#include "sieve-message.h"
45641
 
+
45642
 
+#include "sieve-validator.h"
45643
 
+#include "sieve-generator.h"
45644
 
+#include "sieve-interpreter.h"
45645
 
+#include "sieve-dump.h"
45646
 
+#include "sieve-match.h"
45647
 
+
45648
 
+/*
45649
 
+ * Forward declarations
45650
 
+ */
45651
 
+
45652
 
+static const struct sieve_command envelope_test;
45653
 
+const struct sieve_operation envelope_operation;
45654
 
+const struct sieve_extension envelope_extension;
45655
 
+
45656
 
+/* 
45657
 
+ * Extension 
45658
 
+ */
45659
 
+
45660
 
+static bool ext_envelope_validator_load(struct sieve_validator *validator);
45661
 
+
45662
 
+static int ext_my_id = -1;
45663
 
+
45664
 
+const struct sieve_extension envelope_extension = { 
45665
 
+       "envelope", 
45666
 
+       &ext_my_id,
45667
 
+       NULL, NULL,
45668
 
+       ext_envelope_validator_load, 
45669
 
+       NULL, NULL, NULL, NULL, NULL,
45670
 
+       SIEVE_EXT_DEFINE_OPERATION(envelope_operation), 
45671
 
+       SIEVE_EXT_DEFINE_NO_OPERANDS 
45672
 
+};
45673
 
+
45674
 
+static bool ext_envelope_validator_load(struct sieve_validator *validator)
45675
 
+{
45676
 
+       /* Register new test */
45677
 
+       sieve_validator_register_command(validator, &envelope_test);
45678
 
+
45679
 
+       return TRUE;
45680
 
+}
45681
 
+
45682
 
+/* 
45683
 
+ * Envelope test 
45684
 
+ *
45685
 
+ * Syntax
45686
 
+ *   envelope [COMPARATOR] [ADDRESS-PART] [MATCH-TYPE]
45687
 
+ *     <envelope-part: string-list> <key-list: string-list>   
45688
 
+ */
45689
 
+
45690
 
+static bool tst_envelope_registered
45691
 
+       (struct sieve_validator *validator, struct sieve_command_registration *cmd_reg);
45692
 
+static bool tst_envelope_validate
45693
 
+       (struct sieve_validator *validator, struct sieve_command_context *tst);
45694
 
+static bool tst_envelope_generate
45695
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx);
45696
 
+
45697
 
+static const struct sieve_command envelope_test = { 
45698
 
+       "envelope", 
45699
 
+       SCT_TEST, 
45700
 
+       2, 0, FALSE, FALSE,
45701
 
+       tst_envelope_registered, 
45702
 
+       NULL,
45703
 
+       tst_envelope_validate, 
45704
 
+       tst_envelope_generate, 
45705
 
+       NULL 
45706
 
+};
45707
 
+
45708
 
+/* 
45709
 
+ * Envelope operation 
45710
 
+ */
45711
 
+
45712
 
+static bool ext_envelope_operation_dump
45713
 
+       (const struct sieve_operation *op, 
45714
 
+               const struct sieve_dumptime_env *denv, sieve_size_t *address);
45715
 
+static int ext_envelope_operation_execute
45716
 
+       (const struct sieve_operation *op,
45717
 
+               const struct sieve_runtime_env *renv, sieve_size_t *address);
45718
 
+
45719
 
+const struct sieve_operation envelope_operation = { 
45720
 
+       "ENVELOPE",
45721
 
+       &envelope_extension,
45722
 
+       0,
45723
 
+       ext_envelope_operation_dump, 
45724
 
+       ext_envelope_operation_execute 
45725
 
+};
45726
 
+
45727
 
+/*
45728
 
+ * Envelope parts
45729
 
+ *
45730
 
+ * FIXME: not available to extensions
45731
 
+ */
45732
 
+
45733
 
+struct sieve_envelope_part {
45734
 
+       const char *identifier;
45735
 
+
45736
 
+       const struct sieve_address *const *(*get_addresses)
45737
 
+               (const struct sieve_runtime_env *renv);
45738
 
+       const char * const *(*get_values)
45739
 
+               (const struct sieve_runtime_env *renv);
45740
 
+};
45741
 
+
45742
 
+static const struct sieve_address *const *_from_part_get_addresses
45743
 
+       (const struct sieve_runtime_env *renv);
45744
 
+static const char *const *_from_part_get_values
45745
 
+       (const struct sieve_runtime_env *renv);
45746
 
+static const struct sieve_address *const *_to_part_get_addresses
45747
 
+       (const struct sieve_runtime_env *renv);
45748
 
+static const char *const *_to_part_get_values
45749
 
+       (const struct sieve_runtime_env *renv);
45750
 
+static const char *const *_auth_part_get_values
45751
 
+       (const struct sieve_runtime_env *renv);
45752
 
+
45753
 
+static const struct sieve_envelope_part _from_part = {
45754
 
+       "from",
45755
 
+       _from_part_get_addresses,
45756
 
+       _from_part_get_values,
45757
 
+};
45758
 
+
45759
 
+static const struct sieve_envelope_part _to_part = {
45760
 
+       "to",
45761
 
+       _to_part_get_addresses,
45762
 
+       _to_part_get_values,
45763
 
+};     
45764
 
+
45765
 
+static const struct sieve_envelope_part _auth_part = {
45766
 
+       "auth",
45767
 
+       NULL,
45768
 
+       _auth_part_get_values,
45769
 
+};     
45770
 
+
45771
 
+static const struct sieve_envelope_part *_envelope_parts[] = {
45772
 
+       /* Required */
45773
 
+       &_from_part, &_to_part, 
45774
 
+
45775
 
+       /* Non-standard */
45776
 
+       &_auth_part
45777
 
+};
45778
 
+
45779
 
+static unsigned int _envelope_part_count = N_ELEMENTS(_envelope_parts);
45780
 
+
45781
 
+static const struct sieve_envelope_part *_envelope_part_find
45782
 
+(const char *identifier)
45783
 
+{
45784
 
+       unsigned int i;
45785
 
+
45786
 
+       for ( i = 0; i < _envelope_part_count; i++ ) {
45787
 
+               if ( strcasecmp( _envelope_parts[i]->identifier, identifier ) == 0 ) {
45788
 
+                       return _envelope_parts[i];
45789
 
+        }
45790
 
+       }
45791
 
+       
45792
 
+       return NULL;
45793
 
+}
45794
 
+
45795
 
+
45796
 
+/* 
45797
 
+ * Command Registration 
45798
 
+ */
45799
 
+
45800
 
+static bool tst_envelope_registered
45801
 
+(struct sieve_validator *validator, struct sieve_command_registration *cmd_reg) 
45802
 
+{
45803
 
+       /* The order of these is not significant */
45804
 
+       sieve_comparators_link_tag(validator, cmd_reg, SIEVE_AM_OPT_COMPARATOR);
45805
 
+       sieve_address_parts_link_tags(validator, cmd_reg, SIEVE_AM_OPT_ADDRESS_PART);
45806
 
+       sieve_match_types_link_tags(validator, cmd_reg, SIEVE_AM_OPT_MATCH_TYPE);
45807
 
+       
45808
 
+       return TRUE;
45809
 
+}
45810
 
+
45811
 
+/* 
45812
 
+ * Validation 
45813
 
+ */
45814
 
45815
 
+static int _envelope_part_is_supported
45816
 
+(void *context, struct sieve_ast_argument *arg)
45817
 
+{
45818
 
+       const struct sieve_envelope_part **not_address =
45819
 
+               (const struct sieve_envelope_part **) context;
45820
 
+
45821
 
+       if ( sieve_argument_is_string_literal(arg) ) {
45822
 
+               const struct sieve_envelope_part *epart;
45823
 
+
45824
 
+               if ( (epart=_envelope_part_find(sieve_ast_strlist_strc(arg))) != NULL ) {
45825
 
+                       if ( epart->get_addresses == NULL ) {
45826
 
+                               if ( *not_address == NULL )
45827
 
+                                       *not_address = epart;
45828
 
+                       }
45829
 
+                                       
45830
 
+                       return TRUE;
45831
 
+               }
45832
 
+               
45833
 
+               return FALSE;
45834
 
+       } 
45835
 
+       
45836
 
+       return TRUE; /* Can't check at compile time */
45837
 
+}
45838
 
+
45839
 
+static bool tst_envelope_validate
45840
 
+(struct sieve_validator *validator, struct sieve_command_context *tst) 
45841
 
+{              
45842
 
+       struct sieve_ast_argument *arg = tst->first_positional;
45843
 
+       struct sieve_ast_argument *epart;
45844
 
+       const struct sieve_envelope_part *not_address = NULL;
45845
 
+                               
45846
 
+       if ( !sieve_validate_positional_argument
45847
 
+               (validator, tst, arg, "envelope part", 1, SAAT_STRING_LIST) ) {
45848
 
+               return FALSE;
45849
 
+       }
45850
 
+       
45851
 
+       if ( !sieve_validator_argument_activate(validator, tst, arg, FALSE) )
45852
 
+               return FALSE;
45853
 
+               
45854
 
+       /* Check whether supplied envelope parts are supported
45855
 
+        *   FIXME: verify dynamic envelope parts at runtime 
45856
 
+        */
45857
 
+       epart = arg;
45858
 
+       if ( !sieve_ast_stringlist_map(&epart, (void *) &not_address, 
45859
 
+               _envelope_part_is_supported) ) {                
45860
 
+               
45861
 
+               sieve_argument_validate_error(validator, epart, 
45862
 
+                       "specified envelope part '%s' is not supported by the envelope test", 
45863
 
+                               str_sanitize(sieve_ast_strlist_strc(epart), 64));
45864
 
+               return FALSE;
45865
 
+       }
45866
 
+
45867
 
+       if ( not_address != NULL ) {
45868
 
+               struct sieve_ast_argument *addrp_arg = 
45869
 
+                       sieve_command_find_argument(tst, &address_part_tag);
45870
 
+
45871
 
+               if ( addrp_arg != NULL ) {
45872
 
+                       sieve_argument_validate_error(validator, addrp_arg,
45873
 
+                               "address part ':%s' specified while non-address envelope part '%s' "
45874
 
+                               "is tested with the envelope test",
45875
 
+                sieve_ast_argument_tag(addrp_arg), not_address->identifier);
45876
 
+               return FALSE;
45877
 
+               }
45878
 
+       }
45879
 
+       
45880
 
+       arg = sieve_ast_argument_next(arg);
45881
 
+       
45882
 
+       if ( !sieve_validate_positional_argument
45883
 
+               (validator, tst, arg, "key list", 2, SAAT_STRING_LIST) ) {
45884
 
+               return FALSE;
45885
 
+       }
45886
 
+       
45887
 
+       if ( !sieve_validator_argument_activate(validator, tst, arg, FALSE) )
45888
 
+               return FALSE;
45889
 
+
45890
 
+       /* Validate the key argument to a specified match type */
45891
 
+       return sieve_match_type_validate
45892
 
+               (validator, tst, arg, &is_match_type, &i_ascii_casemap_comparator);
45893
 
+}
45894
 
+
45895
 
+/*
45896
 
+ * Code generation
45897
 
+ */
45898
 
45899
 
+static bool tst_envelope_generate
45900
 
+(const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx) 
45901
 
+{
45902
 
+       (void)sieve_operation_emit_code(cgenv->sbin, &envelope_operation);
45903
 
+
45904
 
+       /* Generate arguments */
45905
 
+       if ( !sieve_generate_arguments(cgenv, ctx, NULL) )
45906
 
+               return FALSE;
45907
 
+
45908
 
+       return TRUE;
45909
 
+}
45910
 
+
45911
 
+/* 
45912
 
+ * Code dump 
45913
 
+ */
45914
 
45915
 
+static bool ext_envelope_operation_dump
45916
 
+(const struct sieve_operation *op ATTR_UNUSED, 
45917
 
+       const struct sieve_dumptime_env *denv, sieve_size_t *address)
45918
 
+{
45919
 
+       sieve_code_dumpf(denv, "ENVELOPE");
45920
 
+       sieve_code_descend(denv);
45921
 
+
45922
 
+       /* Handle any optional arguments */
45923
 
+       if ( !sieve_addrmatch_default_dump_optionals(denv, address) )
45924
 
+               return FALSE;
45925
 
+
45926
 
+       return
45927
 
+               sieve_opr_stringlist_dump(denv, address, "envelope part") &&
45928
 
+               sieve_opr_stringlist_dump(denv, address, "key list");
45929
 
+}
45930
 
+
45931
 
+/*
45932
 
+ * Interpretation
45933
 
+ */
45934
 
+
45935
 
+static const struct sieve_address *const *_from_part_get_addresses
45936
 
+(const struct sieve_runtime_env *renv)
45937
 
+{
45938
 
+       ARRAY_DEFINE(envelope_values, const struct sieve_address *);
45939
 
+       const struct sieve_address *address =
45940
 
+               sieve_message_get_sender_address(renv->msgctx);
45941
 
+       
45942
 
+       if ( address != NULL ) {
45943
 
+               t_array_init(&envelope_values, 2);
45944
 
+
45945
 
+        array_append(&envelope_values, &address, 1);
45946
 
+
45947
 
+           (void)array_append_space(&envelope_values);
45948
 
+       return array_idx(&envelope_values, 0);
45949
 
+       } 
45950
 
+
45951
 
+       return NULL;
45952
 
+}
45953
 
+
45954
 
+static const char *const *_from_part_get_values
45955
 
+(const struct sieve_runtime_env *renv)
45956
 
+{
45957
 
+       ARRAY_DEFINE(envelope_values, const char *);
45958
 
+
45959
 
+       t_array_init(&envelope_values, 2);
45960
 
+
45961
 
+       if ( renv->msgdata->return_path != NULL ) {
45962
 
+        array_append(&envelope_values, &renv->msgdata->return_path, 1);
45963
 
+       }
45964
 
+
45965
 
+       (void)array_append_space(&envelope_values);
45966
 
+
45967
 
+       return array_idx(&envelope_values, 0);
45968
 
+}
45969
 
+
45970
 
+static const struct sieve_address *const *_to_part_get_addresses
45971
 
+(const struct sieve_runtime_env *renv)
45972
 
+{
45973
 
+       ARRAY_DEFINE(envelope_values, const struct sieve_address *);
45974
 
+       const struct sieve_address *address = 
45975
 
+               sieve_message_get_recipient_address(renv->msgctx);      
45976
 
+
45977
 
+       if ( address != NULL && address->local_part != NULL ) {
45978
 
+               t_array_init(&envelope_values, 2);
45979
 
+
45980
 
+        array_append(&envelope_values, &address, 1);
45981
 
+
45982
 
+           (void)array_append_space(&envelope_values);
45983
 
+       return array_idx(&envelope_values, 0);
45984
 
+       }
45985
 
+
45986
 
+       return NULL;
45987
 
+}
45988
 
+
45989
 
+static const char *const *_to_part_get_values
45990
 
+(const struct sieve_runtime_env *renv)
45991
 
+{
45992
 
+       ARRAY_DEFINE(envelope_values, const char *);
45993
 
+
45994
 
+       t_array_init(&envelope_values, 2);
45995
 
+
45996
 
+       if ( renv->msgdata->to_address != NULL ) {
45997
 
+        array_append(&envelope_values, &renv->msgdata->to_address, 1);
45998
 
+       }
45999
 
+
46000
 
+       (void)array_append_space(&envelope_values);
46001
 
+
46002
 
+       return array_idx(&envelope_values, 0);
46003
 
+}
46004
 
+
46005
 
+
46006
 
+static const char *const *_auth_part_get_values
46007
 
+(const struct sieve_runtime_env *renv)
46008
 
+{
46009
 
+       ARRAY_DEFINE(envelope_values, const char *);
46010
 
+
46011
 
+       t_array_init(&envelope_values, 2);
46012
 
+
46013
 
+       if ( renv->msgdata->auth_user != NULL )
46014
 
+        array_append(&envelope_values, &renv->msgdata->auth_user, 1);
46015
 
+
46016
 
+       (void)array_append_space(&envelope_values);
46017
 
+
46018
 
+       return array_idx(&envelope_values, 0);
46019
 
+}
46020
 
+
46021
 
+static int ext_envelope_operation_execute
46022
 
+(const struct sieve_operation *op ATTR_UNUSED,
46023
 
+       const struct sieve_runtime_env *renv, sieve_size_t *address)
46024
 
+{
46025
 
+       bool result = TRUE;
46026
 
+       const struct sieve_comparator *cmp = &i_ascii_casemap_comparator;
46027
 
+       const struct sieve_match_type *mtch = &is_match_type;
46028
 
+       const struct sieve_address_part *addrp = &all_address_part;
46029
 
+       struct sieve_match_context *mctx;
46030
 
+       struct sieve_coded_stringlist *envp_list;
46031
 
+       struct sieve_coded_stringlist *key_list;
46032
 
+       string_t *envp_item;
46033
 
+       bool matched;
46034
 
+       int ret;
46035
 
+
46036
 
+       /*
46037
 
+        * Read operands
46038
 
+        */
46039
 
+       
46040
 
+       sieve_runtime_trace(renv, "ENVELOPE test");
46041
 
+
46042
 
+       if ( (ret=sieve_addrmatch_default_get_optionals
46043
 
+               (renv, address, &addrp, &mtch, &cmp)) <= 0 )
46044
 
+               return ret; 
46045
 
+
46046
 
+       /* Read envelope-part */
46047
 
+       if ( (envp_list=sieve_opr_stringlist_read(renv, address)) == NULL ) {
46048
 
+               sieve_runtime_trace_error(renv, "invalid envelope-part operand");
46049
 
+               return SIEVE_EXEC_BIN_CORRUPT;
46050
 
+       }
46051
 
+
46052
 
+       /* Read key-list */
46053
 
+       if ( (key_list=sieve_opr_stringlist_read(renv, address)) == NULL ) {
46054
 
+               sieve_runtime_trace_error(renv, "invalid key-list operand");
46055
 
+               return SIEVE_EXEC_BIN_CORRUPT;
46056
 
+       }
46057
 
+       
46058
 
+       /* Initialize match */
46059
 
+       mctx = sieve_match_begin(renv->interp, mtch, cmp, NULL, key_list);
46060
 
+       
46061
 
+       /* Iterate through all requested headers to match */
46062
 
+       envp_item = NULL;
46063
 
+       matched = FALSE;
46064
 
+       while ( result && !matched && 
46065
 
+               (result=sieve_coded_stringlist_next_item(envp_list, &envp_item)) 
46066
 
+               && envp_item != NULL ) {
46067
 
+               const struct sieve_envelope_part *epart;
46068
 
+                       
46069
 
+               if ( (epart=_envelope_part_find(str_c(envp_item))) != NULL ) {
46070
 
+                       const struct sieve_address * const *addresses = NULL;
46071
 
+                       int i;
46072
 
+
46073
 
+                       if ( epart->get_addresses != NULL ) {
46074
 
+                               /* Field contains addresses */
46075
 
+                               addresses = epart->get_addresses(renv);
46076
 
+
46077
 
+                               if ( addresses != NULL ) {
46078
 
+                                       for ( i = 0; !matched && addresses[i] != NULL; i++ ) {
46079
 
+                                               if ( addresses[i]->local_part == NULL ) {
46080
 
+                                                       /* Null path <> */
46081
 
+                                                       ret = sieve_match_value(mctx, "", 0);
46082
 
+                                               } else {
46083
 
+                                                       const char *part = addrp->extract_from(addresses[i]);
46084
 
+
46085
 
+                                                       if ( part != NULL ) 
46086
 
+                                                               ret = sieve_match_value(mctx, part, strlen(part));
46087
 
+                                                       else
46088
 
+                                                               ret = 0;
46089
 
+                                               }
46090
 
+
46091
 
+                                               if ( ret < 0 ) {
46092
 
+                                                       result = FALSE;
46093
 
+                                                       break;
46094
 
+                                               }
46095
 
+
46096
 
+                                       matched = ret > 0;
46097
 
+                                       }
46098
 
+                               }
46099
 
+                       } 
46100
 
+
46101
 
+                       if ( epart->get_values != NULL && addresses == NULL && 
46102
 
+                               addrp == &all_address_part ) {
46103
 
+                               /* Field contains something else */
46104
 
+                               const char *const *values = epart->get_values(renv);
46105
 
+
46106
 
+                               if ( values == NULL ) continue;
46107
 
+       
46108
 
+                               for ( i = 0; !matched && values[i] != NULL; i++ ) {                             
46109
 
+
46110
 
+                                       if ( (ret=sieve_match_value
46111
 
+                                               (mctx, values[i], strlen(values[i]))) < 0 ) {
46112
 
+                           result = FALSE;
46113
 
+                       break;
46114
 
+                       }
46115
 
+                       
46116
 
+                                       matched = ret > 0;                              
46117
 
+                               }
46118
 
+                       }
46119
 
+               }
46120
 
+       }
46121
 
+       
46122
 
+       /* Finish match */
46123
 
+       if ( (ret=sieve_match_end(&mctx)) < 0 ) 
46124
 
+               result = FALSE;
46125
 
+       else
46126
 
+               matched = ( ret > 0 || matched );
46127
 
+
46128
 
+       if ( result ) {
46129
 
+               /* Set test result for subsequent conditional jump */
46130
 
+               sieve_interpreter_set_test_result(renv->interp, matched);
46131
 
+               return SIEVE_EXEC_OK;
46132
 
+       }
46133
 
+       
46134
 
+       sieve_runtime_trace_error(renv, "invalid string-list item");    
46135
 
+       return SIEVE_EXEC_BIN_CORRUPT;
46136
 
+}
46137
 
+
46138
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/ext-fileinto.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/ext-fileinto.c
46139
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/ext-fileinto.c 1970-01-01 01:00:00.000000000 +0100
46140
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/ext-fileinto.c  2009-01-06 00:15:52.000000000 +0100
46141
 
@@ -0,0 +1,223 @@
46142
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
46143
 
+ */
46144
 
+
46145
 
+/* Extension fileinto 
46146
 
+ * ------------------
46147
 
+ *
46148
 
+ * Authors: Stephan Bosch
46149
 
+ * Specification: RFC5228
46150
 
+ * Implementation: full
46151
 
+ * Status: experimental, largely untested
46152
 
+ *
46153
 
+ */
46154
 
+
46155
 
+#include "lib.h"
46156
 
+#include "str-sanitize.h"
46157
 
+#include "imap-utf7.h"
46158
 
+
46159
 
+#include "sieve-common.h"
46160
 
+#include "sieve-extensions.h"
46161
 
+#include "sieve-binary.h"
46162
 
+#include "sieve-commands.h"
46163
 
+#include "sieve-code.h"
46164
 
+#include "sieve-actions.h"
46165
 
+#include "sieve-validator.h"
46166
 
+#include "sieve-generator.h"
46167
 
+#include "sieve-interpreter.h"
46168
 
+#include "sieve-dump.h"
46169
 
+#include "sieve-result.h"
46170
 
+
46171
 
+/* 
46172
 
+ * Forward declarations 
46173
 
+ */
46174
 
+
46175
 
+static const struct sieve_command fileinto_command;
46176
 
+const struct sieve_operation fileinto_operation;
46177
 
+const struct sieve_extension fileinto_extension; 
46178
 
+
46179
 
+/* 
46180
 
+ * Extension
46181
 
+ */
46182
 
+
46183
 
+static bool ext_fileinto_validator_load(struct sieve_validator *validator);
46184
 
+
46185
 
+static int ext_my_id = -1;
46186
 
+
46187
 
+const struct sieve_extension fileinto_extension = { 
46188
 
+       "fileinto", 
46189
 
+       &ext_my_id,
46190
 
+       NULL, NULL,
46191
 
+       ext_fileinto_validator_load, 
46192
 
+       NULL, NULL, NULL, NULL, NULL,
46193
 
+       SIEVE_EXT_DEFINE_OPERATION(fileinto_operation), 
46194
 
+       SIEVE_EXT_DEFINE_NO_OPERANDS    
46195
 
+};
46196
 
+
46197
 
+static bool ext_fileinto_validator_load(struct sieve_validator *validator)
46198
 
+{
46199
 
+       /* Register new command */
46200
 
+       sieve_validator_register_command(validator, &fileinto_command);
46201
 
+
46202
 
+       return TRUE;
46203
 
+}
46204
 
+
46205
 
+/* 
46206
 
+ * Fileinto command
46207
 
+ *
46208
 
+ * Syntax: 
46209
 
+ *   fileinto <folder: string>
46210
 
+ */
46211
 
+
46212
 
+static bool cmd_fileinto_validate
46213
 
+       (struct sieve_validator *validator, struct sieve_command_context *cmd);
46214
 
+static bool cmd_fileinto_generate
46215
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx);
46216
 
+
46217
 
+static const struct sieve_command fileinto_command = { 
46218
 
+       "fileinto", 
46219
 
+       SCT_COMMAND,
46220
 
+       1, 0, FALSE, FALSE, 
46221
 
+       NULL, NULL,
46222
 
+       cmd_fileinto_validate, 
46223
 
+       cmd_fileinto_generate, 
46224
 
+       NULL 
46225
 
+};
46226
 
+
46227
 
+/* 
46228
 
+ * Fileinto operation 
46229
 
+ */
46230
 
+
46231
 
+static bool ext_fileinto_operation_dump
46232
 
+       (const struct sieve_operation *op, 
46233
 
+               const struct sieve_dumptime_env *denv, sieve_size_t *address);
46234
 
+static int ext_fileinto_operation_execute
46235
 
+       (const struct sieve_operation *op, 
46236
 
+               const struct sieve_runtime_env *renv, sieve_size_t *address); 
46237
 
+
46238
 
+const struct sieve_operation fileinto_operation = { 
46239
 
+       "FILEINTO",
46240
 
+       &fileinto_extension,
46241
 
+       0,
46242
 
+       ext_fileinto_operation_dump, 
46243
 
+       ext_fileinto_operation_execute 
46244
 
+};
46245
 
+
46246
 
+/* 
46247
 
+ * Validation 
46248
 
+ */
46249
 
+
46250
 
+static bool cmd_fileinto_validate
46251
 
+(struct sieve_validator *validator, struct sieve_command_context *cmd) 
46252
 
+{      
46253
 
+       struct sieve_ast_argument *arg = cmd->first_positional;
46254
 
+       
46255
 
+       if ( !sieve_validate_positional_argument
46256
 
+               (validator, cmd, arg, "folder", 1, SAAT_STRING) ) {
46257
 
+               return FALSE;
46258
 
+       }
46259
 
+       
46260
 
+       return sieve_validator_argument_activate(validator, cmd, arg, FALSE);
46261
 
+}
46262
 
+
46263
 
+/*
46264
 
+ * Code generation
46265
 
+ */
46266
 
46267
 
+static bool cmd_fileinto_generate
46268
 
+(const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx) 
46269
 
+{
46270
 
+       sieve_operation_emit_code(cgenv->sbin, &fileinto_operation);
46271
 
+
46272
 
+       /* Emit line number */
46273
 
+    sieve_code_source_line_emit(cgenv->sbin, sieve_command_source_line(ctx));
46274
 
+
46275
 
+       /* Generate arguments */
46276
 
+       return sieve_generate_arguments(cgenv, ctx, NULL);
46277
 
+}
46278
 
+
46279
 
+/* 
46280
 
+ * Code dump
46281
 
+ */
46282
 
46283
 
+static bool ext_fileinto_operation_dump
46284
 
+(const struct sieve_operation *op ATTR_UNUSED,
46285
 
+       const struct sieve_dumptime_env *denv, sieve_size_t *address)
46286
 
+{
46287
 
+       sieve_code_dumpf(denv, "FILEINTO");
46288
 
+       sieve_code_descend(denv);
46289
 
+
46290
 
+       /* Source line */
46291
 
+    if ( !sieve_code_source_line_dump(denv, address) )
46292
 
+        return FALSE;
46293
 
+
46294
 
+       if ( !sieve_code_dumper_print_optional_operands(denv, address) ) {
46295
 
+               return FALSE;
46296
 
+       }
46297
 
+
46298
 
+       return sieve_opr_string_dump(denv, address, "folder");
46299
 
+}
46300
 
+
46301
 
+/*
46302
 
+ * Execution
46303
 
+ */
46304
 
+
46305
 
+static int ext_fileinto_operation_execute
46306
 
+(const struct sieve_operation *op ATTR_UNUSED,
46307
 
+       const struct sieve_runtime_env *renv, sieve_size_t *address)
46308
 
+{
46309
 
+       struct sieve_side_effects_list *slist = NULL; 
46310
 
+       string_t *folder, *folder_utf7;
46311
 
+       const char *mailbox;
46312
 
+       unsigned int source_line;
46313
 
+       int ret = 0;
46314
 
+       
46315
 
+       /*
46316
 
+        * Read operands
46317
 
+        */
46318
 
+
46319
 
+       /* Source line */
46320
 
+       if ( !sieve_code_source_line_read(renv, address, &source_line) ) {
46321
 
+               sieve_runtime_trace_error(renv, "invalid source line");
46322
 
+               return SIEVE_EXEC_BIN_CORRUPT;
46323
 
+       }
46324
 
+       
46325
 
+       /* Optional operands */
46326
 
+       if ( (ret=sieve_interpreter_handle_optional_operands(renv, address, &slist)) 
46327
 
+               <= 0 )
46328
 
+               return ret;
46329
 
+
46330
 
+       /* Folder operand */
46331
 
+       if ( !sieve_opr_string_read(renv, address, &folder) ) {
46332
 
+               sieve_runtime_trace_error(renv, "invalid folder operand");
46333
 
+               return SIEVE_EXEC_BIN_CORRUPT;
46334
 
+       }
46335
 
+       
46336
 
+       /*
46337
 
+        * Perform operation
46338
 
+        */
46339
 
+
46340
 
+       mailbox = str_sanitize(str_c(folder), 64);
46341
 
+       sieve_runtime_trace(renv, "FILEINTO action (\"%s\")", mailbox);
46342
 
+               
46343
 
+       /* Convert utf-8 folder name to utf-7
46344
 
+        *   FIXME: perform this at compile time when possible.
46345
 
+        */
46346
 
+       folder_utf7 = t_str_new(256);
46347
 
+       if ( imap_utf8_to_utf7(str_c(folder), folder_utf7) < 0 ) {
46348
 
+               sieve_runtime_error
46349
 
+                       (renv, sieve_error_script_location(renv->script, source_line),
46350
 
+                               "mailbox name not utf-8: %s", mailbox);
46351
 
+       }       
46352
 
+               
46353
 
+       /* Add action to result */      
46354
 
+       ret = sieve_act_store_add_to_result
46355
 
+               (renv, slist, str_c(folder_utf7), source_line);
46356
 
+
46357
 
+       return ( ret >= 0 );
46358
 
+}
46359
 
+
46360
 
+
46361
 
+
46362
 
+
46363
 
+
46364
 
+
46365
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/ext-reject.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/ext-reject.c
46366
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/ext-reject.c   1970-01-01 01:00:00.000000000 +0100
46367
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/ext-reject.c    2009-07-21 03:07:54.000000000 +0200
46368
 
@@ -0,0 +1,534 @@
46369
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
46370
 
+ */
46371
 
+
46372
 
+/* Extension reject 
46373
 
+ * ----------------
46374
 
+ *
46375
 
+ * Authors: Stephan Bosch
46376
 
+ * Specification: RFC5429
46377
 
+ * Implementation: full  
46378
 
+ * Status: experimental
46379
 
+ *
46380
 
+ */
46381
 
+
46382
 
+#include "lib.h"
46383
 
+#include "ioloop.h"
46384
 
+#include "hostpid.h"
46385
 
+#include "str-sanitize.h"
46386
 
+#include "message-date.h"
46387
 
+#include "message-size.h"
46388
 
+#include "istream.h"
46389
 
+#include "istream-header-filter.h"
46390
 
+
46391
 
+#include "rfc2822.h"
46392
 
+
46393
 
+#include "sieve-common.h"
46394
 
+#include "sieve-extensions.h"
46395
 
+#include "sieve-commands.h"
46396
 
+#include "sieve-code.h"
46397
 
+#include "sieve-actions.h"
46398
 
+#include "sieve-validator.h"
46399
 
+#include "sieve-generator.h"
46400
 
+#include "sieve-binary.h"
46401
 
+#include "sieve-interpreter.h"
46402
 
+#include "sieve-dump.h"
46403
 
+#include "sieve-result.h"
46404
 
+#include "sieve-message.h"
46405
 
+
46406
 
+/* 
46407
 
+ * Forward declarations 
46408
 
+ */
46409
 
+
46410
 
+static const struct sieve_command reject_command;
46411
 
+static const struct sieve_operation reject_operation;
46412
 
+
46413
 
+static const struct sieve_command ereject_command;
46414
 
+static const struct sieve_operation ereject_operation;
46415
 
+
46416
 
+/* 
46417
 
+ * Extensions
46418
 
+ */
46419
 
+
46420
 
+/* Reject */
46421
 
+
46422
 
+static bool ext_reject_validator_load(struct sieve_validator *validator);
46423
 
+
46424
 
+static int ext_reject_my_id = -1;
46425
 
+       
46426
 
+const struct sieve_extension reject_extension = { 
46427
 
+       "reject", 
46428
 
+       &ext_reject_my_id,
46429
 
+       NULL, NULL,
46430
 
+       ext_reject_validator_load, 
46431
 
+       NULL, NULL, NULL, NULL, NULL,
46432
 
+       SIEVE_EXT_DEFINE_OPERATION(reject_operation), 
46433
 
+       SIEVE_EXT_DEFINE_NO_OPERANDS
46434
 
+};
46435
 
+
46436
 
+static bool ext_reject_validator_load(struct sieve_validator *validator)
46437
 
+{
46438
 
+       /* Register new command */
46439
 
+       sieve_validator_register_command(validator, &reject_command);
46440
 
+
46441
 
+       return TRUE;
46442
 
+}
46443
 
+
46444
 
+/* EReject */
46445
 
+
46446
 
+static bool ext_ereject_validator_load(struct sieve_validator *validator);
46447
 
+
46448
 
+static int ext_ereject_my_id = -1;
46449
 
+       
46450
 
+const struct sieve_extension ereject_extension = { 
46451
 
+       "ereject", 
46452
 
+       &ext_ereject_my_id,
46453
 
+       NULL, NULL,
46454
 
+       ext_ereject_validator_load, 
46455
 
+       NULL, NULL, NULL, NULL, NULL,
46456
 
+       SIEVE_EXT_DEFINE_OPERATION(ereject_operation), 
46457
 
+       SIEVE_EXT_DEFINE_NO_OPERANDS
46458
 
+};
46459
 
+
46460
 
+static bool ext_ereject_validator_load(struct sieve_validator *validator)
46461
 
+{
46462
 
+       /* Register new command */
46463
 
+       sieve_validator_register_command(validator, &ereject_command);
46464
 
+
46465
 
+       return TRUE;
46466
 
+}
46467
 
+
46468
 
+/* 
46469
 
+ * Commands
46470
 
+ */
46471
 
+
46472
 
+/* Forward declarations */
46473
 
+
46474
 
+static bool cmd_reject_validate
46475
 
+       (struct sieve_validator *validator, struct sieve_command_context *cmd);
46476
 
+static bool cmd_reject_generate
46477
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx); 
46478
 
+
46479
 
+/* Reject command
46480
 
+ * 
46481
 
+ * Syntax: 
46482
 
+ *   reject <reason: string>
46483
 
+ */
46484
 
+
46485
 
+static const struct sieve_command reject_command = { 
46486
 
+       "reject", 
46487
 
+       SCT_COMMAND, 
46488
 
+       1, 0, FALSE, FALSE,
46489
 
+       NULL, NULL,
46490
 
+       cmd_reject_validate, 
46491
 
+       cmd_reject_generate, 
46492
 
+       NULL 
46493
 
+};
46494
 
+
46495
 
+/* EReject command
46496
 
+ * 
46497
 
+ * Syntax: 
46498
 
+ *   ereject <reason: string>
46499
 
+ */
46500
 
+
46501
 
+static const struct sieve_command ereject_command = { 
46502
 
+       "ereject", 
46503
 
+       SCT_COMMAND, 
46504
 
+       1, 0, FALSE, FALSE,
46505
 
+       NULL, NULL,
46506
 
+       cmd_reject_validate, 
46507
 
+       cmd_reject_generate, 
46508
 
+       NULL 
46509
 
+};
46510
 
+
46511
 
+/*
46512
 
+ * Operations
46513
 
+ */
46514
 
+
46515
 
+/* Forward declarations */
46516
 
+
46517
 
+static bool ext_reject_operation_dump
46518
 
+       (const struct sieve_operation *op, 
46519
 
+               const struct sieve_dumptime_env *denv, sieve_size_t *address);
46520
 
+static int ext_reject_operation_execute
46521
 
+       (const struct sieve_operation *op,
46522
 
+               const struct sieve_runtime_env *renv, sieve_size_t *address);
46523
 
+
46524
 
+/* Reject operation */
46525
 
+
46526
 
+static const struct sieve_operation reject_operation = { 
46527
 
+       "REJECT",
46528
 
+       &reject_extension, 
46529
 
+       0,
46530
 
+       ext_reject_operation_dump, 
46531
 
+       ext_reject_operation_execute 
46532
 
+};
46533
 
+
46534
 
+/* EReject operation */
46535
 
+
46536
 
+static const struct sieve_operation ereject_operation = { 
46537
 
+       "EREJECT",
46538
 
+       &ereject_extension, 
46539
 
+       0,
46540
 
+       ext_reject_operation_dump, 
46541
 
+       ext_reject_operation_execute 
46542
 
+};
46543
 
+
46544
 
+/* 
46545
 
+ * Reject action 
46546
 
+ */
46547
 
+
46548
 
+static int act_reject_check_duplicate
46549
 
+       (const struct sieve_runtime_env *renv, 
46550
 
+               const struct sieve_action_data *act, 
46551
 
+               const struct sieve_action_data *act_other);
46552
 
+int act_reject_check_conflict
46553
 
+       (const struct sieve_runtime_env *renv, 
46554
 
+               const struct sieve_action_data *act, 
46555
 
+               const struct sieve_action_data *act_other);
46556
 
+static void act_reject_print
46557
 
+       (const struct sieve_action *action, const struct sieve_result_print_env *rpenv,
46558
 
+               void *context, bool *keep);     
46559
 
+static bool act_reject_commit
46560
 
+       (const struct sieve_action *action ATTR_UNUSED, 
46561
 
+               const struct sieve_action_exec_env *aenv, void *tr_context, bool *keep);
46562
 
+               
46563
 
+const struct sieve_action act_reject = {
46564
 
+       "reject",
46565
 
+       SIEVE_ACTFLAG_SENDS_RESPONSE,
46566
 
+       NULL,
46567
 
+       act_reject_check_duplicate, 
46568
 
+       act_reject_check_conflict,
46569
 
+       act_reject_print,
46570
 
+       NULL, NULL,
46571
 
+       act_reject_commit,
46572
 
+       NULL
46573
 
+};
46574
 
+
46575
 
+struct act_reject_context {
46576
 
+       const char *reason;
46577
 
+       bool ereject;
46578
 
+};
46579
 
+
46580
 
+/* 
46581
 
+ * Validation 
46582
 
+ */
46583
 
+
46584
 
+static bool cmd_reject_validate
46585
 
+(struct sieve_validator *validator, struct sieve_command_context *cmd) 
46586
 
+{      
46587
 
+       struct sieve_ast_argument *arg = cmd->first_positional;
46588
 
+               
46589
 
+       if ( !sieve_validate_positional_argument
46590
 
+               (validator, cmd, arg, "reason", 1, SAAT_STRING) ) {
46591
 
+               return FALSE;
46592
 
+       }
46593
 
+       
46594
 
+       return sieve_validator_argument_activate(validator, cmd, arg, FALSE);
46595
 
+}
46596
 
+
46597
 
+/*
46598
 
+ * Code generation
46599
 
+ */
46600
 
46601
 
+static bool cmd_reject_generate
46602
 
+(const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx) 
46603
 
+{
46604
 
+       if ( ctx->command == &reject_command )
46605
 
+               sieve_operation_emit_code(cgenv->sbin, &reject_operation);
46606
 
+       else
46607
 
+               sieve_operation_emit_code(cgenv->sbin, &ereject_operation);
46608
 
+
46609
 
+       /* Emit line number */
46610
 
+       sieve_code_source_line_emit(cgenv->sbin, sieve_command_source_line(ctx));
46611
 
+
46612
 
+       /* Generate arguments */
46613
 
+       return sieve_generate_arguments(cgenv, ctx, NULL);
46614
 
+}
46615
 
+
46616
 
+/* 
46617
 
+ * Code dump
46618
 
+ */
46619
 
46620
 
+static bool ext_reject_operation_dump
46621
 
+(const struct sieve_operation *op,
46622
 
+       const struct sieve_dumptime_env *denv, sieve_size_t *address)
46623
 
+{
46624
 
+       sieve_code_dumpf(denv, "%s", op->mnemonic);
46625
 
+       sieve_code_descend(denv);
46626
 
+       
46627
 
+       /* Source line */
46628
 
+       if ( !sieve_code_source_line_dump(denv, address) )
46629
 
+               return FALSE;
46630
 
+
46631
 
+       if ( !sieve_code_dumper_print_optional_operands(denv, address) )
46632
 
+               return FALSE;
46633
 
+       
46634
 
+       return sieve_opr_string_dump(denv, address, "reason");
46635
 
+}
46636
 
+
46637
 
+/*
46638
 
+ * Interpretation
46639
 
+ */
46640
 
+
46641
 
+static int ext_reject_operation_execute
46642
 
+(const struct sieve_operation *op,
46643
 
+       const struct sieve_runtime_env *renv, sieve_size_t *address)
46644
 
+{
46645
 
+       struct sieve_side_effects_list *slist = NULL;
46646
 
+       struct act_reject_context *act;
46647
 
+       string_t *reason;
46648
 
+       unsigned int source_line;
46649
 
+       pool_t pool;
46650
 
+       int ret;
46651
 
+
46652
 
+       /* Source line */
46653
 
+       if ( !sieve_code_source_line_read(renv, address, &source_line) ) {
46654
 
+               sieve_runtime_trace_error(renv, "invalid source line");
46655
 
+               return SIEVE_EXEC_BIN_CORRUPT;
46656
 
+       }
46657
 
+       
46658
 
+       /* Optional operands (side effects) */
46659
 
+       if ( (ret=sieve_interpreter_handle_optional_operands
46660
 
+               (renv, address, &slist)) <= 0 )
46661
 
+               return ret;
46662
 
+
46663
 
+       /* Read rejection reason */
46664
 
+       if ( !sieve_opr_string_read(renv, address, &reason) ) {
46665
 
+               sieve_runtime_trace_error(renv, "invalid reason operand");
46666
 
+               return SIEVE_EXEC_BIN_CORRUPT;
46667
 
+       }
46668
 
+
46669
 
+       sieve_runtime_trace(renv, "%s action (\"%s\")", op->mnemonic, str_sanitize(str_c(reason), 64));
46670
 
+
46671
 
+       /* Add reject action to the result */
46672
 
+       pool = sieve_result_pool(renv->result);
46673
 
+       act = p_new(pool, struct act_reject_context, 1);
46674
 
+       act->reason = p_strdup(pool, str_c(reason));
46675
 
+       act->ereject = ( op == &ereject_operation );
46676
 
+       
46677
 
+       ret = sieve_result_add_action
46678
 
+               (renv, &act_reject, slist, source_line, (void *) act, 0);
46679
 
+       
46680
 
+       return ( ret >= 0 );
46681
 
+}
46682
 
+
46683
 
+/*
46684
 
+ * Action implementation
46685
 
+ */
46686
 
+
46687
 
+static int act_reject_check_duplicate
46688
 
+(const struct sieve_runtime_env *renv ATTR_UNUSED,
46689
 
+       const struct sieve_action_data *act, 
46690
 
+       const struct sieve_action_data *act_other)
46691
 
+{
46692
 
+       if ( !act_other->executed ) {
46693
 
+               sieve_runtime_error(renv, act->location, 
46694
 
+                       "duplicate reject/ereject action not allowed "
46695
 
+                       "(previously triggered one was here: %s)", act_other->location);        
46696
 
+               return -1;
46697
 
+       }
46698
 
+       
46699
 
+       return 1;
46700
 
+}
46701
 
46702
 
+int act_reject_check_conflict
46703
 
+(const struct sieve_runtime_env *renv,
46704
 
+       const struct sieve_action_data *act, 
46705
 
+       const struct sieve_action_data *act_other)
46706
 
+{
46707
 
+       if ( (act_other->action->flags & SIEVE_ACTFLAG_TRIES_DELIVER) > 0 ) {
46708
 
+               if ( !act_other->executed ) {
46709
 
+                       sieve_runtime_error(renv, act->location, 
46710
 
+                               "reject/ereject action conflicts with other action: "
46711
 
+                               "the %s action (%s) tries to deliver the message",
46712
 
+                               act_other->action->name, act_other->location);  
46713
 
+                       return -1;
46714
 
+               }
46715
 
+       }
46716
 
+
46717
 
+       if ( (act_other->action->flags & SIEVE_ACTFLAG_SENDS_RESPONSE) > 0 ) {
46718
 
+               struct act_reject_context *rj_ctx;
46719
 
+
46720
 
+               if ( !act_other->executed ) {
46721
 
+                       sieve_runtime_error(renv, act->location, 
46722
 
+                               "reject/ereject action conflicts with other action: "
46723
 
+                               "the %s action (%s) also sends a response to the sender",
46724
 
+                               act_other->action->name, act_other->location);  
46725
 
+                       return -1;
46726
 
+               }
46727
 
+
46728
 
+               /* Conflicting action was already executed, transform reject into discard
46729
 
+                * equivalent.
46730
 
+                */
46731
 
+               rj_ctx = (struct act_reject_context *) act->context;
46732
 
+               rj_ctx->reason = NULL;
46733
 
+       }
46734
 
+
46735
 
+       return 0;
46736
 
+}
46737
 
46738
 
+static void act_reject_print
46739
 
+(const struct sieve_action *action ATTR_UNUSED, 
46740
 
+       const struct sieve_result_print_env *rpenv, void *context, bool *keep)  
46741
 
+{
46742
 
+       struct act_reject_context *rj_ctx = (struct act_reject_context *) context;
46743
 
+       
46744
 
+       if ( rj_ctx->reason != NULL ) {
46745
 
+               sieve_result_action_printf(rpenv, "reject message with reason: %s", 
46746
 
+                       str_sanitize(rj_ctx->reason, 128));
46747
 
+       } else {
46748
 
+               sieve_result_action_printf(rpenv, "reject message without sending a response (discard)");               
46749
 
+       }
46750
 
+       
46751
 
+       *keep = FALSE;
46752
 
+}
46753
 
+
46754
 
+static bool act_reject_send    
46755
 
+(const struct sieve_action_exec_env *aenv, struct act_reject_context *ctx,
46756
 
+       const char *sender, const char *recipient)
46757
 
+{
46758
 
+       const struct sieve_script_env *senv = aenv->scriptenv;
46759
 
+       const struct sieve_message_data *msgdata = aenv->msgdata;
46760
 
+       struct istream *input;
46761
 
+       void *smtp_handle;
46762
 
+       struct message_size hdr_size;
46763
 
+       FILE *f;
46764
 
+       const char *new_msgid, *boundary;
46765
 
+       const unsigned char *data;
46766
 
+       const char *header;
46767
 
+       size_t size;
46768
 
+       int ret;
46769
 
+
46770
 
+       /* Just to be sure */
46771
 
+       if ( senv->smtp_open == NULL || senv->smtp_close == NULL ) {
46772
 
+               sieve_result_warning(aenv, "reject action has no means to send mail");
46773
 
+               return TRUE;
46774
 
+       }
46775
 
+
46776
 
+       smtp_handle = senv->smtp_open(sender, NULL, &f);
46777
 
+
46778
 
+       new_msgid = sieve_message_get_new_id(senv);
46779
 
+       boundary = t_strdup_printf("%s/%s", my_pid, senv->hostname);
46780
 
+
46781
 
+       rfc2822_header_field_write(f, "X-Sieve", SIEVE_IMPLEMENTATION);
46782
 
+       rfc2822_header_field_write(f, "Message-ID", new_msgid);
46783
 
+       rfc2822_header_field_write(f, "Date", message_date_create(ioloop_time));
46784
 
+       rfc2822_header_field_printf(f, "From", "Mail Delivery Subsystem <%s>",
46785
 
+               senv->postmaster_address);
46786
 
+       rfc2822_header_field_printf(f, "To", "<%s>", sender);
46787
 
+       rfc2822_header_field_write(f, "Subject", "Automatically rejected mail");
46788
 
+       rfc2822_header_field_write(f, "Auto-Submitted", "auto-replied (rejected)");
46789
 
+       rfc2822_header_field_write(f, "Precedence", "bulk");
46790
 
+       
46791
 
+       rfc2822_header_field_write(f, "MIME-Version", "1.0");
46792
 
+       rfc2822_header_field_printf(f, "Content-Type", 
46793
 
+               "multipart/report; report-type=disposition-notification;\n"
46794
 
+               "boundary=\"%s\"", boundary);
46795
 
+       
46796
 
+       fprintf(f, "\r\nThis is a MIME-encapsulated message\r\n\r\n");
46797
 
+
46798
 
+       /* Human readable status report */
46799
 
+       fprintf(f, "--%s\r\n", boundary);
46800
 
+       fprintf(f, "Content-Type: text/plain; charset=utf-8\r\n");
46801
 
+       fprintf(f, "Content-Disposition: inline\r\n");
46802
 
+       fprintf(f, "Content-Transfer-Encoding: 8bit\r\n\r\n");
46803
 
+
46804
 
+       /* FIXME: var_expand_table expansion not possible */
46805
 
+       fprintf(f, "Your message to <%s> was automatically rejected:\r\n"       
46806
 
+               "%s\r\n", recipient, ctx->reason);
46807
 
+
46808
 
+       /* MDN status report */
46809
 
+       fprintf(f, "--%s\r\n"
46810
 
+               "Content-Type: message/disposition-notification\r\n\r\n", boundary);
46811
 
+       fprintf(f, "Reporting-UA: %s; Dovecot Mail Delivery Agent\r\n",
46812
 
+               senv->hostname);
46813
 
+       if (mail_get_first_header(msgdata->mail, "Original-Recipient", &header) > 0)
46814
 
+               fprintf(f, "Original-Recipient: rfc822; %s\r\n", header);
46815
 
+       fprintf(f, "Final-Recipient: rfc822; %s\r\n", recipient);
46816
 
+
46817
 
+       if ( msgdata->id != NULL )
46818
 
+               fprintf(f, "Original-Message-ID: %s\r\n", msgdata->id);
46819
 
+       fprintf(f, "Disposition: "
46820
 
+               "automatic-action/MDN-sent-automatically; deleted\r\n");
46821
 
+       fprintf(f, "\r\n");
46822
 
+
46823
 
+       /* original message's headers */
46824
 
+       fprintf(f, "--%s\r\nContent-Type: message/rfc822\r\n\r\n", boundary);
46825
 
+
46826
 
+       if (mail_get_stream(msgdata->mail, &hdr_size, NULL, &input) == 0) {
46827
 
+               /* Note: If you add more headers, they need to be sorted.
46828
 
+                * We'll drop Content-Type because we're not including the message
46829
 
+                * body, and having a multipart Content-Type may confuse some
46830
 
+                * MIME parsers when they don't see the message boundaries. 
46831
 
+                */
46832
 
+               static const char *const exclude_headers[] = {
46833
 
+                       "Content-Type"
46834
 
+               };
46835
 
+
46836
 
+               input = i_stream_create_header_filter(input,
46837
 
+                       HEADER_FILTER_EXCLUDE | HEADER_FILTER_NO_CR | HEADER_FILTER_HIDE_BODY, 
46838
 
+                       exclude_headers, N_ELEMENTS(exclude_headers), 
46839
 
+                       null_header_filter_callback, NULL);
46840
 
+
46841
 
+               while ((ret = i_stream_read_data(input, &data, &size, 0)) > 0) {
46842
 
+                       if (fwrite(data, size, 1, f) == 0)
46843
 
+                               break;
46844
 
+                       i_stream_skip(input, size);
46845
 
+               }
46846
 
+               i_stream_unref(&input);
46847
 
+                       
46848
 
+               i_assert(ret != 0);
46849
 
+       }
46850
 
+
46851
 
+       fprintf(f, "\r\n\r\n--%s--\r\n", boundary);
46852
 
+
46853
 
+       if ( !senv->smtp_close(smtp_handle) ) {
46854
 
+               sieve_result_error(aenv, 
46855
 
+                       "failed to send rejection message to <%s> "
46856
 
+                       "(refer to server log for more information)",
46857
 
+                       str_sanitize(sender, 80));
46858
 
+               return FALSE;
46859
 
+       }
46860
 
+       
46861
 
+       return TRUE;
46862
 
+}
46863
 
+
46864
 
+static bool act_reject_commit
46865
 
+(const struct sieve_action *action ATTR_UNUSED, 
46866
 
+       const struct sieve_action_exec_env *aenv, void *tr_context, bool *keep)
46867
 
+{
46868
 
+       struct act_reject_context *rj_ctx = (struct act_reject_context *) tr_context;
46869
 
+       const char *sender = sieve_message_get_sender(aenv->msgctx);
46870
 
+       const char *recipient = sieve_message_get_recipient(aenv->msgctx);
46871
 
+
46872
 
+       if ( recipient == NULL ) {
46873
 
+               sieve_result_warning(aenv, "reject action aborted: envelope recipient is <>");
46874
 
+               return TRUE;
46875
 
+       }
46876
 
+       
46877
 
+       if ( rj_ctx->reason == NULL ) {
46878
 
+               sieve_result_log(aenv, "not sending reject message (would cause second response to sender)");
46879
 
+    
46880
 
+               *keep = FALSE;
46881
 
+               return TRUE;
46882
 
+       }
46883
 
+
46884
 
+       if ( sender == NULL ) {
46885
 
+               sieve_result_log(aenv, "not sending reject message to <>");
46886
 
+    
46887
 
+               *keep = FALSE;
46888
 
+               return TRUE;
46889
 
+       }
46890
 
+               
46891
 
+       if ( act_reject_send(aenv, rj_ctx, sender, recipient) ) {
46892
 
+               sieve_result_log(aenv, "rejected message from <%s> (%s)", str_sanitize(sender, 80),
46893
 
+                       ( rj_ctx->ereject ? "ereject" : "reject" ));
46894
 
+
46895
 
+               *keep = FALSE;
46896
 
+               return TRUE;
46897
 
+       }
46898
 
+         
46899
 
+       return FALSE;
46900
 
+}
46901
 
+
46902
 
+
46903
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/Makefile.am dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/Makefile.am
46904
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/Makefile.am    1970-01-01 01:00:00.000000000 +0100
46905
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/Makefile.am     2009-08-21 00:52:15.000000000 +0200
46906
 
@@ -0,0 +1,136 @@
46907
 
+SUBDIRS = plugins
46908
 
+
46909
 
+noinst_LTLIBRARIES = libsieve.la
46910
 
+
46911
 
+AM_CPPFLAGS = \
46912
 
+       -I$(dovecot_incdir) \
46913
 
+       -I$(dovecot_incdir)/src/lib \
46914
 
+       -I$(dovecot_incdir)/src/lib-mail \
46915
 
+       -I$(dovecot_incdir)/src/lib-storage \
46916
 
+       -I$(dovecot_incdir)/src/lib-imap
46917
 
+
46918
 
+tests = \
46919
 
+       tst-truefalse.c \
46920
 
+       tst-not.c \
46921
 
+       tst-anyof.c \
46922
 
+       tst-allof.c \
46923
 
+       tst-address.c \
46924
 
+       tst-header.c \
46925
 
+       tst-exists.c \
46926
 
+       tst-size.c
46927
 
+
46928
 
+commands = \
46929
 
+       cmd-require.c \
46930
 
+       cmd-stop.c \
46931
 
+       cmd-if.c \
46932
 
+       cmd-keep.c \
46933
 
+       cmd-redirect.c \
46934
 
+       cmd-discard.c
46935
 
+
46936
 
+extensions = \
46937
 
+       ext-fileinto.c \
46938
 
+       ext-reject.c \
46939
 
+       ext-envelope.c \
46940
 
+       ext-encoded-character.c
46941
 
+
46942
 
+match_types = \
46943
 
+       mcht-is.c \
46944
 
+       mcht-contains.c \
46945
 
+       mcht-matches.c
46946
 
+
46947
 
+comparators = \
46948
 
+       cmp-i-octet.c \
46949
 
+       cmp-i-ascii-casemap.c
46950
 
+
46951
 
+if BUILD_UNFINISHED
46952
 
+unfinished_plugins =
46953
 
+endif
46954
 
+
46955
 
+# These are not actual plugins just yet...
46956
 
+plugins = \
46957
 
+       ./plugins/vacation/libsieve_ext_vacation.la \
46958
 
+       ./plugins/subaddress/libsieve_ext_subaddress.la \
46959
 
+       ./plugins/comparator-i-ascii-numeric/libsieve_ext_comparator-i-ascii-numeric.la \
46960
 
+       ./plugins/relational/libsieve_ext_relational.la \
46961
 
+       ./plugins/regex/libsieve_ext_regex.la \
46962
 
+       ./plugins/copy/libsieve_ext_copy.la \
46963
 
+       ./plugins/imap4flags/libsieve_ext_imap4flags.la \
46964
 
+       ./plugins/include/libsieve_ext_include.la \
46965
 
+       ./plugins/body/libsieve_ext_body.la \
46966
 
+       ./plugins/variables/libsieve_ext_variables.la \
46967
 
+       ./plugins/enotify/libsieve_ext_enotify.la \
46968
 
+       ./plugins/notify/libsieve_ext_notify.la \
46969
 
+       ./plugins/environment/libsieve_ext_environment.la \
46970
 
+       ./plugins/mailbox/libsieve_ext_mailbox.la \
46971
 
+       ./plugins/date/libsieve_ext_date.la \
46972
 
+       $(unfinished_plugins)
46973
 
+
46974
 
+libsieve_la_DEPENDENCIES = $(plugins)
46975
 
+libsieve_la_LIBADD = $(plugins)
46976
 
+
46977
 
+libsieve_la_SOURCES = \
46978
 
+       rfc2822.c \
46979
 
+       sieve-limits.c \
46980
 
+       sieve-message.c \
46981
 
+       sieve-lexer.c \
46982
 
+       sieve-script.c \
46983
 
+       sieve-ast.c \
46984
 
+       sieve-binary.c \
46985
 
+       sieve-parser.c \
46986
 
+       sieve-address.c \
46987
 
+       sieve-validator.c \
46988
 
+       sieve-generator.c \
46989
 
+       sieve-interpreter.c \
46990
 
+       sieve-code-dumper.c \
46991
 
+       sieve-binary-dumper.c \
46992
 
+       sieve-result.c \
46993
 
+       sieve-error.c \
46994
 
+       sieve-objects.c \
46995
 
+       sieve-comparators.c \
46996
 
+       sieve-match-types.c \
46997
 
+       sieve-address-parts.c \
46998
 
+       sieve-match.c \
46999
 
+       sieve-commands.c \
47000
 
+       sieve-code.c \
47001
 
+       sieve-actions.c \
47002
 
+       sieve-extensions.c \
47003
 
+       $(comparators) \
47004
 
+       $(match_types) \
47005
 
+       $(tests) \
47006
 
+       $(commands) \
47007
 
+       $(extensions) \
47008
 
+       sieve.c 
47009
 
+
47010
 
+noinst_HEADERS = \
47011
 
+       rfc2822.h \
47012
 
+       sieve-config.h \
47013
 
+       sieve-types.h \
47014
 
+       sieve-common.h \
47015
 
+       sieve-limits.h \
47016
 
+       sieve-message.h \
47017
 
+       sieve-lexer.h \
47018
 
+       sieve-script.h \
47019
 
+       sieve-script-private.h \
47020
 
+       sieve-ast.h \
47021
 
+       sieve-binary.h \
47022
 
+       sieve-parser.h \
47023
 
+       sieve-address.h \
47024
 
+       sieve-validator.h \
47025
 
+       sieve-generator.h \
47026
 
+       sieve-interpreter.h \
47027
 
+       sieve-code-dumper.h \
47028
 
+       sieve-binary-dumper.h \
47029
 
+       sieve-dump.h \
47030
 
+       sieve-result.h \
47031
 
+       sieve-error.h \
47032
 
+       sieve-error-private.h \
47033
 
+       sieve-objects.h \
47034
 
+       sieve-match.h \
47035
 
+       sieve-comparators.h \
47036
 
+       sieve-match-types.h \
47037
 
+       sieve-address-parts.h \
47038
 
+       sieve-commands.h \
47039
 
+       sieve-code.h \
47040
 
+       sieve-actions.h \
47041
 
+       sieve-extensions.h \
47042
 
+       sieve.h
47043
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/Makefile.in dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/Makefile.in
47044
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/Makefile.in    1970-01-01 01:00:00.000000000 +0100
47045
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/Makefile.in     2009-08-21 00:55:42.000000000 +0200
47046
 
@@ -0,0 +1,771 @@
47047
 
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
47048
 
+# @configure_input@
47049
 
+
47050
 
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
47051
 
+# 2003, 2004, 2005, 2006, 2007, 2008  Free Software Foundation, Inc.
47052
 
+# This Makefile.in is free software; the Free Software Foundation
47053
 
+# gives unlimited permission to copy and/or distribute it,
47054
 
+# with or without modifications, as long as this notice is preserved.
47055
 
+
47056
 
+# This program is distributed in the hope that it will be useful,
47057
 
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
47058
 
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
47059
 
+# PARTICULAR PURPOSE.
47060
 
+
47061
 
+@SET_MAKE@
47062
 
+
47063
 
+
47064
 
+VPATH = @srcdir@
47065
 
+pkgdatadir = $(datadir)/@PACKAGE@
47066
 
+pkglibdir = $(libdir)/@PACKAGE@
47067
 
+pkgincludedir = $(includedir)/@PACKAGE@
47068
 
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
47069
 
+install_sh_DATA = $(install_sh) -c -m 644
47070
 
+install_sh_PROGRAM = $(install_sh) -c
47071
 
+install_sh_SCRIPT = $(install_sh) -c
47072
 
+INSTALL_HEADER = $(INSTALL_DATA)
47073
 
+transform = $(program_transform_name)
47074
 
+NORMAL_INSTALL = :
47075
 
+PRE_INSTALL = :
47076
 
+POST_INSTALL = :
47077
 
+NORMAL_UNINSTALL = :
47078
 
+PRE_UNINSTALL = :
47079
 
+POST_UNINSTALL = :
47080
 
+build_triplet = @build@
47081
 
+host_triplet = @host@
47082
 
+subdir = src/lib-sieve
47083
 
+DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
47084
 
+       $(srcdir)/Makefile.in
47085
 
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
47086
 
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
47087
 
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
47088
 
+       $(ACLOCAL_M4)
47089
 
+mkinstalldirs = $(install_sh) -d
47090
 
+CONFIG_HEADER = $(top_builddir)/dummy-config.h \
47091
 
+       $(top_builddir)/dsieve-config.h
47092
 
+CONFIG_CLEAN_FILES =
47093
 
+LTLIBRARIES = $(noinst_LTLIBRARIES)
47094
 
+am__DEPENDENCIES_1 =
47095
 
+am__DEPENDENCIES_2 = ./plugins/vacation/libsieve_ext_vacation.la \
47096
 
+       ./plugins/subaddress/libsieve_ext_subaddress.la \
47097
 
+       ./plugins/comparator-i-ascii-numeric/libsieve_ext_comparator-i-ascii-numeric.la \
47098
 
+       ./plugins/relational/libsieve_ext_relational.la \
47099
 
+       ./plugins/regex/libsieve_ext_regex.la \
47100
 
+       ./plugins/copy/libsieve_ext_copy.la \
47101
 
+       ./plugins/imap4flags/libsieve_ext_imap4flags.la \
47102
 
+       ./plugins/include/libsieve_ext_include.la \
47103
 
+       ./plugins/body/libsieve_ext_body.la \
47104
 
+       ./plugins/variables/libsieve_ext_variables.la \
47105
 
+       ./plugins/enotify/libsieve_ext_enotify.la \
47106
 
+       ./plugins/notify/libsieve_ext_notify.la \
47107
 
+       ./plugins/environment/libsieve_ext_environment.la \
47108
 
+       ./plugins/mailbox/libsieve_ext_mailbox.la \
47109
 
+       ./plugins/date/libsieve_ext_date.la $(am__DEPENDENCIES_1)
47110
 
+am__objects_1 = cmp-i-octet.lo cmp-i-ascii-casemap.lo
47111
 
+am__objects_2 = mcht-is.lo mcht-contains.lo mcht-matches.lo
47112
 
+am__objects_3 = tst-truefalse.lo tst-not.lo tst-anyof.lo tst-allof.lo \
47113
 
+       tst-address.lo tst-header.lo tst-exists.lo tst-size.lo
47114
 
+am__objects_4 = cmd-require.lo cmd-stop.lo cmd-if.lo cmd-keep.lo \
47115
 
+       cmd-redirect.lo cmd-discard.lo
47116
 
+am__objects_5 = ext-fileinto.lo ext-reject.lo ext-envelope.lo \
47117
 
+       ext-encoded-character.lo
47118
 
+am_libsieve_la_OBJECTS = rfc2822.lo sieve-limits.lo sieve-message.lo \
47119
 
+       sieve-lexer.lo sieve-script.lo sieve-ast.lo sieve-binary.lo \
47120
 
+       sieve-parser.lo sieve-address.lo sieve-validator.lo \
47121
 
+       sieve-generator.lo sieve-interpreter.lo sieve-code-dumper.lo \
47122
 
+       sieve-binary-dumper.lo sieve-result.lo sieve-error.lo \
47123
 
+       sieve-objects.lo sieve-comparators.lo sieve-match-types.lo \
47124
 
+       sieve-address-parts.lo sieve-match.lo sieve-commands.lo \
47125
 
+       sieve-code.lo sieve-actions.lo sieve-extensions.lo \
47126
 
+       $(am__objects_1) $(am__objects_2) $(am__objects_3) \
47127
 
+       $(am__objects_4) $(am__objects_5) sieve.lo
47128
 
+libsieve_la_OBJECTS = $(am_libsieve_la_OBJECTS)
47129
 
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
47130
 
+depcomp = $(SHELL) $(top_srcdir)/depcomp
47131
 
+am__depfiles_maybe = depfiles
47132
 
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
47133
 
+       $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
47134
 
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
47135
 
+       --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
47136
 
+       $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
47137
 
+CCLD = $(CC)
47138
 
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
47139
 
+       --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
47140
 
+       $(LDFLAGS) -o $@
47141
 
+SOURCES = $(libsieve_la_SOURCES)
47142
 
+DIST_SOURCES = $(libsieve_la_SOURCES)
47143
 
+RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
47144
 
+       html-recursive info-recursive install-data-recursive \
47145
 
+       install-dvi-recursive install-exec-recursive \
47146
 
+       install-html-recursive install-info-recursive \
47147
 
+       install-pdf-recursive install-ps-recursive install-recursive \
47148
 
+       installcheck-recursive installdirs-recursive pdf-recursive \
47149
 
+       ps-recursive uninstall-recursive
47150
 
+HEADERS = $(noinst_HEADERS)
47151
 
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive        \
47152
 
+  distclean-recursive maintainer-clean-recursive
47153
 
+ETAGS = etags
47154
 
+CTAGS = ctags
47155
 
+DIST_SUBDIRS = $(SUBDIRS)
47156
 
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
47157
 
+ACLOCAL = @ACLOCAL@
47158
 
+AMTAR = @AMTAR@
47159
 
+AR = @AR@
47160
 
+AUTOCONF = @AUTOCONF@
47161
 
+AUTOHEADER = @AUTOHEADER@
47162
 
+AUTOMAKE = @AUTOMAKE@
47163
 
+AWK = @AWK@
47164
 
+CC = @CC@
47165
 
+CCDEPMODE = @CCDEPMODE@
47166
 
+CFLAGS = @CFLAGS@
47167
 
+CPP = @CPP@
47168
 
+CPPFLAGS = @CPPFLAGS@
47169
 
+CYGPATH_W = @CYGPATH_W@
47170
 
+DEFS = @DEFS@
47171
 
+DEPDIR = @DEPDIR@
47172
 
+DSYMUTIL = @DSYMUTIL@
47173
 
+DUMPBIN = @DUMPBIN@
47174
 
+ECHO_C = @ECHO_C@
47175
 
+ECHO_N = @ECHO_N@
47176
 
+ECHO_T = @ECHO_T@
47177
 
+EGREP = @EGREP@
47178
 
+EXEEXT = @EXEEXT@
47179
 
+FGREP = @FGREP@
47180
 
+GREP = @GREP@
47181
 
+INSTALL = @INSTALL@
47182
 
+INSTALL_DATA = @INSTALL_DATA@
47183
 
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
47184
 
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
47185
 
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
47186
 
+LD = @LD@
47187
 
+LDFLAGS = @LDFLAGS@
47188
 
+LIBICONV = @LIBICONV@
47189
 
+LIBOBJS = @LIBOBJS@
47190
 
+LIBS = @LIBS@
47191
 
+LIBTOOL = @LIBTOOL@
47192
 
+LIPO = @LIPO@
47193
 
+LN_S = @LN_S@
47194
 
+LTLIBOBJS = @LTLIBOBJS@
47195
 
+MAINT = @MAINT@
47196
 
+MAKEINFO = @MAKEINFO@
47197
 
+MKDIR_P = @MKDIR_P@
47198
 
+MODULE_LIBS = @MODULE_LIBS@
47199
 
+NM = @NM@
47200
 
+NMEDIT = @NMEDIT@
47201
 
+OBJDUMP = @OBJDUMP@
47202
 
+OBJEXT = @OBJEXT@
47203
 
+OTOOL = @OTOOL@
47204
 
+OTOOL64 = @OTOOL64@
47205
 
+PACKAGE = @PACKAGE@
47206
 
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
47207
 
+PACKAGE_NAME = @PACKAGE_NAME@
47208
 
+PACKAGE_STRING = @PACKAGE_STRING@
47209
 
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
47210
 
+PACKAGE_URL = @PACKAGE_URL@
47211
 
+PACKAGE_VERSION = @PACKAGE_VERSION@
47212
 
+PATH_SEPARATOR = @PATH_SEPARATOR@
47213
 
+RAND_LIBS = @RAND_LIBS@
47214
 
+RANLIB = @RANLIB@
47215
 
+SED = @SED@
47216
 
+SET_MAKE = @SET_MAKE@
47217
 
+SHELL = @SHELL@
47218
 
+STORAGE_LIBS = @STORAGE_LIBS@
47219
 
+STRIP = @STRIP@
47220
 
+VERSION = @VERSION@
47221
 
+abs_builddir = @abs_builddir@
47222
 
+abs_srcdir = @abs_srcdir@
47223
 
+abs_top_builddir = @abs_top_builddir@
47224
 
+abs_top_srcdir = @abs_top_srcdir@
47225
 
+ac_ct_CC = @ac_ct_CC@
47226
 
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
47227
 
+am__include = @am__include@
47228
 
+am__leading_dot = @am__leading_dot@
47229
 
+am__quote = @am__quote@
47230
 
+am__tar = @am__tar@
47231
 
+am__untar = @am__untar@
47232
 
+bindir = @bindir@
47233
 
+build = @build@
47234
 
+build_alias = @build_alias@
47235
 
+build_cpu = @build_cpu@
47236
 
+build_os = @build_os@
47237
 
+build_vendor = @build_vendor@
47238
 
+builddir = @builddir@
47239
 
+datadir = @datadir@
47240
 
+datarootdir = @datarootdir@
47241
 
+docdir = @docdir@
47242
 
+dovecot_incdir = @dovecot_incdir@
47243
 
+dovecotdir = @dovecotdir@
47244
 
+dvidir = @dvidir@
47245
 
+exec_prefix = @exec_prefix@
47246
 
+host = @host@
47247
 
+host_alias = @host_alias@
47248
 
+host_cpu = @host_cpu@
47249
 
+host_os = @host_os@
47250
 
+host_vendor = @host_vendor@
47251
 
+htmldir = @htmldir@
47252
 
+includedir = @includedir@
47253
 
+infodir = @infodir@
47254
 
+install_sh = @install_sh@
47255
 
+libdir = @libdir@
47256
 
+libexecdir = @libexecdir@
47257
 
+localedir = @localedir@
47258
 
+localstatedir = @localstatedir@
47259
 
+lt_ECHO = @lt_ECHO@
47260
 
+mandir = @mandir@
47261
 
+mkdir_p = @mkdir_p@
47262
 
+moduledir = @moduledir@
47263
 
+oldincludedir = @oldincludedir@
47264
 
+pdfdir = @pdfdir@
47265
 
+prefix = @prefix@
47266
 
+program_transform_name = @program_transform_name@
47267
 
+psdir = @psdir@
47268
 
+sbindir = @sbindir@
47269
 
+sharedstatedir = @sharedstatedir@
47270
 
+srcdir = @srcdir@
47271
 
+sysconfdir = @sysconfdir@
47272
 
+target_alias = @target_alias@
47273
 
+top_build_prefix = @top_build_prefix@
47274
 
+top_builddir = @top_builddir@
47275
 
+top_srcdir = @top_srcdir@
47276
 
+SUBDIRS = plugins
47277
 
+noinst_LTLIBRARIES = libsieve.la
47278
 
+AM_CPPFLAGS = \
47279
 
+       -I$(dovecot_incdir) \
47280
 
+       -I$(dovecot_incdir)/src/lib \
47281
 
+       -I$(dovecot_incdir)/src/lib-mail \
47282
 
+       -I$(dovecot_incdir)/src/lib-storage \
47283
 
+       -I$(dovecot_incdir)/src/lib-imap
47284
 
+
47285
 
+tests = \
47286
 
+       tst-truefalse.c \
47287
 
+       tst-not.c \
47288
 
+       tst-anyof.c \
47289
 
+       tst-allof.c \
47290
 
+       tst-address.c \
47291
 
+       tst-header.c \
47292
 
+       tst-exists.c \
47293
 
+       tst-size.c
47294
 
+
47295
 
+commands = \
47296
 
+       cmd-require.c \
47297
 
+       cmd-stop.c \
47298
 
+       cmd-if.c \
47299
 
+       cmd-keep.c \
47300
 
+       cmd-redirect.c \
47301
 
+       cmd-discard.c
47302
 
+
47303
 
+extensions = \
47304
 
+       ext-fileinto.c \
47305
 
+       ext-reject.c \
47306
 
+       ext-envelope.c \
47307
 
+       ext-encoded-character.c
47308
 
+
47309
 
+match_types = \
47310
 
+       mcht-is.c \
47311
 
+       mcht-contains.c \
47312
 
+       mcht-matches.c
47313
 
+
47314
 
+comparators = \
47315
 
+       cmp-i-octet.c \
47316
 
+       cmp-i-ascii-casemap.c
47317
 
+
47318
 
+@BUILD_UNFINISHED_TRUE@unfinished_plugins = 
47319
 
+
47320
 
+# These are not actual plugins just yet...
47321
 
+plugins = \
47322
 
+       ./plugins/vacation/libsieve_ext_vacation.la \
47323
 
+       ./plugins/subaddress/libsieve_ext_subaddress.la \
47324
 
+       ./plugins/comparator-i-ascii-numeric/libsieve_ext_comparator-i-ascii-numeric.la \
47325
 
+       ./plugins/relational/libsieve_ext_relational.la \
47326
 
+       ./plugins/regex/libsieve_ext_regex.la \
47327
 
+       ./plugins/copy/libsieve_ext_copy.la \
47328
 
+       ./plugins/imap4flags/libsieve_ext_imap4flags.la \
47329
 
+       ./plugins/include/libsieve_ext_include.la \
47330
 
+       ./plugins/body/libsieve_ext_body.la \
47331
 
+       ./plugins/variables/libsieve_ext_variables.la \
47332
 
+       ./plugins/enotify/libsieve_ext_enotify.la \
47333
 
+       ./plugins/notify/libsieve_ext_notify.la \
47334
 
+       ./plugins/environment/libsieve_ext_environment.la \
47335
 
+       ./plugins/mailbox/libsieve_ext_mailbox.la \
47336
 
+       ./plugins/date/libsieve_ext_date.la \
47337
 
+       $(unfinished_plugins)
47338
 
+
47339
 
+libsieve_la_DEPENDENCIES = $(plugins)
47340
 
+libsieve_la_LIBADD = $(plugins)
47341
 
+libsieve_la_SOURCES = \
47342
 
+       rfc2822.c \
47343
 
+       sieve-limits.c \
47344
 
+       sieve-message.c \
47345
 
+       sieve-lexer.c \
47346
 
+       sieve-script.c \
47347
 
+       sieve-ast.c \
47348
 
+       sieve-binary.c \
47349
 
+       sieve-parser.c \
47350
 
+       sieve-address.c \
47351
 
+       sieve-validator.c \
47352
 
+       sieve-generator.c \
47353
 
+       sieve-interpreter.c \
47354
 
+       sieve-code-dumper.c \
47355
 
+       sieve-binary-dumper.c \
47356
 
+       sieve-result.c \
47357
 
+       sieve-error.c \
47358
 
+       sieve-objects.c \
47359
 
+       sieve-comparators.c \
47360
 
+       sieve-match-types.c \
47361
 
+       sieve-address-parts.c \
47362
 
+       sieve-match.c \
47363
 
+       sieve-commands.c \
47364
 
+       sieve-code.c \
47365
 
+       sieve-actions.c \
47366
 
+       sieve-extensions.c \
47367
 
+       $(comparators) \
47368
 
+       $(match_types) \
47369
 
+       $(tests) \
47370
 
+       $(commands) \
47371
 
+       $(extensions) \
47372
 
+       sieve.c 
47373
 
+
47374
 
+noinst_HEADERS = \
47375
 
+       rfc2822.h \
47376
 
+       sieve-config.h \
47377
 
+       sieve-types.h \
47378
 
+       sieve-common.h \
47379
 
+       sieve-limits.h \
47380
 
+       sieve-message.h \
47381
 
+       sieve-lexer.h \
47382
 
+       sieve-script.h \
47383
 
+       sieve-script-private.h \
47384
 
+       sieve-ast.h \
47385
 
+       sieve-binary.h \
47386
 
+       sieve-parser.h \
47387
 
+       sieve-address.h \
47388
 
+       sieve-validator.h \
47389
 
+       sieve-generator.h \
47390
 
+       sieve-interpreter.h \
47391
 
+       sieve-code-dumper.h \
47392
 
+       sieve-binary-dumper.h \
47393
 
+       sieve-dump.h \
47394
 
+       sieve-result.h \
47395
 
+       sieve-error.h \
47396
 
+       sieve-error-private.h \
47397
 
+       sieve-objects.h \
47398
 
+       sieve-match.h \
47399
 
+       sieve-comparators.h \
47400
 
+       sieve-match-types.h \
47401
 
+       sieve-address-parts.h \
47402
 
+       sieve-commands.h \
47403
 
+       sieve-code.h \
47404
 
+       sieve-actions.h \
47405
 
+       sieve-extensions.h \
47406
 
+       sieve.h
47407
 
+
47408
 
+all: all-recursive
47409
 
+
47410
 
+.SUFFIXES:
47411
 
+.SUFFIXES: .c .lo .o .obj
47412
 
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
47413
 
+       @for dep in $?; do \
47414
 
+         case '$(am__configure_deps)' in \
47415
 
+           *$$dep*) \
47416
 
+             ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
47417
 
+               && { if test -f $@; then exit 0; else break; fi; }; \
47418
 
+             exit 1;; \
47419
 
+         esac; \
47420
 
+       done; \
47421
 
+       echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign  src/lib-sieve/Makefile'; \
47422
 
+       cd $(top_srcdir) && \
47423
 
+         $(AUTOMAKE) --foreign  src/lib-sieve/Makefile
47424
 
+.PRECIOUS: Makefile
47425
 
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
47426
 
+       @case '$?' in \
47427
 
+         *config.status*) \
47428
 
+           cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
47429
 
+         *) \
47430
 
+           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
47431
 
+           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
47432
 
+       esac;
47433
 
+
47434
 
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
47435
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
47436
 
+
47437
 
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
47438
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
47439
 
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
47440
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
47441
 
+
47442
 
+clean-noinstLTLIBRARIES:
47443
 
+       -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
47444
 
+       @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
47445
 
+         dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
47446
 
+         test "$$dir" != "$$p" || dir=.; \
47447
 
+         echo "rm -f \"$${dir}/so_locations\""; \
47448
 
+         rm -f "$${dir}/so_locations"; \
47449
 
+       done
47450
 
+libsieve.la: $(libsieve_la_OBJECTS) $(libsieve_la_DEPENDENCIES) 
47451
 
+       $(LINK)  $(libsieve_la_OBJECTS) $(libsieve_la_LIBADD) $(LIBS)
47452
 
+
47453
 
+mostlyclean-compile:
47454
 
+       -rm -f *.$(OBJEXT)
47455
 
+
47456
 
+distclean-compile:
47457
 
+       -rm -f *.tab.c
47458
 
+
47459
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd-discard.Plo@am__quote@
47460
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd-if.Plo@am__quote@
47461
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd-keep.Plo@am__quote@
47462
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd-redirect.Plo@am__quote@
47463
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd-require.Plo@am__quote@
47464
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd-stop.Plo@am__quote@
47465
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmp-i-ascii-casemap.Plo@am__quote@
47466
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmp-i-octet.Plo@am__quote@
47467
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-encoded-character.Plo@am__quote@
47468
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-envelope.Plo@am__quote@
47469
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-fileinto.Plo@am__quote@
47470
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-reject.Plo@am__quote@
47471
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mcht-contains.Plo@am__quote@
47472
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mcht-is.Plo@am__quote@
47473
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mcht-matches.Plo@am__quote@
47474
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rfc2822.Plo@am__quote@
47475
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-actions.Plo@am__quote@
47476
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-address-parts.Plo@am__quote@
47477
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-address.Plo@am__quote@
47478
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-ast.Plo@am__quote@
47479
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-binary-dumper.Plo@am__quote@
47480
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-binary.Plo@am__quote@
47481
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-code-dumper.Plo@am__quote@
47482
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-code.Plo@am__quote@
47483
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-commands.Plo@am__quote@
47484
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-comparators.Plo@am__quote@
47485
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-error.Plo@am__quote@
47486
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-extensions.Plo@am__quote@
47487
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-generator.Plo@am__quote@
47488
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-interpreter.Plo@am__quote@
47489
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-lexer.Plo@am__quote@
47490
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-limits.Plo@am__quote@
47491
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-match-types.Plo@am__quote@
47492
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-match.Plo@am__quote@
47493
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-message.Plo@am__quote@
47494
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-objects.Plo@am__quote@
47495
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-parser.Plo@am__quote@
47496
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-result.Plo@am__quote@
47497
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-script.Plo@am__quote@
47498
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-validator.Plo@am__quote@
47499
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve.Plo@am__quote@
47500
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tst-address.Plo@am__quote@
47501
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tst-allof.Plo@am__quote@
47502
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tst-anyof.Plo@am__quote@
47503
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tst-exists.Plo@am__quote@
47504
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tst-header.Plo@am__quote@
47505
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tst-not.Plo@am__quote@
47506
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tst-size.Plo@am__quote@
47507
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tst-truefalse.Plo@am__quote@
47508
 
+
47509
 
+.c.o:
47510
 
+@am__fastdepCC_TRUE@   $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
47511
 
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
47512
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
47513
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
47514
 
+@am__fastdepCC_FALSE@  $(COMPILE) -c $<
47515
 
+
47516
 
+.c.obj:
47517
 
+@am__fastdepCC_TRUE@   $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
47518
 
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
47519
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
47520
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
47521
 
+@am__fastdepCC_FALSE@  $(COMPILE) -c `$(CYGPATH_W) '$<'`
47522
 
+
47523
 
+.c.lo:
47524
 
+@am__fastdepCC_TRUE@   $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
47525
 
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
47526
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
47527
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
47528
 
+@am__fastdepCC_FALSE@  $(LTCOMPILE) -c -o $@ $<
47529
 
+
47530
 
+mostlyclean-libtool:
47531
 
+       -rm -f *.lo
47532
 
+
47533
 
+clean-libtool:
47534
 
+       -rm -rf .libs _libs
47535
 
+
47536
 
+# This directory's subdirectories are mostly independent; you can cd
47537
 
+# into them and run `make' without going through this Makefile.
47538
 
+# To change the values of `make' variables: instead of editing Makefiles,
47539
 
+# (1) if the variable is set in `config.status', edit `config.status'
47540
 
+#     (which will cause the Makefiles to be regenerated when you run `make');
47541
 
+# (2) otherwise, pass the desired values on the `make' command line.
47542
 
+$(RECURSIVE_TARGETS):
47543
 
+       @failcom='exit 1'; \
47544
 
+       for f in x $$MAKEFLAGS; do \
47545
 
+         case $$f in \
47546
 
+           *=* | --[!k]*);; \
47547
 
+           *k*) failcom='fail=yes';; \
47548
 
+         esac; \
47549
 
+       done; \
47550
 
+       dot_seen=no; \
47551
 
+       target=`echo $@ | sed s/-recursive//`; \
47552
 
+       list='$(SUBDIRS)'; for subdir in $$list; do \
47553
 
+         echo "Making $$target in $$subdir"; \
47554
 
+         if test "$$subdir" = "."; then \
47555
 
+           dot_seen=yes; \
47556
 
+           local_target="$$target-am"; \
47557
 
+         else \
47558
 
+           local_target="$$target"; \
47559
 
+         fi; \
47560
 
+         (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
47561
 
+         || eval $$failcom; \
47562
 
+       done; \
47563
 
+       if test "$$dot_seen" = "no"; then \
47564
 
+         $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
47565
 
+       fi; test -z "$$fail"
47566
 
+
47567
 
+$(RECURSIVE_CLEAN_TARGETS):
47568
 
+       @failcom='exit 1'; \
47569
 
+       for f in x $$MAKEFLAGS; do \
47570
 
+         case $$f in \
47571
 
+           *=* | --[!k]*);; \
47572
 
+           *k*) failcom='fail=yes';; \
47573
 
+         esac; \
47574
 
+       done; \
47575
 
+       dot_seen=no; \
47576
 
+       case "$@" in \
47577
 
+         distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
47578
 
+         *) list='$(SUBDIRS)' ;; \
47579
 
+       esac; \
47580
 
+       rev=''; for subdir in $$list; do \
47581
 
+         if test "$$subdir" = "."; then :; else \
47582
 
+           rev="$$subdir $$rev"; \
47583
 
+         fi; \
47584
 
+       done; \
47585
 
+       rev="$$rev ."; \
47586
 
+       target=`echo $@ | sed s/-recursive//`; \
47587
 
+       for subdir in $$rev; do \
47588
 
+         echo "Making $$target in $$subdir"; \
47589
 
+         if test "$$subdir" = "."; then \
47590
 
+           local_target="$$target-am"; \
47591
 
+         else \
47592
 
+           local_target="$$target"; \
47593
 
+         fi; \
47594
 
+         (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
47595
 
+         || eval $$failcom; \
47596
 
+       done && test -z "$$fail"
47597
 
+tags-recursive:
47598
 
+       list='$(SUBDIRS)'; for subdir in $$list; do \
47599
 
+         test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
47600
 
+       done
47601
 
+ctags-recursive:
47602
 
+       list='$(SUBDIRS)'; for subdir in $$list; do \
47603
 
+         test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
47604
 
+       done
47605
 
+
47606
 
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
47607
 
+       list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
47608
 
+       unique=`for i in $$list; do \
47609
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
47610
 
+         done | \
47611
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
47612
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
47613
 
+       mkid -fID $$unique
47614
 
+tags: TAGS
47615
 
+
47616
 
+TAGS: tags-recursive $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
47617
 
+               $(TAGS_FILES) $(LISP)
47618
 
+       tags=; \
47619
 
+       here=`pwd`; \
47620
 
+       if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
47621
 
+         include_option=--etags-include; \
47622
 
+         empty_fix=.; \
47623
 
+       else \
47624
 
+         include_option=--include; \
47625
 
+         empty_fix=; \
47626
 
+       fi; \
47627
 
+       list='$(SUBDIRS)'; for subdir in $$list; do \
47628
 
+         if test "$$subdir" = .; then :; else \
47629
 
+           test ! -f $$subdir/TAGS || \
47630
 
+             tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \
47631
 
+         fi; \
47632
 
+       done; \
47633
 
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
47634
 
+       unique=`for i in $$list; do \
47635
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
47636
 
+         done | \
47637
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
47638
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
47639
 
+       if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
47640
 
+         test -n "$$unique" || unique=$$empty_fix; \
47641
 
+         $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
47642
 
+           $$tags $$unique; \
47643
 
+       fi
47644
 
+ctags: CTAGS
47645
 
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
47646
 
+               $(TAGS_FILES) $(LISP)
47647
 
+       tags=; \
47648
 
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
47649
 
+       unique=`for i in $$list; do \
47650
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
47651
 
+         done | \
47652
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
47653
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
47654
 
+       test -z "$(CTAGS_ARGS)$$tags$$unique" \
47655
 
+         || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
47656
 
+            $$tags $$unique
47657
 
+
47658
 
+GTAGS:
47659
 
+       here=`$(am__cd) $(top_builddir) && pwd` \
47660
 
+         && cd $(top_srcdir) \
47661
 
+         && gtags -i $(GTAGS_ARGS) $$here
47662
 
+
47663
 
+distclean-tags:
47664
 
+       -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
47665
 
+
47666
 
+distdir: $(DISTFILES)
47667
 
+       @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
47668
 
+       topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
47669
 
+       list='$(DISTFILES)'; \
47670
 
+         dist_files=`for file in $$list; do echo $$file; done | \
47671
 
+         sed -e "s|^$$srcdirstrip/||;t" \
47672
 
+             -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
47673
 
+       case $$dist_files in \
47674
 
+         */*) $(MKDIR_P) `echo "$$dist_files" | \
47675
 
+                          sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
47676
 
+                          sort -u` ;; \
47677
 
+       esac; \
47678
 
+       for file in $$dist_files; do \
47679
 
+         if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
47680
 
+         if test -d $$d/$$file; then \
47681
 
+           dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
47682
 
+           if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
47683
 
+             cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
47684
 
+           fi; \
47685
 
+           cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
47686
 
+         else \
47687
 
+           test -f $(distdir)/$$file \
47688
 
+           || cp -p $$d/$$file $(distdir)/$$file \
47689
 
+           || exit 1; \
47690
 
+         fi; \
47691
 
+       done
47692
 
+       list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
47693
 
+         if test "$$subdir" = .; then :; else \
47694
 
+           test -d "$(distdir)/$$subdir" \
47695
 
+           || $(MKDIR_P) "$(distdir)/$$subdir" \
47696
 
+           || exit 1; \
47697
 
+           distdir=`$(am__cd) $(distdir) && pwd`; \
47698
 
+           top_distdir=`$(am__cd) $(top_distdir) && pwd`; \
47699
 
+           (cd $$subdir && \
47700
 
+             $(MAKE) $(AM_MAKEFLAGS) \
47701
 
+               top_distdir="$$top_distdir" \
47702
 
+               distdir="$$distdir/$$subdir" \
47703
 
+               am__remove_distdir=: \
47704
 
+               am__skip_length_check=: \
47705
 
+               distdir) \
47706
 
+             || exit 1; \
47707
 
+         fi; \
47708
 
+       done
47709
 
+check-am: all-am
47710
 
+check: check-recursive
47711
 
+all-am: Makefile $(LTLIBRARIES) $(HEADERS)
47712
 
+installdirs: installdirs-recursive
47713
 
+installdirs-am:
47714
 
+install: install-recursive
47715
 
+install-exec: install-exec-recursive
47716
 
+install-data: install-data-recursive
47717
 
+uninstall: uninstall-recursive
47718
 
+
47719
 
+install-am: all-am
47720
 
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
47721
 
+
47722
 
+installcheck: installcheck-recursive
47723
 
+install-strip:
47724
 
+       $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
47725
 
+         install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
47726
 
+         `test -z '$(STRIP)' || \
47727
 
+           echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
47728
 
+mostlyclean-generic:
47729
 
+
47730
 
+clean-generic:
47731
 
+
47732
 
+distclean-generic:
47733
 
+       -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
47734
 
+
47735
 
+maintainer-clean-generic:
47736
 
+       @echo "This command is intended for maintainers to use"
47737
 
+       @echo "it deletes files that may require special tools to rebuild."
47738
 
+clean: clean-recursive
47739
 
+
47740
 
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
47741
 
+       mostlyclean-am
47742
 
+
47743
 
+distclean: distclean-recursive
47744
 
+       -rm -rf ./$(DEPDIR)
47745
 
+       -rm -f Makefile
47746
 
+distclean-am: clean-am distclean-compile distclean-generic \
47747
 
+       distclean-tags
47748
 
+
47749
 
+dvi: dvi-recursive
47750
 
+
47751
 
+dvi-am:
47752
 
+
47753
 
+html: html-recursive
47754
 
+
47755
 
+info: info-recursive
47756
 
+
47757
 
+info-am:
47758
 
+
47759
 
+install-data-am:
47760
 
+
47761
 
+install-dvi: install-dvi-recursive
47762
 
+
47763
 
+install-exec-am:
47764
 
+
47765
 
+install-html: install-html-recursive
47766
 
+
47767
 
+install-info: install-info-recursive
47768
 
+
47769
 
+install-man:
47770
 
+
47771
 
+install-pdf: install-pdf-recursive
47772
 
+
47773
 
+install-ps: install-ps-recursive
47774
 
+
47775
 
+installcheck-am:
47776
 
+
47777
 
+maintainer-clean: maintainer-clean-recursive
47778
 
+       -rm -rf ./$(DEPDIR)
47779
 
+       -rm -f Makefile
47780
 
+maintainer-clean-am: distclean-am maintainer-clean-generic
47781
 
+
47782
 
+mostlyclean: mostlyclean-recursive
47783
 
+
47784
 
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
47785
 
+       mostlyclean-libtool
47786
 
+
47787
 
+pdf: pdf-recursive
47788
 
+
47789
 
+pdf-am:
47790
 
+
47791
 
+ps: ps-recursive
47792
 
+
47793
 
+ps-am:
47794
 
+
47795
 
+uninstall-am:
47796
 
+
47797
 
+.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) install-am \
47798
 
+       install-strip
47799
 
+
47800
 
+.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
47801
 
+       all all-am check check-am clean clean-generic clean-libtool \
47802
 
+       clean-noinstLTLIBRARIES ctags ctags-recursive distclean \
47803
 
+       distclean-compile distclean-generic distclean-libtool \
47804
 
+       distclean-tags distdir dvi dvi-am html html-am info info-am \
47805
 
+       install install-am install-data install-data-am install-dvi \
47806
 
+       install-dvi-am install-exec install-exec-am install-html \
47807
 
+       install-html-am install-info install-info-am install-man \
47808
 
+       install-pdf install-pdf-am install-ps install-ps-am \
47809
 
+       install-strip installcheck installcheck-am installdirs \
47810
 
+       installdirs-am maintainer-clean maintainer-clean-generic \
47811
 
+       mostlyclean mostlyclean-compile mostlyclean-generic \
47812
 
+       mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \
47813
 
+       uninstall uninstall-am
47814
 
+
47815
 
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
47816
 
+# Otherwise a system limit (for SysV at least) may be exceeded.
47817
 
+.NOEXPORT:
47818
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/mcht-contains.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/mcht-contains.c
47819
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/mcht-contains.c        1970-01-01 01:00:00.000000000 +0100
47820
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/mcht-contains.c 2009-01-06 00:15:52.000000000 +0100
47821
 
@@ -0,0 +1,69 @@
47822
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file 
47823
 
+ */
47824
 
+
47825
 
+/* Match-type ':contains' 
47826
 
+ */
47827
 
+
47828
 
+#include "lib.h"
47829
 
+
47830
 
+#include "sieve-match-types.h"
47831
 
+#include "sieve-comparators.h"
47832
 
+#include "sieve-match.h"
47833
 
+
47834
 
+#include <string.h>
47835
 
+#include <stdio.h>
47836
 
+
47837
 
+/*
47838
 
+ * Forward declarations
47839
 
+ */ 
47840
 
+
47841
 
+static int mcht_contains_match
47842
 
+       (struct sieve_match_context *mctx, const char *val, size_t val_size, 
47843
 
+               const char *key, size_t key_size, int key_index);
47844
 
+
47845
 
+/*
47846
 
+ * Match-type object
47847
 
+ */
47848
 
+
47849
 
+const struct sieve_match_type contains_match_type = {
47850
 
+       SIEVE_OBJECT("contains", &match_type_operand,   SIEVE_MATCH_TYPE_CONTAINS),
47851
 
+       TRUE, TRUE,
47852
 
+       NULL,
47853
 
+       sieve_match_substring_validate_context,
47854
 
+       NULL,
47855
 
+       mcht_contains_match,
47856
 
+       NULL
47857
 
+};
47858
 
+
47859
 
+/*
47860
 
+ * Match-type implementation
47861
 
+ */
47862
 
+
47863
 
+/* FIXME: Naive substring match implementation. Should switch to more 
47864
 
+ * efficient algorithm if large values need to be searched (e.g. message body).
47865
 
+ */
47866
 
+static int mcht_contains_match
47867
 
+(struct sieve_match_context *mctx, const char *val, size_t val_size, 
47868
 
+       const char *key, size_t key_size, int key_index ATTR_UNUSED)
47869
 
+{
47870
 
+       const struct sieve_comparator *cmp = mctx->comparator;
47871
 
+       const char *vend = (const char *) val + val_size;
47872
 
+       const char *kend = (const char *) key + key_size;
47873
 
+       const char *vp = val;
47874
 
+       const char *kp = key;
47875
 
+
47876
 
+       if ( val == NULL || val_size == 0 ) 
47877
 
+               return ( key_size == 0 );
47878
 
+
47879
 
+       if ( mctx->comparator->char_match == NULL ) 
47880
 
+               return FALSE;
47881
 
+
47882
 
+       while ( (vp < vend) && (kp < kend) ) {
47883
 
+               if ( !cmp->char_match(cmp, &vp, vend, &kp, kend) )
47884
 
+                       vp++;
47885
 
+       }
47886
 
+    
47887
 
+       return (kp == kend);
47888
 
+}
47889
 
+
47890
 
+
47891
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/mcht-is.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/mcht-is.c
47892
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/mcht-is.c      1970-01-01 01:00:00.000000000 +0100
47893
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/mcht-is.c       2009-01-06 00:15:52.000000000 +0100
47894
 
@@ -0,0 +1,54 @@
47895
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file 
47896
 
+ */
47897
 
47898
 
+/* Match-type ':is': 
47899
 
+ */
47900
 
+
47901
 
+#include "lib.h"
47902
 
+
47903
 
+#include "sieve-match-types.h"
47904
 
+#include "sieve-comparators.h"
47905
 
+#include "sieve-match.h"
47906
 
+
47907
 
+#include <string.h>
47908
 
+#include <stdio.h>
47909
 
+
47910
 
+/* 
47911
 
+ * Forward declarations 
47912
 
+ */
47913
 
+
47914
 
+static int mcht_is_match
47915
 
+       (struct sieve_match_context *mctx, const char *val, size_t val_size, 
47916
 
+               const char *key, size_t key_size, int key_index);
47917
 
+
47918
 
+/* 
47919
 
+ * Match-type object 
47920
 
+ */
47921
 
+
47922
 
+const struct sieve_match_type is_match_type = {
47923
 
+       SIEVE_OBJECT("is", &match_type_operand, SIEVE_MATCH_TYPE_IS),
47924
 
+       TRUE, TRUE,
47925
 
+       NULL, NULL, NULL,
47926
 
+       mcht_is_match,
47927
 
+       NULL
47928
 
+};
47929
 
+
47930
 
+/*
47931
 
+ * Match-type implementation
47932
 
+ */
47933
 
+
47934
 
+static int mcht_is_match
47935
 
+(struct sieve_match_context *mctx ATTR_UNUSED, 
47936
 
+       const char *val, size_t val_size, 
47937
 
+       const char *key, size_t key_size, int key_index ATTR_UNUSED)
47938
 
+{
47939
 
+       if ( (val == NULL || val_size == 0) ) 
47940
 
+               return ( key_size == 0 );
47941
 
+
47942
 
+       if ( mctx->comparator->compare != NULL )
47943
 
+               return (mctx->comparator->compare(mctx->comparator, 
47944
 
+                       val, val_size, key, key_size) == 0);
47945
 
+
47946
 
+       return FALSE;
47947
 
+}
47948
 
+
47949
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/mcht-matches.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/mcht-matches.c
47950
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/mcht-matches.c 1970-01-01 01:00:00.000000000 +0100
47951
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/mcht-matches.c  2009-02-02 10:17:30.000000000 +0100
47952
 
@@ -0,0 +1,434 @@
47953
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file 
47954
 
+ */
47955
 
47956
 
+/* Match-type ':matches' 
47957
 
+ */
47958
 
+
47959
 
+#include "lib.h"
47960
 
+#include "str.h"
47961
 
+
47962
 
+#include "sieve-match-types.h"
47963
 
+#include "sieve-comparators.h"
47964
 
+#include "sieve-match.h"
47965
 
+
47966
 
+#include <string.h>
47967
 
+#include <stdio.h>
47968
 
+
47969
 
+/*
47970
 
+ * Forward declarations
47971
 
+ */
47972
 
+
47973
 
+static int mcht_matches_match
47974
 
+       (struct sieve_match_context *mctx, const char *val, size_t val_size, 
47975
 
+               const char *key, size_t key_size, int key_index);
47976
 
+
47977
 
+/*
47978
 
+ * Match-type object
47979
 
+ */
47980
 
+
47981
 
+const struct sieve_match_type matches_match_type = {
47982
 
+       SIEVE_OBJECT("matches", &match_type_operand, SIEVE_MATCH_TYPE_MATCHES),
47983
 
+       TRUE, FALSE,
47984
 
+       NULL,
47985
 
+       sieve_match_substring_validate_context, 
47986
 
+       NULL,
47987
 
+       mcht_matches_match,
47988
 
+       NULL
47989
 
+};
47990
 
+
47991
 
+/*
47992
 
+ * Match-type implementation
47993
 
+ */
47994
 
+
47995
 
+/* Quick 'n dirty debug */
47996
 
+//#define MATCH_DEBUG
47997
 
+#ifdef MATCH_DEBUG
47998
 
+#define debug_printf(...) printf ("match debug: " __VA_ARGS__)
47999
 
+#else
48000
 
+#define debug_printf(...) 
48001
 
+#endif
48002
 
+
48003
 
+/* FIXME: Naive implementation, substitute this with dovecot src/lib/str-find.c
48004
 
+ */
48005
 
+static inline bool _string_find(const struct sieve_comparator *cmp, 
48006
 
+       const char **valp, const char *vend, const char **keyp, const char *kend)
48007
 
+{
48008
 
+       while ( (*valp < vend) && (*keyp < kend) ) {
48009
 
+               if ( !cmp->char_match(cmp, valp, vend, keyp, kend) )
48010
 
+                       (*valp)++;
48011
 
+       }
48012
 
+       
48013
 
+       return (*keyp == kend);
48014
 
+}
48015
 
+
48016
 
+static char _scan_key_section
48017
 
+       (string_t *section, const char **wcardp, const char *key_end)
48018
 
+{
48019
 
+       /* Find next wildcard and resolve escape sequences */   
48020
 
+       str_truncate(section, 0);
48021
 
+       while ( *wcardp < key_end && **wcardp != '*' && **wcardp != '?') {
48022
 
+               if ( **wcardp == '\\' ) {
48023
 
+                       (*wcardp)++;
48024
 
+               }
48025
 
+               str_append_c(section, **wcardp);
48026
 
+               (*wcardp)++;
48027
 
+       }
48028
 
+       
48029
 
+       /* Record wildcard character or \0 */
48030
 
+       if ( *wcardp < key_end ) {                      
48031
 
+               return **wcardp;
48032
 
+       } 
48033
 
+       
48034
 
+       i_assert( *wcardp == key_end );
48035
 
+       return '\0';
48036
 
+}
48037
 
+
48038
 
+static int mcht_matches_match
48039
 
+(struct sieve_match_context *mctx, const char *val, size_t val_size, 
48040
 
+       const char *key, size_t key_size, int key_index ATTR_UNUSED)
48041
 
+{
48042
 
+       const struct sieve_comparator *cmp = mctx->comparator;
48043
 
+       struct sieve_match_values *mvalues;
48044
 
+       string_t *mvalue = NULL, *mchars = NULL;
48045
 
+       string_t *section, *subsection;
48046
 
+       const char *vend, *kend, *vp, *kp, *wp, *pvp;
48047
 
+       bool backtrack = FALSE; /* TRUE: match of '?'-connected sections failed */
48048
 
+       char wcard = '\0';      /* Current wildcard */
48049
 
+       char next_wcard = '\0'; /* Next  widlcard */
48050
 
+       unsigned int key_offset = 0;
48051
 
+
48052
 
+       /* Value may be NULL, parse empty string in stead */
48053
 
+       if ( val == NULL ) {
48054
 
+               val = "";
48055
 
+               val_size = 0;
48056
 
+       }
48057
 
+       
48058
 
+       /* Key sections */
48059
 
+       section = t_str_new(32);    /* Section (after beginning or *) */
48060
 
+       subsection = t_str_new(32); /* Sub-section (after ?) */
48061
 
+       
48062
 
+       /* Mark end of value and key */
48063
 
+       vend = (const char *) val + val_size;
48064
 
+       kend = (const char *) key + key_size;
48065
 
+
48066
 
+       /* Initialize pointers */
48067
 
+       vp = val;                   /* Value pointer */
48068
 
+       kp = key;                   /* Key pointer */
48069
 
+       wp = key;                   /* Wildcard (key) pointer */
48070
 
+       pvp = val;                  /* Previous value Pointer */
48071
 
+
48072
 
+       /* Start match values list if requested */
48073
 
+       if ( (mvalues = sieve_match_values_start(mctx->interp)) != NULL ) {
48074
 
+               /* Skip ${0} for now; added when match succeeds */
48075
 
+               sieve_match_values_add(mvalues, NULL);
48076
 
+
48077
 
+               mvalue = t_str_new(32);     /* Match value (*) */
48078
 
+               mchars = t_str_new(32);     /* Match characters (.?..?.??) */
48079
 
+       }
48080
 
+       
48081
 
+       /* Match the pattern: 
48082
 
+        *   <pattern> = <section>*<section>*<section>...
48083
 
+        *   <section> = <sub-section>?<sub-section>?<sub-section>...
48084
 
+        *
48085
 
+        * Escape sequences \? and \* need special attention. 
48086
 
+        */
48087
 
+        
48088
 
+       debug_printf("=== Start ===\n");
48089
 
+       debug_printf("  key:   %s\n", t_strdup_until(key, kend));
48090
 
+       debug_printf("  value: %s\n", t_strdup_until(val, vend));
48091
 
+
48092
 
+       /* Loop until either key or value ends */
48093
 
+       while (kp < kend && vp < vend ) {
48094
 
+               const char *needle, *nend;
48095
 
+               
48096
 
+               if ( !backtrack ) {
48097
 
+                       /* Search the next '*' wildcard in the key string */
48098
 
+
48099
 
+                       wcard = next_wcard;
48100
 
+                       
48101
 
+                       /* Find the needle to look for in the string */ 
48102
 
+                       key_offset = 0; 
48103
 
+                       for (;;) {
48104
 
+                               next_wcard = _scan_key_section(section, &wp, kend);
48105
 
+                               
48106
 
+                               if ( wcard == '\0' || str_len(section) > 0 ) 
48107
 
+                                       break;
48108
 
+                                       
48109
 
+                               if ( next_wcard == '*' ) {      
48110
 
+                                       break;
48111
 
+                               }
48112
 
+                                       
48113
 
+                               if ( wp < kend ) 
48114
 
+                                       wp++;
48115
 
+                               else 
48116
 
+                                       break;
48117
 
+                               key_offset++;
48118
 
+                       }
48119
 
+                       
48120
 
+                       debug_printf("found wildcard '%c' at pos [%d]\n", 
48121
 
+                               next_wcard, (int) (wp-key));
48122
 
+       
48123
 
+                       if ( mvalues != NULL )                  
48124
 
+                               str_truncate(mvalue, 0);
48125
 
+               } else {
48126
 
+                       /* Backtracked; '*' wildcard is retained */
48127
 
+                       debug_printf("backtracked");
48128
 
+                       backtrack = FALSE;
48129
 
+               }
48130
 
+               
48131
 
+               /* Determine what we are looking for */
48132
 
+               needle = str_c(section);
48133
 
+               nend = PTR_OFFSET(needle, str_len(section));            
48134
 
+                
48135
 
+               debug_printf("  section needle:  '%s'\n", t_strdup_until(needle, nend));
48136
 
+               debug_printf("  section key:     '%s'\n", t_strdup_until(kp, kend));
48137
 
+               debug_printf("  section remnant: '%s'\n", t_strdup_until(wp, kend));
48138
 
+               debug_printf("  value remnant:   '%s'\n", t_strdup_until(vp, vend));
48139
 
+               debug_printf("  key offset:      %d\n", key_offset);
48140
 
+               
48141
 
+               pvp = vp;
48142
 
+               if ( next_wcard == '\0' ) {
48143
 
+                       /* No more wildcards; find the needle substring at the end of string */
48144
 
+       
48145
 
+                       const char *qp, *qend;
48146
 
+                       
48147
 
+                       debug_printf("next_wcard = NUL; must find needle at end\n");                             
48148
 
+
48149
 
+                       /* Check if the value is still large enough */                  
48150
 
+                       if ( vend - str_len(section) < vp ) {
48151
 
+                               debug_printf("  wont match: value is too short\n");
48152
 
+                               break;
48153
 
+                       }
48154
 
+
48155
 
+                       /* Move value pointer to where the needle should be */
48156
 
+                       vp = PTR_OFFSET(vend, -str_len(section));
48157
 
+
48158
 
+                       /* Record match values */
48159
 
+                       qend = vp;
48160
 
+                       qp = vp - key_offset;
48161
 
+               
48162
 
+                       if ( mvalues != NULL )
48163
 
+                               str_append_n(mvalue, pvp, qp-pvp);
48164
 
+                                       
48165
 
+                       /* Compare needle to end of value string */
48166
 
+                       if ( !cmp->char_match(cmp, &vp, vend, &needle, nend) ) {        
48167
 
+                               debug_printf("  match at end failed\n");                                 
48168
 
+                               break;
48169
 
+                       }
48170
 
+                       
48171
 
+                       /* Add match values */
48172
 
+                       if ( mvalues != NULL ) {
48173
 
+                               /* Append '*' match value */
48174
 
+                               sieve_match_values_add(mvalues, mvalue);
48175
 
+
48176
 
+                               /* Append any initial '?' match values */
48177
 
+                               for ( ; qp < qend; qp++ )
48178
 
+                                       sieve_match_values_add_char(mvalues, *qp); 
48179
 
+                       }
48180
 
+
48181
 
+                       /* Finish match */
48182
 
+                       kp = kend;
48183
 
+                       vp = vend;
48184
 
+
48185
 
+                       debug_printf("  matched end of value\n");
48186
 
+                       break;
48187
 
+               } else {
48188
 
+                       /* Next wildcard found; match needle before next wildcard */
48189
 
+
48190
 
+                       const char *prv = NULL; /* Stored value pointer for backtrack */
48191
 
+                       const char *prk = NULL; /* Stored key pointer for backtrack */
48192
 
+                       const char *prw = NULL; /* Stored wildcard pointer for backtrack */
48193
 
+                       const char *chars;
48194
 
+
48195
 
+                       /* Reset '?' match values */
48196
 
+                       if ( mvalues != NULL )          
48197
 
+                               str_truncate(mchars, 0);
48198
 
+                                                       
48199
 
+                       if ( wcard == '\0' ) {
48200
 
+                               /* No current wildcard; match needs to happen right at the beginning */
48201
 
+                               debug_printf("wcard = NUL; needle should be found at the beginning.\n");
48202
 
+                               debug_printf("  begin needle: '%s'\n", t_strdup_until(needle, nend));
48203
 
+                               debug_printf("  begin value:  '%s'\n", t_strdup_until(vp, vend));
48204
 
+
48205
 
+                               if ( !cmp->char_match(cmp, &vp, vend, &needle, nend) ) {        
48206
 
+                                       debug_printf("  failed to find needle at beginning\n");                          
48207
 
+                                       break;
48208
 
+                               }
48209
 
+
48210
 
+                       } else {
48211
 
+                               /* Current wildcard present; match needle between current and next wildcard */
48212
 
+                               debug_printf("wcard != NUL; must find needle at an offset (>= %d).\n",
48213
 
+                                       key_offset);
48214
 
+
48215
 
+                               /* Match may happen at any offset (>= key offset): find substring */                            
48216
 
+                               vp += key_offset;
48217
 
+                               if ( (vp >= vend) || !_string_find(cmp, &vp, vend, &needle, nend) ) {
48218
 
+                                       debug_printf("  failed to find needle at an offset\n"); 
48219
 
+                                       break;
48220
 
+                               }
48221
 
+
48222
 
+                               prv = vp - str_len(section);
48223
 
+                               prk = kp;
48224
 
+                               prw = wp;               
48225
 
+       
48226
 
+                               /* Append match values */
48227
 
+                               if ( mvalues != NULL ) {
48228
 
+                                       const char *qend = vp - str_len(section);
48229
 
+                                       const char *qp = qend - key_offset;
48230
 
+
48231
 
+                                       /* Append '*' match value */
48232
 
+                                       str_append_n(mvalue, pvp, qp-pvp);
48233
 
+
48234
 
+                                       /* Append any initial '?' match values (those that caused the key
48235
 
+                                        * offset.
48236
 
+                                        */
48237
 
+                                       for ( ; qp < qend; qp++ )
48238
 
+                                               str_append_c(mchars, *qp);
48239
 
+                               }
48240
 
+                       }
48241
 
+                       
48242
 
+                       /* Update wildcard and key pointers for next wildcard scan */
48243
 
+                       if ( wp < kend ) wp++;
48244
 
+                       kp = wp;
48245
 
+               
48246
 
+                       /* Scan successive '?' wildcards */
48247
 
+                       while ( next_wcard == '?' ) {
48248
 
+                               debug_printf("next_wcard = '?'; need to match arbitrary character\n");
48249
 
+                               
48250
 
+                               /* Add match value */ 
48251
 
+                               if ( mvalues != NULL )
48252
 
+                                       str_append_c(mchars, *vp);
48253
 
+
48254
 
+                               vp++;
48255
 
+
48256
 
+                               /* Scan for next '?' wildcard */                                
48257
 
+                               next_wcard = _scan_key_section(subsection, &wp, kend);
48258
 
+                               debug_printf("found next wildcard '%c' at pos [%d] (fixed match)\n", 
48259
 
+                                       next_wcard, (int) (wp-key));
48260
 
+                                       
48261
 
+                               /* Determine what we are looking for */
48262
 
+                               needle = str_c(subsection);
48263
 
+                               nend = PTR_OFFSET(needle, str_len(subsection));
48264
 
+
48265
 
+                               debug_printf("  sub key:       '%s'\n", t_strdup_until(needle, nend));
48266
 
+                               debug_printf("  value remnant: '%s'\n", vp <= vend ? t_strdup_until(vp, vend) : "");
48267
 
+
48268
 
+                               /* Try matching the needle at fixed position */
48269
 
+                               if ( (needle == nend && next_wcard == '\0' && vp < vend ) || 
48270
 
+                                       !cmp->char_match(cmp, &vp, vend, &needle, nend) ) {     
48271
 
+                                       
48272
 
+                                       /* Match failed: now we have a problem. We need to backtrack to the previous
48273
 
+                                        * '*' wildcard occurence and start scanning for the next possible match.
48274
 
+                                        */
48275
 
+
48276
 
+                                       debug_printf("  failed fixed match\n");
48277
 
+                                       
48278
 
+                                       /* Start backtrack */
48279
 
+                                       if ( prv != NULL && prv + 1 < vend ) {
48280
 
+                                               /* Restore pointers */
48281
 
+                                               vp = prv;
48282
 
+                                               kp = prk;
48283
 
+                                               wp = prw;
48284
 
+                               
48285
 
+                                               /* Skip forward one value character to scan the next possible match */
48286
 
+                                               if ( mvalues != NULL )
48287
 
+                                                       str_append_c(mvalue, *vp);
48288
 
+                                               vp++;
48289
 
+                               
48290
 
+                                               /* Set wildcard state appropriately */
48291
 
+                                               wcard = '*';
48292
 
+                                               next_wcard = '?';
48293
 
+                               
48294
 
+                                               /* Backtrack */
48295
 
+                                               backtrack = TRUE;                                
48296
 
+
48297
 
+                                               debug_printf("  BACKTRACK\n");
48298
 
+                                       }
48299
 
+
48300
 
+                                       /* Break '?' wildcard scanning loop */
48301
 
+                                       break;
48302
 
+                               }
48303
 
+                               
48304
 
+                               /* Update wildcard and key pointers for next wildcard scan */
48305
 
+                               if ( wp < kend ) wp++;
48306
 
+                               kp = wp;
48307
 
+                       }
48308
 
+                       
48309
 
+                       if ( !backtrack ) {
48310
 
+                               unsigned int i;
48311
 
+                               
48312
 
+                               if ( next_wcard == '?' ) {
48313
 
+                                       debug_printf("failed to match '?'\n");  
48314
 
+                                       break;
48315
 
+                               }
48316
 
+                               
48317
 
+                               if ( mvalues != NULL ) {
48318
 
+                                       if ( prv != NULL )
48319
 
+                                               sieve_match_values_add(mvalues, mvalue);
48320
 
+
48321
 
+                                       chars = (const char *) str_data(mchars);
48322
 
+
48323
 
+                                       for ( i = 0; i < str_len(mchars); i++ ) {
48324
 
+                                               sieve_match_values_add_char(mvalues, chars[i]);
48325
 
+                                       }
48326
 
+                               }
48327
 
+
48328
 
+                               if ( next_wcard != '*' ) {
48329
 
+                                       debug_printf("failed to match at end of string\n");
48330
 
+                                       break;
48331
 
+                               }
48332
 
+                       }
48333
 
+               }
48334
 
+                                       
48335
 
+               /* Check whether string ends in a wildcard 
48336
 
+                * (avoid scanning the rest of the string)
48337
 
+                */
48338
 
+               if ( kp == kend && next_wcard == '*' ) {
48339
 
+                       /* Add the rest of the string as match value */
48340
 
+                       if ( mvalues != NULL ) {
48341
 
+                               str_truncate(mvalue, 0);
48342
 
+                               str_append_n(mvalue, vp, vend-vp);
48343
 
+                               sieve_match_values_add(mvalues, mvalue);
48344
 
+                       }
48345
 
+               
48346
 
+                       /* Finish match */
48347
 
+                       kp = kend;
48348
 
+                       vp = vend;
48349
 
+               
48350
 
+                       debug_printf("key ends with '*'\n");
48351
 
+                       break;
48352
 
+               }                       
48353
 
+                                       
48354
 
+               debug_printf("== Loop ==\n");
48355
 
+       }
48356
 
+
48357
 
+       /* Eat away a trailing series of *s */
48358
 
+       if ( vp == vend ) {
48359
 
+               while ( kp < kend && *kp == '*' ) kp++;
48360
 
+       }
48361
 
+
48362
 
+       /* By definition, the match is only successful if both value and key pattern
48363
 
+        * are exhausted.
48364
 
+        */
48365
 
+       
48366
 
+       debug_printf("=== Finish ===\n");
48367
 
+       debug_printf("  result: %s\n", (kp == kend && vp == vend) ? "true" : "false");
48368
 
+       
48369
 
+       if (kp == kend && vp == vend) {
48370
 
+               /* Activate new match values after successful match */
48371
 
+               if ( mvalues != NULL ) {
48372
 
+                       /* Set ${0} */
48373
 
+                       string_t *matched = str_new_const(pool_datastack_create(), val, val_size);
48374
 
+                       sieve_match_values_set(mvalues, 0, matched);
48375
 
+
48376
 
+                       /* Commit new match values */
48377
 
+                       sieve_match_values_commit(mctx->interp, &mvalues);
48378
 
+               }
48379
 
+               return TRUE;
48380
 
+       }
48381
 
+
48382
 
+       /* No match; drop collected match values */
48383
 
+       sieve_match_values_abort(&mvalues);
48384
 
+       return FALSE;
48385
 
+}
48386
 
+                        
48387
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/body/ext-body.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/body/ext-body.c
48388
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/body/ext-body.c        1970-01-01 01:00:00.000000000 +0100
48389
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/body/ext-body.c 2009-01-06 00:15:52.000000000 +0100
48390
 
@@ -0,0 +1,73 @@
48391
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
48392
 
+ */
48393
 
+
48394
 
+/* Extension body 
48395
 
+ * ------------------
48396
 
+ *
48397
 
+ * Authors: Stephan Bosch, original CMUSieve implementation by Timo Sirainen
48398
 
+ * Specification: RFC 5173
48399
 
+ * Implementation: full, but text body-transform implementation is simple
48400
 
+ * Status: experimental, largely untested
48401
 
+ *
48402
 
+ */
48403
 
48404
 
+/* FIXME: 
48405
 
+ *
48406
 
+ * From RFC with respect to :text body transform:
48407
 
+ *
48408
 
+ * "Sophisticated implementations MAY strip mark-up from the text prior
48409
 
+ *  to matching, and MAY convert media types other than text to text
48410
 
+ *  prior to matching.
48411
 
+ *
48412
 
+ *  (For example, they may be able to convert proprietary text editor
48413
 
+ *  formats to text or apply optical character recognition algorithms to
48414
 
+ *  image data.)"
48415
 
+ *
48416
 
+ * We might want to do this in the future, i.e. we must evaluate whether this is 
48417
 
+ * feasible.
48418
 
+ */
48419
 
48420
 
+#include "lib.h"
48421
 
+#include "array.h"
48422
 
+
48423
 
+#include "sieve-extensions.h"
48424
 
+#include "sieve-commands.h"
48425
 
+#include "sieve-comparators.h"
48426
 
+#include "sieve-match-types.h"
48427
 
+#include "sieve-address-parts.h"
48428
 
+
48429
 
+#include "sieve-validator.h"
48430
 
+#include "sieve-generator.h"
48431
 
+#include "sieve-binary.h"
48432
 
+#include "sieve-interpreter.h"
48433
 
+#include "sieve-dump.h"
48434
 
+
48435
 
+#include "ext-body-common.h"
48436
 
+
48437
 
+/* 
48438
 
+ * Extension 
48439
 
+ */
48440
 
+
48441
 
+static bool ext_body_validator_load(struct sieve_validator *validator);
48442
 
+
48443
 
+int ext_body_my_id = -1;
48444
 
+
48445
 
+const struct sieve_extension body_extension = { 
48446
 
+       "body", 
48447
 
+       &ext_body_my_id,
48448
 
+       NULL, NULL,
48449
 
+       ext_body_validator_load, 
48450
 
+       NULL, NULL, NULL, NULL, NULL,
48451
 
+       SIEVE_EXT_DEFINE_OPERATION(body_operation), 
48452
 
+       SIEVE_EXT_DEFINE_NO_OPERANDS
48453
 
+};
48454
 
+
48455
 
+static bool ext_body_validator_load(struct sieve_validator *validator)
48456
 
+{
48457
 
+       /* Register new test */
48458
 
+       sieve_validator_register_command(validator, &body_test);
48459
 
+
48460
 
+       return TRUE;
48461
 
+}
48462
 
+
48463
 
+
48464
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/body/ext-body-common.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/body/ext-body-common.c
48465
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/body/ext-body-common.c 1970-01-01 01:00:00.000000000 +0100
48466
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/body/ext-body-common.c  2009-06-01 10:18:44.000000000 +0200
48467
 
@@ -0,0 +1,343 @@
48468
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
48469
 
+ */
48470
 
+
48471
 
+#include "lib.h"
48472
 
+#include "mempool.h"
48473
 
+#include "buffer.h"
48474
 
+#include "array.h"
48475
 
+#include "str.h"
48476
 
+#include "istream.h"
48477
 
+#include "rfc822-parser.h"
48478
 
+#include "message-date.h"
48479
 
+#include "message-parser.h"
48480
 
+#include "message-decoder.h"
48481
 
+
48482
 
+#include "sieve-common.h"
48483
 
+#include "sieve-message.h"
48484
 
+#include "sieve-interpreter.h"
48485
 
+
48486
 
+#include "ext-body-common.h"
48487
 
+
48488
 
+/* This implementation is largely borrowed from the original sieve-cmu.c of the 
48489
 
+ * cmusieve plugin.
48490
 
+ */
48491
 
48492
 
+struct ext_body_part_cached {
48493
 
+       const char *content_type;
48494
 
+
48495
 
+       const char *raw_body;
48496
 
+       const char *decoded_body;
48497
 
+       size_t raw_body_size;
48498
 
+       size_t decoded_body_size;
48499
 
+       
48500
 
+       bool have_body; /* there's the empty end-of-headers line */
48501
 
+};
48502
 
+
48503
 
+struct ext_body_message_context {
48504
 
+       pool_t pool;
48505
 
+       ARRAY_DEFINE(cached_body_parts, struct ext_body_part_cached);
48506
 
+       ARRAY_DEFINE(return_body_parts, struct ext_body_part);
48507
 
+       buffer_t *tmp_buffer;
48508
 
+};
48509
 
+
48510
 
+static bool _is_wanted_content_type
48511
 
+(const char * const *wanted_types, const char *content_type)
48512
 
+{
48513
 
+       const char *subtype = strchr(content_type, '/');
48514
 
+       size_t type_len;
48515
 
+
48516
 
+       type_len = ( subtype == NULL ? strlen(content_type) :
48517
 
+               (size_t)(subtype - content_type) );
48518
 
+
48519
 
+       i_assert( wanted_types != NULL );
48520
 
+
48521
 
+       for (; *wanted_types != NULL; wanted_types++) {
48522
 
+               const char *wanted_subtype = strchr(*wanted_types, '/');
48523
 
+
48524
 
+               if (**wanted_types == '\0') {
48525
 
+                       /* empty string matches everything */
48526
 
+                       return TRUE;
48527
 
+               }
48528
 
+               if (wanted_subtype == NULL) {
48529
 
+                       /* match only main type */
48530
 
+                       if (strlen(*wanted_types) == type_len &&
48531
 
+                           strncasecmp(*wanted_types, content_type,
48532
 
+                                       type_len) == 0)
48533
 
+                               return TRUE;
48534
 
+               } else {
48535
 
+                       /* match whole type/subtype */
48536
 
+                       if (strcasecmp(*wanted_types, content_type) == 0)
48537
 
+                               return TRUE;
48538
 
+               }
48539
 
+       }
48540
 
+       return FALSE;
48541
 
+}
48542
 
+
48543
 
+static bool ext_body_get_return_parts
48544
 
+(struct ext_body_message_context *ctx, const char * const *wanted_types,
48545
 
+       bool decode_to_plain)
48546
 
+{
48547
 
+       const struct ext_body_part_cached *body_parts;
48548
 
+       unsigned int i, count;
48549
 
+       struct ext_body_part *return_part;
48550
 
+
48551
 
+       /* Check whether any body parts are cached already */
48552
 
+       body_parts = array_get(&ctx->cached_body_parts, &count);
48553
 
+       if ( count == 0 )
48554
 
+               return FALSE;
48555
 
+
48556
 
+       /* Clear result array */
48557
 
+       array_clear(&ctx->return_body_parts);
48558
 
+       
48559
 
+       /* Fill result array with requested content_types */
48560
 
+       for (i = 0; i < count; i++) {
48561
 
+               if (!body_parts[i].have_body) {
48562
 
+                       /* Part has no body; according to RFC this MUST not match to anything and 
48563
 
+                        * therefore it is not included in the result.
48564
 
+                        */
48565
 
+                       continue;
48566
 
+               }
48567
 
+
48568
 
+               /* Skip content types that are not requested */
48569
 
+               if (!_is_wanted_content_type(wanted_types, body_parts[i].content_type))
48570
 
+                       continue;
48571
 
+
48572
 
+               /* Add new item to the result */
48573
 
+               return_part = array_append_space(&ctx->return_body_parts);
48574
 
+               
48575
 
+               /* Depending on whether a decoded body part is requested, the appropriate
48576
 
+                * cache item is read. If it is missing, this function fails and the cache 
48577
 
+                * needs to be completed by ext_body_parts_add_missing().
48578
 
+                */
48579
 
+               if (decode_to_plain) {
48580
 
+                       if (body_parts[i].decoded_body == NULL)
48581
 
+                               return FALSE;
48582
 
+                       return_part->content = body_parts[i].decoded_body;
48583
 
+                       return_part->size = body_parts[i].decoded_body_size;
48584
 
+               } else {
48585
 
+                       if (body_parts[i].raw_body == NULL)
48586
 
+                               return FALSE;
48587
 
+                       return_part->content = body_parts[i].raw_body;
48588
 
+                       return_part->size = body_parts[i].raw_body_size;
48589
 
+               }
48590
 
+       }
48591
 
+
48592
 
+       return TRUE;
48593
 
+}
48594
 
+
48595
 
+static void ext_body_part_save
48596
 
+(struct ext_body_message_context *ctx, struct message_part *part,
48597
 
+       struct ext_body_part_cached *body_part, bool decoded)
48598
 
+{
48599
 
+       buffer_t *buf = ctx->tmp_buffer;
48600
 
+       char *part_data;
48601
 
+       size_t part_size;
48602
 
+
48603
 
+       /* Add terminating NUL to the body part buffer */
48604
 
+       buffer_append_c(buf, '\0');
48605
 
+
48606
 
+       part_data = p_malloc(ctx->pool, buf->used);
48607
 
+       memcpy(part_data, buf->data, buf->used);
48608
 
+       part_size = buf->used - 1;
48609
 
+       
48610
 
+       /* Depending on whether the part is decoded or not store message body in the
48611
 
+        * appropriate cache location.
48612
 
+        */
48613
 
+       if ( !decoded ) {
48614
 
+               body_part->raw_body = part_data;
48615
 
+               body_part->raw_body_size = part_size;
48616
 
+               i_assert(buf->used - 1 == part->body_size.physical_size);
48617
 
+       } else {
48618
 
+               body_part->decoded_body = part_data;
48619
 
+               body_part->decoded_body_size = part_size;
48620
 
+       }
48621
 
+       
48622
 
+       /* Clear buffer */
48623
 
+       buffer_set_used_size(buf, 0);
48624
 
+}
48625
 
+
48626
 
+static const char *_parse_content_type(const struct message_header_line *hdr)
48627
 
+{
48628
 
+       struct rfc822_parser_context parser;
48629
 
+       string_t *content_type;
48630
 
+
48631
 
+       rfc822_parser_init(&parser, hdr->full_value, hdr->full_value_len, NULL);
48632
 
+       (void)rfc822_skip_lwsp(&parser);
48633
 
+
48634
 
+       content_type = t_str_new(64);
48635
 
+       if (rfc822_parse_content_type(&parser, content_type) < 0)
48636
 
+               return "";
48637
 
+       return str_c(content_type);
48638
 
+}
48639
 
+
48640
 
+/* ext_body_parts_add_missing():
48641
 
+ *   Add requested message body parts to the cache that are missing. 
48642
 
+ */
48643
 
+static bool ext_body_parts_add_missing
48644
 
+(const struct sieve_message_data *msgdata, struct ext_body_message_context *ctx, 
48645
 
+       const char * const *content_types, bool decode_to_plain)
48646
 
+{
48647
 
+       struct ext_body_part_cached *body_part = NULL;
48648
 
+       struct message_parser_ctx *parser;
48649
 
+       struct message_decoder_context *decoder;
48650
 
+       struct message_block block, decoded;
48651
 
+       struct message_part *parts, *prev_part = NULL;
48652
 
+       struct istream *input;
48653
 
+       unsigned int idx = 0;
48654
 
+       bool save_body = FALSE, have_all;
48655
 
+       int ret;
48656
 
+
48657
 
+       /* First check whether any are missing */
48658
 
+       if (ext_body_get_return_parts(ctx, content_types, decode_to_plain)) {
48659
 
+               /* Cache hit; all are present */
48660
 
+               return TRUE;
48661
 
+       }
48662
 
+
48663
 
+       /* Get the message stream */
48664
 
+       if ( mail_get_stream(msgdata->mail, NULL, NULL, &input) < 0 )
48665
 
+               return FALSE;
48666
 
+               
48667
 
+       buffer_set_used_size(ctx->tmp_buffer, 0);
48668
 
+       
48669
 
+       /* Initialize body decoder */
48670
 
+       decoder = decode_to_plain ? message_decoder_init(FALSE) : NULL;
48671
 
+       
48672
 
+       parser = message_parser_init
48673
 
+               (ctx->pool, input, 0, MESSAGE_PARSER_FLAG_SKIP_BODY_BLOCK);
48674
 
+       while ( (ret = message_parser_parse_next_block(parser, &block)) > 0 ) {
48675
 
+               if ( block.part != prev_part ) {
48676
 
+                       /* Save previous body part */
48677
 
+                       if ( body_part != NULL && save_body ) {
48678
 
+                               ext_body_part_save(ctx, prev_part, body_part, decoder != NULL);
48679
 
+                       }
48680
 
+                       
48681
 
+                       /* Start processing next */
48682
 
+                       prev_part = block.part;
48683
 
+                       body_part = array_idx_modifiable(&ctx->cached_body_parts, idx);
48684
 
+                       idx++;
48685
 
+                       body_part->content_type = "text/plain";
48686
 
+               }
48687
 
+               
48688
 
+               if ( block.hdr != NULL || block.size == 0 ) {
48689
 
+                       /* reading headers */
48690
 
+                       if ( decoder != NULL ) {
48691
 
+                               (void)message_decoder_decode_next_block(decoder,
48692
 
+                                       &block, &decoded);
48693
 
+                       }
48694
 
+
48695
 
+                       if ( block.hdr == NULL ) {
48696
 
+                               /* save bodies only if we have a wanted
48697
 
+                                  content-type */
48698
 
+                               save_body = _is_wanted_content_type
48699
 
+                                       (content_types, body_part->content_type);
48700
 
+                               continue;
48701
 
+                       }
48702
 
+                       
48703
 
+                       /* Encountered the empty line that indicates the end of the headers and 
48704
 
+                        * the start of the body
48705
 
+                        */
48706
 
+                       if ( block.hdr->eoh )
48707
 
+                               body_part->have_body = TRUE;
48708
 
+                               
48709
 
+                       /* We're interested of only Content-Type: header */
48710
 
+                       if ( strcasecmp(block.hdr->name, "Content-Type" ) != 0)
48711
 
+                               continue;
48712
 
+
48713
 
+                       /* Header can have folding whitespace. Acquire the full value before 
48714
 
+                        * continuing
48715
 
+                        */
48716
 
+                       if ( block.hdr->continues ) {
48717
 
+                               block.hdr->use_full_value = TRUE;
48718
 
+                               continue;
48719
 
+                       }
48720
 
+               
48721
 
+                       /* Parse the content type from the Content-type header */
48722
 
+                       T_BEGIN {
48723
 
+                               body_part->content_type =
48724
 
+                                       p_strdup(ctx->pool, _parse_content_type(block.hdr));
48725
 
+                       } T_END;
48726
 
+                       
48727
 
+                       continue;
48728
 
+               }
48729
 
+
48730
 
+               /* reading body */
48731
 
+               if (save_body) {
48732
 
+                       if (decoder != NULL) {
48733
 
+                               (void)message_decoder_decode_next_block(decoder,
48734
 
+                                                       &block, &decoded);
48735
 
+                               buffer_append(ctx->tmp_buffer,
48736
 
+                                             decoded.data, decoded.size);
48737
 
+                       } else {
48738
 
+                               buffer_append(ctx->tmp_buffer,
48739
 
+                                             block.data, block.size);
48740
 
+                       }
48741
 
+               }
48742
 
+       }
48743
 
+
48744
 
+       /* Save last body part if necessary */
48745
 
+       if (body_part != NULL && save_body)
48746
 
+               ext_body_part_save(ctx, prev_part, body_part, decoder != NULL);
48747
 
+
48748
 
+       /* Try to fill the return_body_parts array once more */
48749
 
+       have_all = ext_body_get_return_parts(ctx, content_types, decode_to_plain);
48750
 
+       
48751
 
+       /* This time, failure is a bug */
48752
 
+       i_assert(have_all);
48753
 
+
48754
 
+       /* Cleanup */
48755
 
+       (void)message_parser_deinit(&parser, &parts);
48756
 
+       if (decoder != NULL)
48757
 
+               message_decoder_deinit(&decoder);
48758
 
+       
48759
 
+       /* Return status */
48760
 
+       return ( input->stream_errno == 0 );
48761
 
+}
48762
 
+
48763
 
+static struct ext_body_message_context *ext_body_get_context
48764
 
+(struct sieve_message_context *msgctx)
48765
 
+{
48766
 
+       pool_t pool = sieve_message_context_pool(msgctx);
48767
 
+       struct ext_body_message_context *ctx;
48768
 
+       
48769
 
+       /* Get message context (contains cached message body information) */
48770
 
+       ctx = (struct ext_body_message_context *)
48771
 
+               sieve_message_context_extension_get(msgctx, &body_extension);
48772
 
+       
48773
 
+       /* Create it if it does not exist already */
48774
 
+       if ( ctx == NULL ) {
48775
 
+               ctx = p_new(pool, struct ext_body_message_context, 1);  
48776
 
+               ctx->pool = pool;
48777
 
+               p_array_init(&ctx->cached_body_parts, pool, 8);
48778
 
+               p_array_init(&ctx->return_body_parts, pool, 8);
48779
 
+               ctx->tmp_buffer = buffer_create_dynamic(pool, 1024*64);
48780
 
+               
48781
 
+               /* Register context */
48782
 
+               sieve_message_context_extension_set(msgctx, &body_extension, (void *) ctx);
48783
 
+       }
48784
 
+       
48785
 
+       return ctx;
48786
 
+}
48787
 
+
48788
 
+bool ext_body_get_content
48789
 
+(const struct sieve_runtime_env *renv, const char * const *content_types,
48790
 
+       int decode_to_plain, struct ext_body_part **parts_r)
48791
 
+{
48792
 
+       bool result = TRUE;
48793
 
+       struct ext_body_message_context *ctx = ext_body_get_context(renv->msgctx);
48794
 
+
48795
 
+       T_BEGIN {
48796
 
+               /* Fill the return_body_parts array */
48797
 
+               if ( !ext_body_parts_add_missing
48798
 
+                       (renv->msgdata, ctx, content_types, decode_to_plain != 0) )
48799
 
+                       result = FALSE;
48800
 
+       } T_END;
48801
 
+       
48802
 
+       /* Check status */
48803
 
+       if ( !result ) return FALSE;
48804
 
+
48805
 
+       /* Return the array of body items */
48806
 
+       (void) array_append_space(&ctx->return_body_parts); /* NULL-terminate */
48807
 
+       *parts_r = array_idx_modifiable(&ctx->return_body_parts, 0);
48808
 
+
48809
 
+       return result;
48810
 
+}
48811
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/body/ext-body-common.h dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/body/ext-body-common.h
48812
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/body/ext-body-common.h 1970-01-01 01:00:00.000000000 +0100
48813
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/body/ext-body-common.h  2009-01-06 00:15:52.000000000 +0100
48814
 
@@ -0,0 +1,38 @@
48815
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
48816
 
+ */
48817
 
48818
 
+#ifndef __EXT_BODY_COMMON_H
48819
 
+#define __EXT_BODY_COMMON_H
48820
 
+
48821
 
+/*
48822
 
+ * Extension
48823
 
+ */
48824
 
48825
 
+extern const struct sieve_extension body_extension;
48826
 
+
48827
 
+/* 
48828
 
+ * Commands
48829
 
+ */
48830
 
+
48831
 
+extern const struct sieve_command body_test;
48832
 
48833
 
+/*
48834
 
+ * Operations
48835
 
+ */
48836
 
+
48837
 
+extern const struct sieve_operation body_operation;
48838
 
+
48839
 
+/*
48840
 
+ * Message body part extraction
48841
 
+ */
48842
 
+
48843
 
+struct ext_body_part {
48844
 
+       const char *content;
48845
 
+       unsigned long size;
48846
 
+};
48847
 
+
48848
 
+bool ext_body_get_content
48849
 
+(const struct sieve_runtime_env *renv, const char * const *content_types,
48850
 
+       int decode_to_plain, struct ext_body_part **parts_r);
48851
 
+
48852
 
+#endif /* __EXT_BODY_COMMON_H */
48853
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/body/Makefile.am dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/body/Makefile.am
48854
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/body/Makefile.am       1970-01-01 01:00:00.000000000 +0100
48855
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/body/Makefile.am        2008-10-20 01:35:49.000000000 +0200
48856
 
@@ -0,0 +1,19 @@
48857
 
+noinst_LTLIBRARIES = libsieve_ext_body.la
48858
 
+
48859
 
+AM_CPPFLAGS = \
48860
 
+       -I../../ \
48861
 
+       -I$(dovecot_incdir) \
48862
 
+       -I$(dovecot_incdir)/src/lib \
48863
 
+       -I$(dovecot_incdir)/src/lib-mail \
48864
 
+       -I$(dovecot_incdir)/src/lib-storage 
48865
 
+
48866
 
+tsts = \
48867
 
+       tst-body.c
48868
 
+
48869
 
+libsieve_ext_body_la_SOURCES = \
48870
 
+       ext-body-common.c \
48871
 
+       $(tsts) \
48872
 
+       ext-body.c
48873
 
+
48874
 
+noinst_HEADERS = \
48875
 
+       ext-body-common.h
48876
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/body/Makefile.in dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/body/Makefile.in
48877
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/body/Makefile.in       1970-01-01 01:00:00.000000000 +0100
48878
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/body/Makefile.in        2009-08-21 00:55:43.000000000 +0200
48879
 
@@ -0,0 +1,468 @@
48880
 
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
48881
 
+# @configure_input@
48882
 
+
48883
 
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
48884
 
+# 2003, 2004, 2005, 2006, 2007, 2008  Free Software Foundation, Inc.
48885
 
+# This Makefile.in is free software; the Free Software Foundation
48886
 
+# gives unlimited permission to copy and/or distribute it,
48887
 
+# with or without modifications, as long as this notice is preserved.
48888
 
+
48889
 
+# This program is distributed in the hope that it will be useful,
48890
 
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
48891
 
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
48892
 
+# PARTICULAR PURPOSE.
48893
 
+
48894
 
+@SET_MAKE@
48895
 
+
48896
 
+
48897
 
+VPATH = @srcdir@
48898
 
+pkgdatadir = $(datadir)/@PACKAGE@
48899
 
+pkglibdir = $(libdir)/@PACKAGE@
48900
 
+pkgincludedir = $(includedir)/@PACKAGE@
48901
 
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
48902
 
+install_sh_DATA = $(install_sh) -c -m 644
48903
 
+install_sh_PROGRAM = $(install_sh) -c
48904
 
+install_sh_SCRIPT = $(install_sh) -c
48905
 
+INSTALL_HEADER = $(INSTALL_DATA)
48906
 
+transform = $(program_transform_name)
48907
 
+NORMAL_INSTALL = :
48908
 
+PRE_INSTALL = :
48909
 
+POST_INSTALL = :
48910
 
+NORMAL_UNINSTALL = :
48911
 
+PRE_UNINSTALL = :
48912
 
+POST_UNINSTALL = :
48913
 
+build_triplet = @build@
48914
 
+host_triplet = @host@
48915
 
+subdir = src/lib-sieve/plugins/body
48916
 
+DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
48917
 
+       $(srcdir)/Makefile.in
48918
 
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
48919
 
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
48920
 
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
48921
 
+       $(ACLOCAL_M4)
48922
 
+mkinstalldirs = $(install_sh) -d
48923
 
+CONFIG_HEADER = $(top_builddir)/dummy-config.h \
48924
 
+       $(top_builddir)/dsieve-config.h
48925
 
+CONFIG_CLEAN_FILES =
48926
 
+LTLIBRARIES = $(noinst_LTLIBRARIES)
48927
 
+libsieve_ext_body_la_LIBADD =
48928
 
+am__objects_1 = tst-body.lo
48929
 
+am_libsieve_ext_body_la_OBJECTS = ext-body-common.lo $(am__objects_1) \
48930
 
+       ext-body.lo
48931
 
+libsieve_ext_body_la_OBJECTS = $(am_libsieve_ext_body_la_OBJECTS)
48932
 
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
48933
 
+depcomp = $(SHELL) $(top_srcdir)/depcomp
48934
 
+am__depfiles_maybe = depfiles
48935
 
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
48936
 
+       $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
48937
 
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
48938
 
+       --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
48939
 
+       $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
48940
 
+CCLD = $(CC)
48941
 
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
48942
 
+       --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
48943
 
+       $(LDFLAGS) -o $@
48944
 
+SOURCES = $(libsieve_ext_body_la_SOURCES)
48945
 
+DIST_SOURCES = $(libsieve_ext_body_la_SOURCES)
48946
 
+HEADERS = $(noinst_HEADERS)
48947
 
+ETAGS = etags
48948
 
+CTAGS = ctags
48949
 
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
48950
 
+ACLOCAL = @ACLOCAL@
48951
 
+AMTAR = @AMTAR@
48952
 
+AR = @AR@
48953
 
+AUTOCONF = @AUTOCONF@
48954
 
+AUTOHEADER = @AUTOHEADER@
48955
 
+AUTOMAKE = @AUTOMAKE@
48956
 
+AWK = @AWK@
48957
 
+CC = @CC@
48958
 
+CCDEPMODE = @CCDEPMODE@
48959
 
+CFLAGS = @CFLAGS@
48960
 
+CPP = @CPP@
48961
 
+CPPFLAGS = @CPPFLAGS@
48962
 
+CYGPATH_W = @CYGPATH_W@
48963
 
+DEFS = @DEFS@
48964
 
+DEPDIR = @DEPDIR@
48965
 
+DSYMUTIL = @DSYMUTIL@
48966
 
+DUMPBIN = @DUMPBIN@
48967
 
+ECHO_C = @ECHO_C@
48968
 
+ECHO_N = @ECHO_N@
48969
 
+ECHO_T = @ECHO_T@
48970
 
+EGREP = @EGREP@
48971
 
+EXEEXT = @EXEEXT@
48972
 
+FGREP = @FGREP@
48973
 
+GREP = @GREP@
48974
 
+INSTALL = @INSTALL@
48975
 
+INSTALL_DATA = @INSTALL_DATA@
48976
 
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
48977
 
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
48978
 
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
48979
 
+LD = @LD@
48980
 
+LDFLAGS = @LDFLAGS@
48981
 
+LIBICONV = @LIBICONV@
48982
 
+LIBOBJS = @LIBOBJS@
48983
 
+LIBS = @LIBS@
48984
 
+LIBTOOL = @LIBTOOL@
48985
 
+LIPO = @LIPO@
48986
 
+LN_S = @LN_S@
48987
 
+LTLIBOBJS = @LTLIBOBJS@
48988
 
+MAINT = @MAINT@
48989
 
+MAKEINFO = @MAKEINFO@
48990
 
+MKDIR_P = @MKDIR_P@
48991
 
+MODULE_LIBS = @MODULE_LIBS@
48992
 
+NM = @NM@
48993
 
+NMEDIT = @NMEDIT@
48994
 
+OBJDUMP = @OBJDUMP@
48995
 
+OBJEXT = @OBJEXT@
48996
 
+OTOOL = @OTOOL@
48997
 
+OTOOL64 = @OTOOL64@
48998
 
+PACKAGE = @PACKAGE@
48999
 
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
49000
 
+PACKAGE_NAME = @PACKAGE_NAME@
49001
 
+PACKAGE_STRING = @PACKAGE_STRING@
49002
 
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
49003
 
+PACKAGE_URL = @PACKAGE_URL@
49004
 
+PACKAGE_VERSION = @PACKAGE_VERSION@
49005
 
+PATH_SEPARATOR = @PATH_SEPARATOR@
49006
 
+RAND_LIBS = @RAND_LIBS@
49007
 
+RANLIB = @RANLIB@
49008
 
+SED = @SED@
49009
 
+SET_MAKE = @SET_MAKE@
49010
 
+SHELL = @SHELL@
49011
 
+STORAGE_LIBS = @STORAGE_LIBS@
49012
 
+STRIP = @STRIP@
49013
 
+VERSION = @VERSION@
49014
 
+abs_builddir = @abs_builddir@
49015
 
+abs_srcdir = @abs_srcdir@
49016
 
+abs_top_builddir = @abs_top_builddir@
49017
 
+abs_top_srcdir = @abs_top_srcdir@
49018
 
+ac_ct_CC = @ac_ct_CC@
49019
 
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
49020
 
+am__include = @am__include@
49021
 
+am__leading_dot = @am__leading_dot@
49022
 
+am__quote = @am__quote@
49023
 
+am__tar = @am__tar@
49024
 
+am__untar = @am__untar@
49025
 
+bindir = @bindir@
49026
 
+build = @build@
49027
 
+build_alias = @build_alias@
49028
 
+build_cpu = @build_cpu@
49029
 
+build_os = @build_os@
49030
 
+build_vendor = @build_vendor@
49031
 
+builddir = @builddir@
49032
 
+datadir = @datadir@
49033
 
+datarootdir = @datarootdir@
49034
 
+docdir = @docdir@
49035
 
+dovecot_incdir = @dovecot_incdir@
49036
 
+dovecotdir = @dovecotdir@
49037
 
+dvidir = @dvidir@
49038
 
+exec_prefix = @exec_prefix@
49039
 
+host = @host@
49040
 
+host_alias = @host_alias@
49041
 
+host_cpu = @host_cpu@
49042
 
+host_os = @host_os@
49043
 
+host_vendor = @host_vendor@
49044
 
+htmldir = @htmldir@
49045
 
+includedir = @includedir@
49046
 
+infodir = @infodir@
49047
 
+install_sh = @install_sh@
49048
 
+libdir = @libdir@
49049
 
+libexecdir = @libexecdir@
49050
 
+localedir = @localedir@
49051
 
+localstatedir = @localstatedir@
49052
 
+lt_ECHO = @lt_ECHO@
49053
 
+mandir = @mandir@
49054
 
+mkdir_p = @mkdir_p@
49055
 
+moduledir = @moduledir@
49056
 
+oldincludedir = @oldincludedir@
49057
 
+pdfdir = @pdfdir@
49058
 
+prefix = @prefix@
49059
 
+program_transform_name = @program_transform_name@
49060
 
+psdir = @psdir@
49061
 
+sbindir = @sbindir@
49062
 
+sharedstatedir = @sharedstatedir@
49063
 
+srcdir = @srcdir@
49064
 
+sysconfdir = @sysconfdir@
49065
 
+target_alias = @target_alias@
49066
 
+top_build_prefix = @top_build_prefix@
49067
 
+top_builddir = @top_builddir@
49068
 
+top_srcdir = @top_srcdir@
49069
 
+noinst_LTLIBRARIES = libsieve_ext_body.la
49070
 
+AM_CPPFLAGS = \
49071
 
+       -I../../ \
49072
 
+       -I$(dovecot_incdir) \
49073
 
+       -I$(dovecot_incdir)/src/lib \
49074
 
+       -I$(dovecot_incdir)/src/lib-mail \
49075
 
+       -I$(dovecot_incdir)/src/lib-storage 
49076
 
+
49077
 
+tsts = \
49078
 
+       tst-body.c
49079
 
+
49080
 
+libsieve_ext_body_la_SOURCES = \
49081
 
+       ext-body-common.c \
49082
 
+       $(tsts) \
49083
 
+       ext-body.c
49084
 
+
49085
 
+noinst_HEADERS = \
49086
 
+       ext-body-common.h
49087
 
+
49088
 
+all: all-am
49089
 
+
49090
 
+.SUFFIXES:
49091
 
+.SUFFIXES: .c .lo .o .obj
49092
 
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
49093
 
+       @for dep in $?; do \
49094
 
+         case '$(am__configure_deps)' in \
49095
 
+           *$$dep*) \
49096
 
+             ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
49097
 
+               && { if test -f $@; then exit 0; else break; fi; }; \
49098
 
+             exit 1;; \
49099
 
+         esac; \
49100
 
+       done; \
49101
 
+       echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign  src/lib-sieve/plugins/body/Makefile'; \
49102
 
+       cd $(top_srcdir) && \
49103
 
+         $(AUTOMAKE) --foreign  src/lib-sieve/plugins/body/Makefile
49104
 
+.PRECIOUS: Makefile
49105
 
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
49106
 
+       @case '$?' in \
49107
 
+         *config.status*) \
49108
 
+           cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
49109
 
+         *) \
49110
 
+           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
49111
 
+           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
49112
 
+       esac;
49113
 
+
49114
 
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
49115
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
49116
 
+
49117
 
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
49118
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
49119
 
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
49120
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
49121
 
+
49122
 
+clean-noinstLTLIBRARIES:
49123
 
+       -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
49124
 
+       @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
49125
 
+         dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
49126
 
+         test "$$dir" != "$$p" || dir=.; \
49127
 
+         echo "rm -f \"$${dir}/so_locations\""; \
49128
 
+         rm -f "$${dir}/so_locations"; \
49129
 
+       done
49130
 
+libsieve_ext_body.la: $(libsieve_ext_body_la_OBJECTS) $(libsieve_ext_body_la_DEPENDENCIES) 
49131
 
+       $(LINK)  $(libsieve_ext_body_la_OBJECTS) $(libsieve_ext_body_la_LIBADD) $(LIBS)
49132
 
+
49133
 
+mostlyclean-compile:
49134
 
+       -rm -f *.$(OBJEXT)
49135
 
+
49136
 
+distclean-compile:
49137
 
+       -rm -f *.tab.c
49138
 
+
49139
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-body-common.Plo@am__quote@
49140
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-body.Plo@am__quote@
49141
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tst-body.Plo@am__quote@
49142
 
+
49143
 
+.c.o:
49144
 
+@am__fastdepCC_TRUE@   $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
49145
 
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
49146
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
49147
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
49148
 
+@am__fastdepCC_FALSE@  $(COMPILE) -c $<
49149
 
+
49150
 
+.c.obj:
49151
 
+@am__fastdepCC_TRUE@   $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
49152
 
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
49153
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
49154
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
49155
 
+@am__fastdepCC_FALSE@  $(COMPILE) -c `$(CYGPATH_W) '$<'`
49156
 
+
49157
 
+.c.lo:
49158
 
+@am__fastdepCC_TRUE@   $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
49159
 
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
49160
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
49161
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
49162
 
+@am__fastdepCC_FALSE@  $(LTCOMPILE) -c -o $@ $<
49163
 
+
49164
 
+mostlyclean-libtool:
49165
 
+       -rm -f *.lo
49166
 
+
49167
 
+clean-libtool:
49168
 
+       -rm -rf .libs _libs
49169
 
+
49170
 
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
49171
 
+       list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
49172
 
+       unique=`for i in $$list; do \
49173
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
49174
 
+         done | \
49175
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
49176
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
49177
 
+       mkid -fID $$unique
49178
 
+tags: TAGS
49179
 
+
49180
 
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
49181
 
+               $(TAGS_FILES) $(LISP)
49182
 
+       tags=; \
49183
 
+       here=`pwd`; \
49184
 
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
49185
 
+       unique=`for i in $$list; do \
49186
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
49187
 
+         done | \
49188
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
49189
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
49190
 
+       if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
49191
 
+         test -n "$$unique" || unique=$$empty_fix; \
49192
 
+         $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
49193
 
+           $$tags $$unique; \
49194
 
+       fi
49195
 
+ctags: CTAGS
49196
 
+CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
49197
 
+               $(TAGS_FILES) $(LISP)
49198
 
+       tags=; \
49199
 
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
49200
 
+       unique=`for i in $$list; do \
49201
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
49202
 
+         done | \
49203
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
49204
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
49205
 
+       test -z "$(CTAGS_ARGS)$$tags$$unique" \
49206
 
+         || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
49207
 
+            $$tags $$unique
49208
 
+
49209
 
+GTAGS:
49210
 
+       here=`$(am__cd) $(top_builddir) && pwd` \
49211
 
+         && cd $(top_srcdir) \
49212
 
+         && gtags -i $(GTAGS_ARGS) $$here
49213
 
+
49214
 
+distclean-tags:
49215
 
+       -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
49216
 
+
49217
 
+distdir: $(DISTFILES)
49218
 
+       @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
49219
 
+       topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
49220
 
+       list='$(DISTFILES)'; \
49221
 
+         dist_files=`for file in $$list; do echo $$file; done | \
49222
 
+         sed -e "s|^$$srcdirstrip/||;t" \
49223
 
+             -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
49224
 
+       case $$dist_files in \
49225
 
+         */*) $(MKDIR_P) `echo "$$dist_files" | \
49226
 
+                          sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
49227
 
+                          sort -u` ;; \
49228
 
+       esac; \
49229
 
+       for file in $$dist_files; do \
49230
 
+         if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
49231
 
+         if test -d $$d/$$file; then \
49232
 
+           dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
49233
 
+           if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
49234
 
+             cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
49235
 
+           fi; \
49236
 
+           cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
49237
 
+         else \
49238
 
+           test -f $(distdir)/$$file \
49239
 
+           || cp -p $$d/$$file $(distdir)/$$file \
49240
 
+           || exit 1; \
49241
 
+         fi; \
49242
 
+       done
49243
 
+check-am: all-am
49244
 
+check: check-am
49245
 
+all-am: Makefile $(LTLIBRARIES) $(HEADERS)
49246
 
+installdirs:
49247
 
+install: install-am
49248
 
+install-exec: install-exec-am
49249
 
+install-data: install-data-am
49250
 
+uninstall: uninstall-am
49251
 
+
49252
 
+install-am: all-am
49253
 
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
49254
 
+
49255
 
+installcheck: installcheck-am
49256
 
+install-strip:
49257
 
+       $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
49258
 
+         install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
49259
 
+         `test -z '$(STRIP)' || \
49260
 
+           echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
49261
 
+mostlyclean-generic:
49262
 
+
49263
 
+clean-generic:
49264
 
+
49265
 
+distclean-generic:
49266
 
+       -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
49267
 
+
49268
 
+maintainer-clean-generic:
49269
 
+       @echo "This command is intended for maintainers to use"
49270
 
+       @echo "it deletes files that may require special tools to rebuild."
49271
 
+clean: clean-am
49272
 
+
49273
 
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
49274
 
+       mostlyclean-am
49275
 
+
49276
 
+distclean: distclean-am
49277
 
+       -rm -rf ./$(DEPDIR)
49278
 
+       -rm -f Makefile
49279
 
+distclean-am: clean-am distclean-compile distclean-generic \
49280
 
+       distclean-tags
49281
 
+
49282
 
+dvi: dvi-am
49283
 
+
49284
 
+dvi-am:
49285
 
+
49286
 
+html: html-am
49287
 
+
49288
 
+info: info-am
49289
 
+
49290
 
+info-am:
49291
 
+
49292
 
+install-data-am:
49293
 
+
49294
 
+install-dvi: install-dvi-am
49295
 
+
49296
 
+install-exec-am:
49297
 
+
49298
 
+install-html: install-html-am
49299
 
+
49300
 
+install-info: install-info-am
49301
 
+
49302
 
+install-man:
49303
 
+
49304
 
+install-pdf: install-pdf-am
49305
 
+
49306
 
+install-ps: install-ps-am
49307
 
+
49308
 
+installcheck-am:
49309
 
+
49310
 
+maintainer-clean: maintainer-clean-am
49311
 
+       -rm -rf ./$(DEPDIR)
49312
 
+       -rm -f Makefile
49313
 
+maintainer-clean-am: distclean-am maintainer-clean-generic
49314
 
+
49315
 
+mostlyclean: mostlyclean-am
49316
 
+
49317
 
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
49318
 
+       mostlyclean-libtool
49319
 
+
49320
 
+pdf: pdf-am
49321
 
+
49322
 
+pdf-am:
49323
 
+
49324
 
+ps: ps-am
49325
 
+
49326
 
+ps-am:
49327
 
+
49328
 
+uninstall-am:
49329
 
+
49330
 
+.MAKE: install-am install-strip
49331
 
+
49332
 
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
49333
 
+       clean-libtool clean-noinstLTLIBRARIES ctags distclean \
49334
 
+       distclean-compile distclean-generic distclean-libtool \
49335
 
+       distclean-tags distdir dvi dvi-am html html-am info info-am \
49336
 
+       install install-am install-data install-data-am install-dvi \
49337
 
+       install-dvi-am install-exec install-exec-am install-html \
49338
 
+       install-html-am install-info install-info-am install-man \
49339
 
+       install-pdf install-pdf-am install-ps install-ps-am \
49340
 
+       install-strip installcheck installcheck-am installdirs \
49341
 
+       maintainer-clean maintainer-clean-generic mostlyclean \
49342
 
+       mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
49343
 
+       pdf pdf-am ps ps-am tags uninstall uninstall-am
49344
 
+
49345
 
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
49346
 
+# Otherwise a system limit (for SysV at least) may be exceeded.
49347
 
+.NOEXPORT:
49348
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/body/tst-body.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/body/tst-body.c
49349
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/body/tst-body.c        1970-01-01 01:00:00.000000000 +0100
49350
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/body/tst-body.c 2009-08-08 14:57:37.000000000 +0200
49351
 
@@ -0,0 +1,425 @@
49352
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
49353
 
+ */
49354
 
49355
 
+#include "sieve-extensions.h"
49356
 
+#include "sieve-commands.h"
49357
 
+#include "sieve-code.h"
49358
 
+#include "sieve-comparators.h"
49359
 
+#include "sieve-match-types.h"
49360
 
+#include "sieve-address-parts.h"
49361
 
+
49362
 
+#include "sieve-validator.h"
49363
 
+#include "sieve-generator.h"
49364
 
+#include "sieve-binary.h"
49365
 
+#include "sieve-interpreter.h"
49366
 
+#include "sieve-dump.h"
49367
 
+#include "sieve-match.h"
49368
 
+
49369
 
+#include "ext-body-common.h"
49370
 
+
49371
 
+/*
49372
 
+ * Types
49373
 
+ */
49374
 
+
49375
 
+enum tst_body_transform {
49376
 
+       TST_BODY_TRANSFORM_RAW,
49377
 
+       TST_BODY_TRANSFORM_CONTENT,
49378
 
+       TST_BODY_TRANSFORM_TEXT
49379
 
+};
49380
 
+
49381
 
+/* 
49382
 
+ * Body test 
49383
 
+ *
49384
 
+ * Syntax
49385
 
+ *   body [COMPARATOR] [MATCH-TYPE] [BODY-TRANSFORM]
49386
 
+ *     <key-list: string-list>
49387
 
+ */
49388
 
+
49389
 
+static bool tst_body_registered
49390
 
+       (struct sieve_validator *validator, struct sieve_command_registration *cmd_reg);
49391
 
+static bool tst_body_validate
49392
 
+       (struct sieve_validator *validator, struct sieve_command_context *tst);
49393
 
+static bool tst_body_generate
49394
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx);
49395
 
+
49396
 
+const struct sieve_command body_test = { 
49397
 
+       "body", 
49398
 
+       SCT_TEST, 
49399
 
+       1, 0, FALSE, FALSE,
49400
 
+       tst_body_registered, 
49401
 
+       NULL,
49402
 
+       tst_body_validate, 
49403
 
+       tst_body_generate, 
49404
 
+       NULL 
49405
 
+};
49406
 
+
49407
 
+/* 
49408
 
+ * Body operation 
49409
 
+ */
49410
 
+
49411
 
+static bool ext_body_operation_dump
49412
 
+       (const struct sieve_operation *op, 
49413
 
+               const struct sieve_dumptime_env *denv, sieve_size_t *address);
49414
 
+static int ext_body_operation_execute
49415
 
+       (const struct sieve_operation *op,
49416
 
+               const struct sieve_runtime_env *renv, sieve_size_t *address);
49417
 
+
49418
 
+const struct sieve_operation body_operation = { 
49419
 
+       "body",
49420
 
+       &body_extension,
49421
 
+       0,
49422
 
+       ext_body_operation_dump, 
49423
 
+       ext_body_operation_execute 
49424
 
+};
49425
 
+
49426
 
+/*
49427
 
+ * Optional operands
49428
 
+ */
49429
 
+
49430
 
+enum tst_body_optional {       
49431
 
+       OPT_BODY_TRANSFORM = SIEVE_MATCH_OPT_LAST
49432
 
+};
49433
 
+
49434
 
+/* 
49435
 
+ * Tagged arguments 
49436
 
+ */
49437
 
+
49438
 
+/* Forward declarations */
49439
 
+
49440
 
+static bool tag_body_transform_validate
49441
 
+       (struct sieve_validator *validator, struct sieve_ast_argument **arg, 
49442
 
+               struct sieve_command_context *cmd);
49443
 
+static bool tag_body_transform_generate        
49444
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, 
49445
 
+               struct sieve_command_context *cmd);
49446
 
+
49447
 
+/* Argument objects */
49448
 
49449
 
+static const struct sieve_argument body_raw_tag = { 
49450
 
+       "raw", 
49451
 
+       NULL, NULL,
49452
 
+       tag_body_transform_validate, 
49453
 
+       NULL, 
49454
 
+       tag_body_transform_generate 
49455
 
+};
49456
 
+
49457
 
+static const struct sieve_argument body_content_tag = { 
49458
 
+       "content", 
49459
 
+       NULL, NULL,
49460
 
+       tag_body_transform_validate, 
49461
 
+       NULL, 
49462
 
+       tag_body_transform_generate 
49463
 
+};
49464
 
+
49465
 
+static const struct sieve_argument body_text_tag = { 
49466
 
+       "text", 
49467
 
+       NULL, NULL,
49468
 
+       tag_body_transform_validate, 
49469
 
+       NULL, 
49470
 
+       tag_body_transform_generate
49471
 
+};
49472
 
+
49473
 
+/* Argument implementation */
49474
 
49475
 
+static bool tag_body_transform_validate
49476
 
+(struct sieve_validator *validator, struct sieve_ast_argument **arg, 
49477
 
+       struct sieve_command_context *cmd)
49478
 
+{
49479
 
+       enum tst_body_transform transform;
49480
 
+       struct sieve_ast_argument *tag = *arg;
49481
 
+
49482
 
+       /* BODY-TRANSFORM:
49483
 
+        *   :raw
49484
 
+        *     / :content <content-types: string-list>
49485
 
+        *     / :text
49486
 
+        */
49487
 
+       if ( (bool) cmd->data ) {
49488
 
+               sieve_argument_validate_error(validator, *arg, 
49489
 
+                       "the :raw, :content and :text arguments for the body test are mutually "
49490
 
+                       "exclusive, but more than one was specified");
49491
 
+               return FALSE;
49492
 
+       }
49493
 
+
49494
 
+       /* Skip tag */
49495
 
+       *arg = sieve_ast_argument_next(*arg);
49496
 
+
49497
 
+       /* :content tag has a string-list argument */
49498
 
+       if ( tag->argument == &body_raw_tag ) 
49499
 
+               transform = TST_BODY_TRANSFORM_RAW;
49500
 
+               
49501
 
+       else if ( tag->argument == &body_text_tag )
49502
 
+               transform = TST_BODY_TRANSFORM_TEXT;
49503
 
+               
49504
 
+       else if ( tag->argument == &body_content_tag ) {
49505
 
+               /* Check syntax:
49506
 
+                *   :content <content-types: string-list>
49507
 
+                */
49508
 
+               if ( !sieve_validate_tag_parameter
49509
 
+                       (validator, cmd, tag, *arg, SAAT_STRING_LIST) ) {
49510
 
+                       return FALSE;
49511
 
+               }
49512
 
+               
49513
 
+               if ( !sieve_validator_argument_activate(validator, cmd, *arg, FALSE) )
49514
 
+                       return FALSE;
49515
 
+               
49516
 
+               /* Assign tag parameters */
49517
 
+               tag->parameters = *arg;
49518
 
+               *arg = sieve_ast_arguments_detach(*arg,1);
49519
 
+               
49520
 
+               transform = TST_BODY_TRANSFORM_CONTENT;
49521
 
+       } else 
49522
 
+               return FALSE;
49523
 
+       
49524
 
+       /* Signal the presence of this tag */
49525
 
+       cmd->data = (void *) TRUE;
49526
 
+               
49527
 
+       /* Assign context data */
49528
 
+       tag->context = (void *) transform;      
49529
 
+               
49530
 
+       return TRUE;
49531
 
+}
49532
 
+
49533
 
+/* 
49534
 
+ * Command Registration 
49535
 
+ */
49536
 
+
49537
 
+static bool tst_body_registered
49538
 
+(struct sieve_validator *validator, struct sieve_command_registration *cmd_reg) 
49539
 
+{
49540
 
+       /* The order of these is not significant */
49541
 
+       sieve_comparators_link_tag(validator, cmd_reg, SIEVE_MATCH_OPT_COMPARATOR);
49542
 
+       sieve_match_types_link_tags(validator, cmd_reg, SIEVE_MATCH_OPT_MATCH_TYPE);
49543
 
+       
49544
 
+       sieve_validator_register_tag
49545
 
+               (validator, cmd_reg, &body_raw_tag, OPT_BODY_TRANSFORM);        
49546
 
+       sieve_validator_register_tag
49547
 
+               (validator, cmd_reg, &body_content_tag, OPT_BODY_TRANSFORM);    
49548
 
+       sieve_validator_register_tag
49549
 
+               (validator, cmd_reg, &body_text_tag, OPT_BODY_TRANSFORM);       
49550
 
+       
49551
 
+       return TRUE;
49552
 
+}
49553
 
+
49554
 
+/* 
49555
 
+ * Validation 
49556
 
+ */
49557
 
49558
 
+static bool tst_body_validate
49559
 
+(struct sieve_validator *validator, struct sieve_command_context *tst) 
49560
 
+{              
49561
 
+       struct sieve_ast_argument *arg = tst->first_positional;
49562
 
+                                       
49563
 
+       if ( !sieve_validate_positional_argument
49564
 
+               (validator, tst, arg, "key list", 1, SAAT_STRING_LIST) ) {
49565
 
+               return FALSE;
49566
 
+       }
49567
 
+
49568
 
+       if ( !sieve_validator_argument_activate(validator, tst, arg, FALSE) )
49569
 
+               return FALSE;
49570
 
+
49571
 
+       /* Validate the key argument to a specified match type */
49572
 
+       return sieve_match_type_validate
49573
 
+               (validator, tst, arg, &is_match_type, &i_ascii_casemap_comparator);
49574
 
+}
49575
 
+
49576
 
+/*
49577
 
+ * Code generation
49578
 
+ */
49579
 
49580
 
+static bool tst_body_generate
49581
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx) 
49582
 
+{
49583
 
+       (void)sieve_operation_emit_code(cgenv->sbin, &body_operation);
49584
 
+
49585
 
+       /* Generate arguments */
49586
 
+       return sieve_generate_arguments(cgenv, ctx, NULL);
49587
 
+}
49588
 
+
49589
 
+static bool tag_body_transform_generate
49590
 
+(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, 
49591
 
+       struct sieve_command_context *cmd ATTR_UNUSED)
49592
 
+{
49593
 
+       enum tst_body_transform transform =     (enum tst_body_transform) arg->context;
49594
 
+       
49595
 
+       sieve_binary_emit_byte(cgenv->sbin, transform);
49596
 
+       sieve_generate_argument_parameters(cgenv, cmd, arg); 
49597
 
+                       
49598
 
+       return TRUE;
49599
 
+}
49600
 
+
49601
 
+/* 
49602
 
+ * Code dump 
49603
 
+ */
49604
 
49605
 
+static bool ext_body_operation_dump
49606
 
+(const struct sieve_operation *op ATTR_UNUSED, 
49607
 
+       const struct sieve_dumptime_env *denv, sieve_size_t *address)
49608
 
+{
49609
 
+       enum tst_body_transform transform;
49610
 
+       int opt_code = 0;
49611
 
+
49612
 
+       sieve_code_dumpf(denv, "BODY");
49613
 
+       sieve_code_descend(denv);
49614
 
+
49615
 
+       /* Handle any optional arguments */
49616
 
+       do {
49617
 
+               
49618
 
+               if ( !sieve_match_dump_optional_operands(denv, address, &opt_code) )
49619
 
+                       return FALSE;
49620
 
+
49621
 
+               switch ( opt_code ) {
49622
 
+               case SIEVE_MATCH_OPT_END:
49623
 
+                       break;
49624
 
+               case OPT_BODY_TRANSFORM:
49625
 
+                       if ( !sieve_binary_read_byte(denv->sbin, address, &transform) )
49626
 
+                               return FALSE;
49627
 
+                       
49628
 
+                       switch ( transform ) {
49629
 
+                       case TST_BODY_TRANSFORM_RAW:
49630
 
+                               sieve_code_dumpf(denv, "BODY-TRANSFORM: RAW");
49631
 
+                               break;
49632
 
+                       case TST_BODY_TRANSFORM_TEXT:
49633
 
+                               sieve_code_dumpf(denv, "BODY-TRANSFORM: TEXT");
49634
 
+                               break;
49635
 
+                       case TST_BODY_TRANSFORM_CONTENT:
49636
 
+                               sieve_code_dumpf(denv, "BODY-TRANSFORM: CONTENT");
49637
 
+                               
49638
 
+                               sieve_code_descend(denv);
49639
 
+                               if ( !sieve_opr_stringlist_dump(denv, address, "content types") )
49640
 
+                                       return FALSE;
49641
 
+                               sieve_code_ascend(denv);
49642
 
+                               break;
49643
 
+                       default:
49644
 
+                               return FALSE;
49645
 
+                       }
49646
 
+                       break;
49647
 
+               default: 
49648
 
+                       return FALSE;
49649
 
+               }
49650
 
+       } while ( opt_code != SIEVE_MATCH_OPT_END );
49651
 
+
49652
 
+       return sieve_opr_stringlist_dump(denv, address, "key list");
49653
 
+}
49654
 
+
49655
 
+/*
49656
 
+ * Interpretation
49657
 
+ */
49658
 
+
49659
 
+static int ext_body_operation_execute
49660
 
+(const struct sieve_operation *op ATTR_UNUSED,
49661
 
+       const struct sieve_runtime_env *renv, sieve_size_t *address)
49662
 
+{
49663
 
+       static const char * const _no_content_types[] = { "", NULL };
49664
 
+       
49665
 
+       int ret = SIEVE_EXEC_OK;
49666
 
+       int opt_code = 0;
49667
 
+       int mret;
49668
 
+       const struct sieve_comparator *cmp = &i_ascii_casemap_comparator;
49669
 
+       const struct sieve_match_type *mtch = &is_match_type;
49670
 
+       enum tst_body_transform transform;
49671
 
+       struct sieve_coded_stringlist *key_list, *ctype_list = NULL;
49672
 
+       struct sieve_match_context *mctx;
49673
 
+       const char * const *content_types = _no_content_types;
49674
 
+       struct ext_body_part *body_parts;
49675
 
+       bool mvalues_active;
49676
 
+       bool matched;
49677
 
+
49678
 
+       /*
49679
 
+        * Read operands
49680
 
+        */
49681
 
+       
49682
 
+       /* Handle any optional operands */
49683
 
+       do {
49684
 
+               if ( (ret=sieve_match_read_optional_operands
49685
 
+                       (renv, address, &opt_code, &cmp, &mtch)) <= 0 )
49686
 
+                       return ret;
49687
 
+                       
49688
 
+               switch ( opt_code ) {
49689
 
+               case SIEVE_MATCH_OPT_END: 
49690
 
+                       break;
49691
 
+               case OPT_BODY_TRANSFORM:
49692
 
+                       if ( !sieve_binary_read_byte(renv->sbin, address, &transform) ||
49693
 
+                               transform > TST_BODY_TRANSFORM_TEXT ) {
49694
 
+                               sieve_runtime_trace_error(renv, "invalid body transform type");
49695
 
+                               return SIEVE_EXEC_BIN_CORRUPT;
49696
 
+                       }
49697
 
+                       
49698
 
+                       if ( transform == TST_BODY_TRANSFORM_CONTENT ) {                                
49699
 
+                               if ( (ctype_list=sieve_opr_stringlist_read(renv, address)) 
49700
 
+                                       == NULL ) {
49701
 
+                                       sieve_runtime_trace_error(renv, 
49702
 
+                                               "invalid :content body transform operand");
49703
 
+                                       return SIEVE_EXEC_BIN_CORRUPT;
49704
 
+                               }
49705
 
+                       }
49706
 
+                       break;
49707
 
+
49708
 
+               default:
49709
 
+                       sieve_runtime_trace_error(renv, "unknown optional operand");
49710
 
+                       return SIEVE_EXEC_BIN_CORRUPT;
49711
 
+               }
49712
 
+       } while ( opt_code != SIEVE_MATCH_OPT_END );
49713
 
+               
49714
 
+       /* Read key-list */
49715
 
+       if ( (key_list=sieve_opr_stringlist_read(renv, address)) == NULL ) {
49716
 
+               sieve_runtime_trace_error(renv, "invalid key-list operand");
49717
 
+               return SIEVE_EXEC_BIN_CORRUPT;
49718
 
+       }
49719
 
+       
49720
 
+       if ( ctype_list != NULL && !sieve_coded_stringlist_read_all
49721
 
+               (ctype_list, pool_datastack_create(), &content_types) ) {
49722
 
+               sieve_runtime_trace_error(renv, "invalid content-type-list operand");
49723
 
+               return SIEVE_EXEC_BIN_CORRUPT;
49724
 
+       }
49725
 
+       
49726
 
+       /*
49727
 
+        * Perform operation
49728
 
+        */
49729
 
+
49730
 
+       sieve_runtime_trace(renv, "BODY action");
49731
 
+       
49732
 
+       /* Extract requested parts */
49733
 
+       
49734
 
+       if ( !ext_body_get_content
49735
 
+               (renv, content_types, transform != TST_BODY_TRANSFORM_RAW, &body_parts) ) {
49736
 
+               return SIEVE_EXEC_FAILURE;
49737
 
+       }
49738
 
+
49739
 
+       /* Disable match values processing as required by RFC */
49740
 
+               
49741
 
+       mvalues_active = sieve_match_values_set_enabled(renv->interp, FALSE);
49742
 
+
49743
 
+       /* Iterate through all requested body parts to match */
49744
 
+
49745
 
+       matched = FALSE;        
49746
 
+       mctx = sieve_match_begin(renv->interp, mtch, cmp, NULL, key_list);      
49747
 
+       while ( !matched && body_parts->content != NULL ) {
49748
 
+               if ( (mret=sieve_match_value(mctx, body_parts->content, body_parts->size))      
49749
 
+                       < 0) 
49750
 
+               {
49751
 
+                       sieve_runtime_trace_error(renv, "invalid string list item");
49752
 
+                       ret = SIEVE_EXEC_BIN_CORRUPT;
49753
 
+                       break;
49754
 
+               }
49755
 
+               
49756
 
+               matched = ( mret > 0 );                 
49757
 
+               body_parts++;   
49758
 
+       }
49759
 
+
49760
 
+       if ( (mret=sieve_match_end(&mctx)) < 0 ) {
49761
 
+               sieve_runtime_trace_error(renv, "invalid string list item");
49762
 
+               ret = SIEVE_EXEC_BIN_CORRUPT;
49763
 
+       } else  
49764
 
+               matched = ( mret > 0 || matched );      
49765
 
+       
49766
 
+       /* Restore match values processing */ 
49767
 
+       
49768
 
+       (void)sieve_match_values_set_enabled(renv->interp, mvalues_active);
49769
 
+       
49770
 
+       /* Set test result */   
49771
 
+       
49772
 
+       if ( ret == SIEVE_EXEC_OK )
49773
 
+               sieve_interpreter_set_test_result(renv->interp, matched);
49774
 
+
49775
 
+       return ret;
49776
 
+}
49777
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/comparator-i-ascii-numeric/ext-cmp-i-ascii-numeric.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/comparator-i-ascii-numeric/ext-cmp-i-ascii-numeric.c
49778
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/comparator-i-ascii-numeric/ext-cmp-i-ascii-numeric.c   1970-01-01 01:00:00.000000000 +0100
49779
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/comparator-i-ascii-numeric/ext-cmp-i-ascii-numeric.c    2009-01-06 00:15:52.000000000 +0100
49780
 
@@ -0,0 +1,166 @@
49781
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
49782
 
+ */ 
49783
 
+
49784
 
+/* Extension comparator-i;ascii-numeric
49785
 
+ * ------------------------------------
49786
 
+ *
49787
 
+ * Author: Stephan Bosch
49788
 
+ * Specification: RFC 2244
49789
 
+ * Implementation: full
49790
 
+ * Status: experimental, largely untested
49791
 
+ * 
49792
 
+ */
49793
 
49794
 
+#include "sieve-common.h"
49795
 
+
49796
 
+#include "sieve-code.h"
49797
 
+#include "sieve-extensions.h"
49798
 
+#include "sieve-comparators.h"
49799
 
+#include "sieve-validator.h"
49800
 
+#include "sieve-generator.h"
49801
 
+#include "sieve-interpreter.h"
49802
 
+
49803
 
+#include <ctype.h>
49804
 
+
49805
 
+/* 
49806
 
+ * Forward declarations 
49807
 
+ */
49808
 
+
49809
 
+static const struct sieve_operand my_comparator_operand;
49810
 
+
49811
 
+const struct sieve_comparator i_ascii_numeric_comparator;
49812
 
+
49813
 
+static bool ext_cmp_i_ascii_numeric_validator_load
49814
 
+       (struct sieve_validator *validator);
49815
 
+
49816
 
+/* 
49817
 
+ * Extension
49818
 
+ */
49819
 
+
49820
 
+static int ext_my_id = -1;
49821
 
+
49822
 
+const struct sieve_extension comparator_i_ascii_numeric_extension = { 
49823
 
+       "comparator-i;ascii-numeric", 
49824
 
+       &ext_my_id,
49825
 
+       NULL, NULL,
49826
 
+       ext_cmp_i_ascii_numeric_validator_load,
49827
 
+       NULL, NULL, NULL, NULL, NULL,
49828
 
+       SIEVE_EXT_DEFINE_NO_OPERATIONS, 
49829
 
+       SIEVE_EXT_DEFINE_OPERAND(my_comparator_operand)
49830
 
+};
49831
 
+
49832
 
+static bool ext_cmp_i_ascii_numeric_validator_load
49833
 
+       (struct sieve_validator *validator)
49834
 
+{
49835
 
+       sieve_comparator_register(validator, &i_ascii_numeric_comparator);
49836
 
+       return TRUE;
49837
 
+}
49838
 
+
49839
 
+/*
49840
 
+ * Operand
49841
 
+ */
49842
 
+
49843
 
+static const struct sieve_extension_objects ext_comparators =
49844
 
+       SIEVE_EXT_DEFINE_COMPARATOR(i_ascii_numeric_comparator);
49845
 
+       
49846
 
+static const struct sieve_operand my_comparator_operand = { 
49847
 
+       "comparator-i;ascii-numeric", 
49848
 
+       &comparator_i_ascii_numeric_extension,
49849
 
+       0, 
49850
 
+       &sieve_comparator_operand_class,
49851
 
+       &ext_comparators
49852
 
+};
49853
 
+
49854
 
+/*
49855
 
+ * Comparator
49856
 
+ */
49857
 
+
49858
 
+/* Forward declarations */
49859
 
49860
 
+static int cmp_i_ascii_numeric_compare
49861
 
+       (const struct sieve_comparator *cmp, 
49862
 
+               const char *val1, size_t val1_size, const char *val2, size_t val2_size);
49863
 
+
49864
 
+/* Comparator object */
49865
 
+
49866
 
+const struct sieve_comparator i_ascii_numeric_comparator = { 
49867
 
+       SIEVE_OBJECT("i;ascii-numeric", &my_comparator_operand, 0),
49868
 
+       SIEVE_COMPARATOR_FLAG_ORDERING | SIEVE_COMPARATOR_FLAG_EQUALITY,
49869
 
+       cmp_i_ascii_numeric_compare,
49870
 
+       NULL,
49871
 
+       NULL
49872
 
+};
49873
 
+
49874
 
+/* Comparator implementation */
49875
 
+
49876
 
+static int cmp_i_ascii_numeric_compare
49877
 
+       (const struct sieve_comparator *cmp ATTR_UNUSED, 
49878
 
+               const char *val, size_t val_size, const char *key, size_t key_size)
49879
 
+{      
49880
 
+       const char *vend = val + val_size;
49881
 
+       const char *kend = key + key_size;
49882
 
+       const char *vp = val;
49883
 
+       const char *kp = key;
49884
 
+       int digits, i;
49885
 
+
49886
 
+       /* RFC 4790: All input is valid; strings that do not start with a digit 
49887
 
+        * represent positive infinity.
49888
 
+        */
49889
 
+       if ( !i_isdigit(*vp) ) {
49890
 
+               if ( i_isdigit(*kp) ) {
49891
 
+                       /* Value is greater */
49892
 
+                       return -1;
49893
 
+               }
49894
 
+       } else {
49895
 
+               if ( !i_isdigit(*kp) ) {
49896
 
+            /* Value is less */
49897
 
+            return -1;
49898
 
+        }
49899
 
+       }
49900
 
+       
49901
 
+       /* Ignore leading zeros */
49902
 
+
49903
 
+       while ( *vp == '0' && vp < vend )  
49904
 
+               vp++;
49905
 
+
49906
 
+       while ( *kp == '0' && kp < kend )  
49907
 
+               kp++;
49908
 
+
49909
 
+       /* Check whether both numbers are equally long in terms of digits */
49910
 
+
49911
 
+       digits = 0;
49912
 
+       while ( vp < vend && kp < kend && i_isdigit(*vp) && i_isdigit(*kp) ) {
49913
 
+               vp++;
49914
 
+               kp++;
49915
 
+               digits++;       
49916
 
+       }
49917
 
+
49918
 
+       if ( vp == vend || !i_isdigit(*vp) ) {
49919
 
+               if ( kp != kend && i_isdigit(*kp) ) {
49920
 
+                       /* Value is less */
49921
 
+                       return -1;
49922
 
+               }
49923
 
+       } else {
49924
 
+               /* Value is greater */  
49925
 
+               return 1;
49926
 
+       }
49927
 
+
49928
 
+       /* Equally long: compare digits */
49929
 
+
49930
 
+       vp -= digits;
49931
 
+       kp -= digits;
49932
 
+       i = 0;
49933
 
+       while ( i < digits ) {
49934
 
+               if ( *vp > *kp )
49935
 
+                       return 1;
49936
 
+               else if ( *vp < *kp )
49937
 
+                       return -1;
49938
 
+
49939
 
+               kp++;
49940
 
+               vp++;
49941
 
+               i++;
49942
 
+       }
49943
 
+               
49944
 
+       return 0;
49945
 
+}
49946
 
+
49947
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/comparator-i-ascii-numeric/Makefile.am dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/comparator-i-ascii-numeric/Makefile.am
49948
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/comparator-i-ascii-numeric/Makefile.am 1970-01-01 01:00:00.000000000 +0100
49949
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/comparator-i-ascii-numeric/Makefile.am  2008-10-20 01:35:49.000000000 +0200
49950
 
@@ -0,0 +1,11 @@
49951
 
+noinst_LTLIBRARIES = libsieve_ext_comparator-i-ascii-numeric.la
49952
 
+
49953
 
+AM_CPPFLAGS = \
49954
 
+       -I../../ \
49955
 
+       -I$(dovecot_incdir) \
49956
 
+       -I$(dovecot_incdir)/src/lib \
49957
 
+       -I$(dovecot_incdir)/src/lib-mail \
49958
 
+       -I$(dovecot_incdir)/src/lib-storage 
49959
 
+
49960
 
+libsieve_ext_comparator_i_ascii_numeric_la_SOURCES = \
49961
 
+       ext-cmp-i-ascii-numeric.c
49962
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/comparator-i-ascii-numeric/Makefile.in dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/comparator-i-ascii-numeric/Makefile.in
49963
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/comparator-i-ascii-numeric/Makefile.in 1970-01-01 01:00:00.000000000 +0100
49964
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/comparator-i-ascii-numeric/Makefile.in  2009-08-21 00:55:43.000000000 +0200
49965
 
@@ -0,0 +1,455 @@
49966
 
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
49967
 
+# @configure_input@
49968
 
+
49969
 
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
49970
 
+# 2003, 2004, 2005, 2006, 2007, 2008  Free Software Foundation, Inc.
49971
 
+# This Makefile.in is free software; the Free Software Foundation
49972
 
+# gives unlimited permission to copy and/or distribute it,
49973
 
+# with or without modifications, as long as this notice is preserved.
49974
 
+
49975
 
+# This program is distributed in the hope that it will be useful,
49976
 
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
49977
 
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
49978
 
+# PARTICULAR PURPOSE.
49979
 
+
49980
 
+@SET_MAKE@
49981
 
+
49982
 
+VPATH = @srcdir@
49983
 
+pkgdatadir = $(datadir)/@PACKAGE@
49984
 
+pkglibdir = $(libdir)/@PACKAGE@
49985
 
+pkgincludedir = $(includedir)/@PACKAGE@
49986
 
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
49987
 
+install_sh_DATA = $(install_sh) -c -m 644
49988
 
+install_sh_PROGRAM = $(install_sh) -c
49989
 
+install_sh_SCRIPT = $(install_sh) -c
49990
 
+INSTALL_HEADER = $(INSTALL_DATA)
49991
 
+transform = $(program_transform_name)
49992
 
+NORMAL_INSTALL = :
49993
 
+PRE_INSTALL = :
49994
 
+POST_INSTALL = :
49995
 
+NORMAL_UNINSTALL = :
49996
 
+PRE_UNINSTALL = :
49997
 
+POST_UNINSTALL = :
49998
 
+build_triplet = @build@
49999
 
+host_triplet = @host@
50000
 
+subdir = src/lib-sieve/plugins/comparator-i-ascii-numeric
50001
 
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
50002
 
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
50003
 
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
50004
 
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
50005
 
+       $(ACLOCAL_M4)
50006
 
+mkinstalldirs = $(install_sh) -d
50007
 
+CONFIG_HEADER = $(top_builddir)/dummy-config.h \
50008
 
+       $(top_builddir)/dsieve-config.h
50009
 
+CONFIG_CLEAN_FILES =
50010
 
+LTLIBRARIES = $(noinst_LTLIBRARIES)
50011
 
+libsieve_ext_comparator_i_ascii_numeric_la_LIBADD =
50012
 
+am_libsieve_ext_comparator_i_ascii_numeric_la_OBJECTS =  \
50013
 
+       ext-cmp-i-ascii-numeric.lo
50014
 
+libsieve_ext_comparator_i_ascii_numeric_la_OBJECTS =  \
50015
 
+       $(am_libsieve_ext_comparator_i_ascii_numeric_la_OBJECTS)
50016
 
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
50017
 
+depcomp = $(SHELL) $(top_srcdir)/depcomp
50018
 
+am__depfiles_maybe = depfiles
50019
 
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
50020
 
+       $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
50021
 
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
50022
 
+       --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
50023
 
+       $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
50024
 
+CCLD = $(CC)
50025
 
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
50026
 
+       --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
50027
 
+       $(LDFLAGS) -o $@
50028
 
+SOURCES = $(libsieve_ext_comparator_i_ascii_numeric_la_SOURCES)
50029
 
+DIST_SOURCES = $(libsieve_ext_comparator_i_ascii_numeric_la_SOURCES)
50030
 
+ETAGS = etags
50031
 
+CTAGS = ctags
50032
 
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
50033
 
+ACLOCAL = @ACLOCAL@
50034
 
+AMTAR = @AMTAR@
50035
 
+AR = @AR@
50036
 
+AUTOCONF = @AUTOCONF@
50037
 
+AUTOHEADER = @AUTOHEADER@
50038
 
+AUTOMAKE = @AUTOMAKE@
50039
 
+AWK = @AWK@
50040
 
+CC = @CC@
50041
 
+CCDEPMODE = @CCDEPMODE@
50042
 
+CFLAGS = @CFLAGS@
50043
 
+CPP = @CPP@
50044
 
+CPPFLAGS = @CPPFLAGS@
50045
 
+CYGPATH_W = @CYGPATH_W@
50046
 
+DEFS = @DEFS@
50047
 
+DEPDIR = @DEPDIR@
50048
 
+DSYMUTIL = @DSYMUTIL@
50049
 
+DUMPBIN = @DUMPBIN@
50050
 
+ECHO_C = @ECHO_C@
50051
 
+ECHO_N = @ECHO_N@
50052
 
+ECHO_T = @ECHO_T@
50053
 
+EGREP = @EGREP@
50054
 
+EXEEXT = @EXEEXT@
50055
 
+FGREP = @FGREP@
50056
 
+GREP = @GREP@
50057
 
+INSTALL = @INSTALL@
50058
 
+INSTALL_DATA = @INSTALL_DATA@
50059
 
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
50060
 
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
50061
 
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
50062
 
+LD = @LD@
50063
 
+LDFLAGS = @LDFLAGS@
50064
 
+LIBICONV = @LIBICONV@
50065
 
+LIBOBJS = @LIBOBJS@
50066
 
+LIBS = @LIBS@
50067
 
+LIBTOOL = @LIBTOOL@
50068
 
+LIPO = @LIPO@
50069
 
+LN_S = @LN_S@
50070
 
+LTLIBOBJS = @LTLIBOBJS@
50071
 
+MAINT = @MAINT@
50072
 
+MAKEINFO = @MAKEINFO@
50073
 
+MKDIR_P = @MKDIR_P@
50074
 
+MODULE_LIBS = @MODULE_LIBS@
50075
 
+NM = @NM@
50076
 
+NMEDIT = @NMEDIT@
50077
 
+OBJDUMP = @OBJDUMP@
50078
 
+OBJEXT = @OBJEXT@
50079
 
+OTOOL = @OTOOL@
50080
 
+OTOOL64 = @OTOOL64@
50081
 
+PACKAGE = @PACKAGE@
50082
 
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
50083
 
+PACKAGE_NAME = @PACKAGE_NAME@
50084
 
+PACKAGE_STRING = @PACKAGE_STRING@
50085
 
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
50086
 
+PACKAGE_URL = @PACKAGE_URL@
50087
 
+PACKAGE_VERSION = @PACKAGE_VERSION@
50088
 
+PATH_SEPARATOR = @PATH_SEPARATOR@
50089
 
+RAND_LIBS = @RAND_LIBS@
50090
 
+RANLIB = @RANLIB@
50091
 
+SED = @SED@
50092
 
+SET_MAKE = @SET_MAKE@
50093
 
+SHELL = @SHELL@
50094
 
+STORAGE_LIBS = @STORAGE_LIBS@
50095
 
+STRIP = @STRIP@
50096
 
+VERSION = @VERSION@
50097
 
+abs_builddir = @abs_builddir@
50098
 
+abs_srcdir = @abs_srcdir@
50099
 
+abs_top_builddir = @abs_top_builddir@
50100
 
+abs_top_srcdir = @abs_top_srcdir@
50101
 
+ac_ct_CC = @ac_ct_CC@
50102
 
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
50103
 
+am__include = @am__include@
50104
 
+am__leading_dot = @am__leading_dot@
50105
 
+am__quote = @am__quote@
50106
 
+am__tar = @am__tar@
50107
 
+am__untar = @am__untar@
50108
 
+bindir = @bindir@
50109
 
+build = @build@
50110
 
+build_alias = @build_alias@
50111
 
+build_cpu = @build_cpu@
50112
 
+build_os = @build_os@
50113
 
+build_vendor = @build_vendor@
50114
 
+builddir = @builddir@
50115
 
+datadir = @datadir@
50116
 
+datarootdir = @datarootdir@
50117
 
+docdir = @docdir@
50118
 
+dovecot_incdir = @dovecot_incdir@
50119
 
+dovecotdir = @dovecotdir@
50120
 
+dvidir = @dvidir@
50121
 
+exec_prefix = @exec_prefix@
50122
 
+host = @host@
50123
 
+host_alias = @host_alias@
50124
 
+host_cpu = @host_cpu@
50125
 
+host_os = @host_os@
50126
 
+host_vendor = @host_vendor@
50127
 
+htmldir = @htmldir@
50128
 
+includedir = @includedir@
50129
 
+infodir = @infodir@
50130
 
+install_sh = @install_sh@
50131
 
+libdir = @libdir@
50132
 
+libexecdir = @libexecdir@
50133
 
+localedir = @localedir@
50134
 
+localstatedir = @localstatedir@
50135
 
+lt_ECHO = @lt_ECHO@
50136
 
+mandir = @mandir@
50137
 
+mkdir_p = @mkdir_p@
50138
 
+moduledir = @moduledir@
50139
 
+oldincludedir = @oldincludedir@
50140
 
+pdfdir = @pdfdir@
50141
 
+prefix = @prefix@
50142
 
+program_transform_name = @program_transform_name@
50143
 
+psdir = @psdir@
50144
 
+sbindir = @sbindir@
50145
 
+sharedstatedir = @sharedstatedir@
50146
 
+srcdir = @srcdir@
50147
 
+sysconfdir = @sysconfdir@
50148
 
+target_alias = @target_alias@
50149
 
+top_build_prefix = @top_build_prefix@
50150
 
+top_builddir = @top_builddir@
50151
 
+top_srcdir = @top_srcdir@
50152
 
+noinst_LTLIBRARIES = libsieve_ext_comparator-i-ascii-numeric.la
50153
 
+AM_CPPFLAGS = \
50154
 
+       -I../../ \
50155
 
+       -I$(dovecot_incdir) \
50156
 
+       -I$(dovecot_incdir)/src/lib \
50157
 
+       -I$(dovecot_incdir)/src/lib-mail \
50158
 
+       -I$(dovecot_incdir)/src/lib-storage 
50159
 
+
50160
 
+libsieve_ext_comparator_i_ascii_numeric_la_SOURCES = \
50161
 
+       ext-cmp-i-ascii-numeric.c
50162
 
+
50163
 
+all: all-am
50164
 
+
50165
 
+.SUFFIXES:
50166
 
+.SUFFIXES: .c .lo .o .obj
50167
 
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
50168
 
+       @for dep in $?; do \
50169
 
+         case '$(am__configure_deps)' in \
50170
 
+           *$$dep*) \
50171
 
+             ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
50172
 
+               && { if test -f $@; then exit 0; else break; fi; }; \
50173
 
+             exit 1;; \
50174
 
+         esac; \
50175
 
+       done; \
50176
 
+       echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign  src/lib-sieve/plugins/comparator-i-ascii-numeric/Makefile'; \
50177
 
+       cd $(top_srcdir) && \
50178
 
+         $(AUTOMAKE) --foreign  src/lib-sieve/plugins/comparator-i-ascii-numeric/Makefile
50179
 
+.PRECIOUS: Makefile
50180
 
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
50181
 
+       @case '$?' in \
50182
 
+         *config.status*) \
50183
 
+           cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
50184
 
+         *) \
50185
 
+           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
50186
 
+           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
50187
 
+       esac;
50188
 
+
50189
 
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
50190
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
50191
 
+
50192
 
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
50193
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
50194
 
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
50195
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
50196
 
+
50197
 
+clean-noinstLTLIBRARIES:
50198
 
+       -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
50199
 
+       @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
50200
 
+         dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
50201
 
+         test "$$dir" != "$$p" || dir=.; \
50202
 
+         echo "rm -f \"$${dir}/so_locations\""; \
50203
 
+         rm -f "$${dir}/so_locations"; \
50204
 
+       done
50205
 
+libsieve_ext_comparator-i-ascii-numeric.la: $(libsieve_ext_comparator_i_ascii_numeric_la_OBJECTS) $(libsieve_ext_comparator_i_ascii_numeric_la_DEPENDENCIES) 
50206
 
+       $(LINK)  $(libsieve_ext_comparator_i_ascii_numeric_la_OBJECTS) $(libsieve_ext_comparator_i_ascii_numeric_la_LIBADD) $(LIBS)
50207
 
+
50208
 
+mostlyclean-compile:
50209
 
+       -rm -f *.$(OBJEXT)
50210
 
+
50211
 
+distclean-compile:
50212
 
+       -rm -f *.tab.c
50213
 
+
50214
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-cmp-i-ascii-numeric.Plo@am__quote@
50215
 
+
50216
 
+.c.o:
50217
 
+@am__fastdepCC_TRUE@   $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
50218
 
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
50219
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
50220
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
50221
 
+@am__fastdepCC_FALSE@  $(COMPILE) -c $<
50222
 
+
50223
 
+.c.obj:
50224
 
+@am__fastdepCC_TRUE@   $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
50225
 
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
50226
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
50227
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
50228
 
+@am__fastdepCC_FALSE@  $(COMPILE) -c `$(CYGPATH_W) '$<'`
50229
 
+
50230
 
+.c.lo:
50231
 
+@am__fastdepCC_TRUE@   $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
50232
 
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
50233
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
50234
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
50235
 
+@am__fastdepCC_FALSE@  $(LTCOMPILE) -c -o $@ $<
50236
 
+
50237
 
+mostlyclean-libtool:
50238
 
+       -rm -f *.lo
50239
 
+
50240
 
+clean-libtool:
50241
 
+       -rm -rf .libs _libs
50242
 
+
50243
 
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
50244
 
+       list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
50245
 
+       unique=`for i in $$list; do \
50246
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
50247
 
+         done | \
50248
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
50249
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
50250
 
+       mkid -fID $$unique
50251
 
+tags: TAGS
50252
 
+
50253
 
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
50254
 
+               $(TAGS_FILES) $(LISP)
50255
 
+       tags=; \
50256
 
+       here=`pwd`; \
50257
 
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
50258
 
+       unique=`for i in $$list; do \
50259
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
50260
 
+         done | \
50261
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
50262
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
50263
 
+       if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
50264
 
+         test -n "$$unique" || unique=$$empty_fix; \
50265
 
+         $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
50266
 
+           $$tags $$unique; \
50267
 
+       fi
50268
 
+ctags: CTAGS
50269
 
+CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
50270
 
+               $(TAGS_FILES) $(LISP)
50271
 
+       tags=; \
50272
 
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
50273
 
+       unique=`for i in $$list; do \
50274
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
50275
 
+         done | \
50276
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
50277
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
50278
 
+       test -z "$(CTAGS_ARGS)$$tags$$unique" \
50279
 
+         || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
50280
 
+            $$tags $$unique
50281
 
+
50282
 
+GTAGS:
50283
 
+       here=`$(am__cd) $(top_builddir) && pwd` \
50284
 
+         && cd $(top_srcdir) \
50285
 
+         && gtags -i $(GTAGS_ARGS) $$here
50286
 
+
50287
 
+distclean-tags:
50288
 
+       -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
50289
 
+
50290
 
+distdir: $(DISTFILES)
50291
 
+       @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
50292
 
+       topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
50293
 
+       list='$(DISTFILES)'; \
50294
 
+         dist_files=`for file in $$list; do echo $$file; done | \
50295
 
+         sed -e "s|^$$srcdirstrip/||;t" \
50296
 
+             -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
50297
 
+       case $$dist_files in \
50298
 
+         */*) $(MKDIR_P) `echo "$$dist_files" | \
50299
 
+                          sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
50300
 
+                          sort -u` ;; \
50301
 
+       esac; \
50302
 
+       for file in $$dist_files; do \
50303
 
+         if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
50304
 
+         if test -d $$d/$$file; then \
50305
 
+           dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
50306
 
+           if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
50307
 
+             cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
50308
 
+           fi; \
50309
 
+           cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
50310
 
+         else \
50311
 
+           test -f $(distdir)/$$file \
50312
 
+           || cp -p $$d/$$file $(distdir)/$$file \
50313
 
+           || exit 1; \
50314
 
+         fi; \
50315
 
+       done
50316
 
+check-am: all-am
50317
 
+check: check-am
50318
 
+all-am: Makefile $(LTLIBRARIES)
50319
 
+installdirs:
50320
 
+install: install-am
50321
 
+install-exec: install-exec-am
50322
 
+install-data: install-data-am
50323
 
+uninstall: uninstall-am
50324
 
+
50325
 
+install-am: all-am
50326
 
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
50327
 
+
50328
 
+installcheck: installcheck-am
50329
 
+install-strip:
50330
 
+       $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
50331
 
+         install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
50332
 
+         `test -z '$(STRIP)' || \
50333
 
+           echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
50334
 
+mostlyclean-generic:
50335
 
+
50336
 
+clean-generic:
50337
 
+
50338
 
+distclean-generic:
50339
 
+       -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
50340
 
+
50341
 
+maintainer-clean-generic:
50342
 
+       @echo "This command is intended for maintainers to use"
50343
 
+       @echo "it deletes files that may require special tools to rebuild."
50344
 
+clean: clean-am
50345
 
+
50346
 
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
50347
 
+       mostlyclean-am
50348
 
+
50349
 
+distclean: distclean-am
50350
 
+       -rm -rf ./$(DEPDIR)
50351
 
+       -rm -f Makefile
50352
 
+distclean-am: clean-am distclean-compile distclean-generic \
50353
 
+       distclean-tags
50354
 
+
50355
 
+dvi: dvi-am
50356
 
+
50357
 
+dvi-am:
50358
 
+
50359
 
+html: html-am
50360
 
+
50361
 
+info: info-am
50362
 
+
50363
 
+info-am:
50364
 
+
50365
 
+install-data-am:
50366
 
+
50367
 
+install-dvi: install-dvi-am
50368
 
+
50369
 
+install-exec-am:
50370
 
+
50371
 
+install-html: install-html-am
50372
 
+
50373
 
+install-info: install-info-am
50374
 
+
50375
 
+install-man:
50376
 
+
50377
 
+install-pdf: install-pdf-am
50378
 
+
50379
 
+install-ps: install-ps-am
50380
 
+
50381
 
+installcheck-am:
50382
 
+
50383
 
+maintainer-clean: maintainer-clean-am
50384
 
+       -rm -rf ./$(DEPDIR)
50385
 
+       -rm -f Makefile
50386
 
+maintainer-clean-am: distclean-am maintainer-clean-generic
50387
 
+
50388
 
+mostlyclean: mostlyclean-am
50389
 
+
50390
 
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
50391
 
+       mostlyclean-libtool
50392
 
+
50393
 
+pdf: pdf-am
50394
 
+
50395
 
+pdf-am:
50396
 
+
50397
 
+ps: ps-am
50398
 
+
50399
 
+ps-am:
50400
 
+
50401
 
+uninstall-am:
50402
 
+
50403
 
+.MAKE: install-am install-strip
50404
 
+
50405
 
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
50406
 
+       clean-libtool clean-noinstLTLIBRARIES ctags distclean \
50407
 
+       distclean-compile distclean-generic distclean-libtool \
50408
 
+       distclean-tags distdir dvi dvi-am html html-am info info-am \
50409
 
+       install install-am install-data install-data-am install-dvi \
50410
 
+       install-dvi-am install-exec install-exec-am install-html \
50411
 
+       install-html-am install-info install-info-am install-man \
50412
 
+       install-pdf install-pdf-am install-ps install-ps-am \
50413
 
+       install-strip installcheck installcheck-am installdirs \
50414
 
+       maintainer-clean maintainer-clean-generic mostlyclean \
50415
 
+       mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
50416
 
+       pdf pdf-am ps ps-am tags uninstall uninstall-am
50417
 
+
50418
 
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
50419
 
+# Otherwise a system limit (for SysV at least) may be exceeded.
50420
 
+.NOEXPORT:
50421
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/copy/ext-copy.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/copy/ext-copy.c
50422
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/copy/ext-copy.c        1970-01-01 01:00:00.000000000 +0100
50423
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/copy/ext-copy.c 2009-08-05 12:42:30.000000000 +0200
50424
 
@@ -0,0 +1,177 @@
50425
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
50426
 
+ */
50427
 
+
50428
 
+/* Extension copy
50429
 
+ * ------------------
50430
 
+ *
50431
 
+ * Authors: Stephan Bosch
50432
 
+ * Specification: RFC 3894
50433
 
+ * Implementation: full
50434
 
+ * Status: experimental, largely untested
50435
 
+ * 
50436
 
+ */
50437
 
+
50438
 
+#include <stdio.h>
50439
 
+
50440
 
+#include "sieve-common.h"
50441
 
+
50442
 
+#include "sieve-code.h"
50443
 
+#include "sieve-extensions.h"
50444
 
+#include "sieve-actions.h"
50445
 
+#include "sieve-commands.h"
50446
 
+#include "sieve-validator.h"
50447
 
+#include "sieve-generator.h"
50448
 
+#include "sieve-interpreter.h"
50449
 
+#include "sieve-result.h"
50450
 
+
50451
 
+/* 
50452
 
+ * Forward declarations 
50453
 
+ */
50454
 
+
50455
 
+static const struct sieve_argument copy_tag;
50456
 
+static const struct sieve_operand copy_side_effect_operand;
50457
 
+
50458
 
+/* 
50459
 
+ * Extension
50460
 
+ */
50461
 
+
50462
 
+static bool ext_copy_validator_load(struct sieve_validator *validator);
50463
 
+
50464
 
+static int ext_my_id = -1;
50465
 
+
50466
 
+const struct sieve_extension copy_extension = { 
50467
 
+       "copy", 
50468
 
+       &ext_my_id,
50469
 
+       NULL, NULL,
50470
 
+       ext_copy_validator_load, 
50471
 
+       NULL, NULL, NULL, NULL, NULL,
50472
 
+       SIEVE_EXT_DEFINE_NO_OPERATIONS,
50473
 
+       SIEVE_EXT_DEFINE_OPERAND(copy_side_effect_operand)
50474
 
+};
50475
 
+
50476
 
+static bool ext_copy_validator_load(struct sieve_validator *validator)
50477
 
+{
50478
 
+       /* Register copy tag with redirect and fileinto commands and we don't care
50479
 
+        * whether these commands are registered or even whether they will be
50480
 
+        * registered at all. The validator handles either situation gracefully 
50481
 
+        */
50482
 
+       sieve_validator_register_external_tag
50483
 
+               (validator, &copy_tag, "redirect", SIEVE_OPT_SIDE_EFFECT);
50484
 
+       sieve_validator_register_external_tag
50485
 
+               (validator, &copy_tag, "fileinto", SIEVE_OPT_SIDE_EFFECT);
50486
 
+
50487
 
+       return TRUE;
50488
 
+}
50489
 
+
50490
 
+/*
50491
 
+ * Side effect 
50492
 
+ */
50493
 
+
50494
 
+static void seff_copy_print
50495
 
+       (const struct sieve_side_effect *seffect, const struct sieve_action *action, 
50496
 
+               const struct sieve_result_print_env *rpenv, void *se_context, bool *keep);
50497
 
+static void seff_copy_post_commit
50498
 
+       (const struct sieve_side_effect *seffect, const struct sieve_action *action, 
50499
 
+               const struct sieve_action_exec_env *aenv, void *se_context,
50500
 
+               void *tr_context, bool *keep);
50501
 
+
50502
 
+const struct sieve_side_effect copy_side_effect = {
50503
 
+       SIEVE_OBJECT("copy", &copy_side_effect_operand, 0),
50504
 
+       &act_store,
50505
 
+       NULL, NULL, NULL,
50506
 
+       seff_copy_print,
50507
 
+       NULL, NULL,
50508
 
+       seff_copy_post_commit, 
50509
 
+       NULL
50510
 
+};
50511
 
+
50512
 
+/* 
50513
 
+ * Tagged argument 
50514
 
+ */
50515
 
+
50516
 
+static bool tag_copy_validate
50517
 
+       (struct sieve_validator *validator, struct sieve_ast_argument **arg, 
50518
 
+               struct sieve_command_context *cmd);
50519
 
+static bool tag_copy_generate
50520
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg,
50521
 
+    struct sieve_command_context *context);
50522
 
+
50523
 
+static const struct sieve_argument copy_tag = { 
50524
 
+       "copy", 
50525
 
+       NULL, NULL,
50526
 
+       tag_copy_validate, 
50527
 
+       NULL,
50528
 
+       tag_copy_generate
50529
 
+};
50530
 
+
50531
 
+/*
50532
 
+ * Operand
50533
 
+ */
50534
 
+
50535
 
+static const struct sieve_extension_objects ext_side_effects =
50536
 
+       SIEVE_EXT_DEFINE_SIDE_EFFECT(copy_side_effect);
50537
 
+
50538
 
+static const struct sieve_operand copy_side_effect_operand = {
50539
 
+       "copy operand",
50540
 
+       &copy_extension,
50541
 
+       0,
50542
 
+       &sieve_side_effect_operand_class,
50543
 
+       &ext_side_effects
50544
 
+};
50545
 
+
50546
 
+/* 
50547
 
+ * Tag validation 
50548
 
+ */
50549
 
+
50550
 
+static bool tag_copy_validate
50551
 
+       (struct sieve_validator *validator ATTR_UNUSED, 
50552
 
+       struct sieve_ast_argument **arg ATTR_UNUSED, 
50553
 
+       struct sieve_command_context *cmd ATTR_UNUSED)
50554
 
+{
50555
 
+       *arg = sieve_ast_argument_next(*arg);
50556
 
+
50557
 
+       return TRUE;
50558
 
+}
50559
 
+
50560
 
+/*
50561
 
+ * Code generation 
50562
 
+ */
50563
 
+
50564
 
+static bool tag_copy_generate
50565
 
+(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg,
50566
 
+    struct sieve_command_context *context ATTR_UNUSED)
50567
 
+{
50568
 
+       if ( sieve_ast_argument_type(arg) != SAAT_TAG ) {
50569
 
+               return FALSE;
50570
 
+       }
50571
 
+
50572
 
+       sieve_opr_side_effect_emit(cgenv->sbin, &copy_side_effect);
50573
 
+
50574
 
+       return TRUE;
50575
 
+}
50576
 
+
50577
 
+/* 
50578
 
+ * Side effect implementation
50579
 
+ */
50580
 
+
50581
 
+static void seff_copy_print
50582
 
+(const struct sieve_side_effect *seffect ATTR_UNUSED, 
50583
 
+       const struct sieve_action *action ATTR_UNUSED, 
50584
 
+       const struct sieve_result_print_env *rpenv,
50585
 
+       void *se_context ATTR_UNUSED, bool *keep)
50586
 
+{
50587
 
+       sieve_result_seffect_printf(rpenv, "preserve implicit keep");
50588
 
+
50589
 
+       *keep = TRUE;
50590
 
+}
50591
 
+
50592
 
+static void seff_copy_post_commit
50593
 
+(const struct sieve_side_effect *seffect ATTR_UNUSED, 
50594
 
+       const struct sieve_action *action ATTR_UNUSED, 
50595
 
+       const struct sieve_action_exec_env *aenv ATTR_UNUSED, 
50596
 
+               void *se_context ATTR_UNUSED,   void *tr_context ATTR_UNUSED, bool *keep)
50597
 
+{      
50598
 
+       *keep = TRUE;
50599
 
+}
50600
 
+
50601
 
+
50602
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/copy/Makefile.am dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/copy/Makefile.am
50603
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/copy/Makefile.am       1970-01-01 01:00:00.000000000 +0100
50604
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/copy/Makefile.am        2008-10-20 01:35:49.000000000 +0200
50605
 
@@ -0,0 +1,11 @@
50606
 
+noinst_LTLIBRARIES = libsieve_ext_copy.la
50607
 
+
50608
 
+AM_CPPFLAGS = \
50609
 
+       -I../../ \
50610
 
+       -I$(dovecot_incdir) \
50611
 
+       -I$(dovecot_incdir)/src/lib \
50612
 
+       -I$(dovecot_incdir)/src/lib-mail \
50613
 
+       -I$(dovecot_incdir)/src/lib-storage 
50614
 
+
50615
 
+libsieve_ext_copy_la_SOURCES = \
50616
 
+       ext-copy.c
50617
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/copy/Makefile.in dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/copy/Makefile.in
50618
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/copy/Makefile.in       1970-01-01 01:00:00.000000000 +0100
50619
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/copy/Makefile.in        2009-08-21 00:55:43.000000000 +0200
50620
 
@@ -0,0 +1,453 @@
50621
 
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
50622
 
+# @configure_input@
50623
 
+
50624
 
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
50625
 
+# 2003, 2004, 2005, 2006, 2007, 2008  Free Software Foundation, Inc.
50626
 
+# This Makefile.in is free software; the Free Software Foundation
50627
 
+# gives unlimited permission to copy and/or distribute it,
50628
 
+# with or without modifications, as long as this notice is preserved.
50629
 
+
50630
 
+# This program is distributed in the hope that it will be useful,
50631
 
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
50632
 
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
50633
 
+# PARTICULAR PURPOSE.
50634
 
+
50635
 
+@SET_MAKE@
50636
 
+
50637
 
+VPATH = @srcdir@
50638
 
+pkgdatadir = $(datadir)/@PACKAGE@
50639
 
+pkglibdir = $(libdir)/@PACKAGE@
50640
 
+pkgincludedir = $(includedir)/@PACKAGE@
50641
 
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
50642
 
+install_sh_DATA = $(install_sh) -c -m 644
50643
 
+install_sh_PROGRAM = $(install_sh) -c
50644
 
+install_sh_SCRIPT = $(install_sh) -c
50645
 
+INSTALL_HEADER = $(INSTALL_DATA)
50646
 
+transform = $(program_transform_name)
50647
 
+NORMAL_INSTALL = :
50648
 
+PRE_INSTALL = :
50649
 
+POST_INSTALL = :
50650
 
+NORMAL_UNINSTALL = :
50651
 
+PRE_UNINSTALL = :
50652
 
+POST_UNINSTALL = :
50653
 
+build_triplet = @build@
50654
 
+host_triplet = @host@
50655
 
+subdir = src/lib-sieve/plugins/copy
50656
 
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
50657
 
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
50658
 
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
50659
 
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
50660
 
+       $(ACLOCAL_M4)
50661
 
+mkinstalldirs = $(install_sh) -d
50662
 
+CONFIG_HEADER = $(top_builddir)/dummy-config.h \
50663
 
+       $(top_builddir)/dsieve-config.h
50664
 
+CONFIG_CLEAN_FILES =
50665
 
+LTLIBRARIES = $(noinst_LTLIBRARIES)
50666
 
+libsieve_ext_copy_la_LIBADD =
50667
 
+am_libsieve_ext_copy_la_OBJECTS = ext-copy.lo
50668
 
+libsieve_ext_copy_la_OBJECTS = $(am_libsieve_ext_copy_la_OBJECTS)
50669
 
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
50670
 
+depcomp = $(SHELL) $(top_srcdir)/depcomp
50671
 
+am__depfiles_maybe = depfiles
50672
 
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
50673
 
+       $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
50674
 
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
50675
 
+       --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
50676
 
+       $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
50677
 
+CCLD = $(CC)
50678
 
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
50679
 
+       --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
50680
 
+       $(LDFLAGS) -o $@
50681
 
+SOURCES = $(libsieve_ext_copy_la_SOURCES)
50682
 
+DIST_SOURCES = $(libsieve_ext_copy_la_SOURCES)
50683
 
+ETAGS = etags
50684
 
+CTAGS = ctags
50685
 
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
50686
 
+ACLOCAL = @ACLOCAL@
50687
 
+AMTAR = @AMTAR@
50688
 
+AR = @AR@
50689
 
+AUTOCONF = @AUTOCONF@
50690
 
+AUTOHEADER = @AUTOHEADER@
50691
 
+AUTOMAKE = @AUTOMAKE@
50692
 
+AWK = @AWK@
50693
 
+CC = @CC@
50694
 
+CCDEPMODE = @CCDEPMODE@
50695
 
+CFLAGS = @CFLAGS@
50696
 
+CPP = @CPP@
50697
 
+CPPFLAGS = @CPPFLAGS@
50698
 
+CYGPATH_W = @CYGPATH_W@
50699
 
+DEFS = @DEFS@
50700
 
+DEPDIR = @DEPDIR@
50701
 
+DSYMUTIL = @DSYMUTIL@
50702
 
+DUMPBIN = @DUMPBIN@
50703
 
+ECHO_C = @ECHO_C@
50704
 
+ECHO_N = @ECHO_N@
50705
 
+ECHO_T = @ECHO_T@
50706
 
+EGREP = @EGREP@
50707
 
+EXEEXT = @EXEEXT@
50708
 
+FGREP = @FGREP@
50709
 
+GREP = @GREP@
50710
 
+INSTALL = @INSTALL@
50711
 
+INSTALL_DATA = @INSTALL_DATA@
50712
 
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
50713
 
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
50714
 
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
50715
 
+LD = @LD@
50716
 
+LDFLAGS = @LDFLAGS@
50717
 
+LIBICONV = @LIBICONV@
50718
 
+LIBOBJS = @LIBOBJS@
50719
 
+LIBS = @LIBS@
50720
 
+LIBTOOL = @LIBTOOL@
50721
 
+LIPO = @LIPO@
50722
 
+LN_S = @LN_S@
50723
 
+LTLIBOBJS = @LTLIBOBJS@
50724
 
+MAINT = @MAINT@
50725
 
+MAKEINFO = @MAKEINFO@
50726
 
+MKDIR_P = @MKDIR_P@
50727
 
+MODULE_LIBS = @MODULE_LIBS@
50728
 
+NM = @NM@
50729
 
+NMEDIT = @NMEDIT@
50730
 
+OBJDUMP = @OBJDUMP@
50731
 
+OBJEXT = @OBJEXT@
50732
 
+OTOOL = @OTOOL@
50733
 
+OTOOL64 = @OTOOL64@
50734
 
+PACKAGE = @PACKAGE@
50735
 
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
50736
 
+PACKAGE_NAME = @PACKAGE_NAME@
50737
 
+PACKAGE_STRING = @PACKAGE_STRING@
50738
 
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
50739
 
+PACKAGE_URL = @PACKAGE_URL@
50740
 
+PACKAGE_VERSION = @PACKAGE_VERSION@
50741
 
+PATH_SEPARATOR = @PATH_SEPARATOR@
50742
 
+RAND_LIBS = @RAND_LIBS@
50743
 
+RANLIB = @RANLIB@
50744
 
+SED = @SED@
50745
 
+SET_MAKE = @SET_MAKE@
50746
 
+SHELL = @SHELL@
50747
 
+STORAGE_LIBS = @STORAGE_LIBS@
50748
 
+STRIP = @STRIP@
50749
 
+VERSION = @VERSION@
50750
 
+abs_builddir = @abs_builddir@
50751
 
+abs_srcdir = @abs_srcdir@
50752
 
+abs_top_builddir = @abs_top_builddir@
50753
 
+abs_top_srcdir = @abs_top_srcdir@
50754
 
+ac_ct_CC = @ac_ct_CC@
50755
 
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
50756
 
+am__include = @am__include@
50757
 
+am__leading_dot = @am__leading_dot@
50758
 
+am__quote = @am__quote@
50759
 
+am__tar = @am__tar@
50760
 
+am__untar = @am__untar@
50761
 
+bindir = @bindir@
50762
 
+build = @build@
50763
 
+build_alias = @build_alias@
50764
 
+build_cpu = @build_cpu@
50765
 
+build_os = @build_os@
50766
 
+build_vendor = @build_vendor@
50767
 
+builddir = @builddir@
50768
 
+datadir = @datadir@
50769
 
+datarootdir = @datarootdir@
50770
 
+docdir = @docdir@
50771
 
+dovecot_incdir = @dovecot_incdir@
50772
 
+dovecotdir = @dovecotdir@
50773
 
+dvidir = @dvidir@
50774
 
+exec_prefix = @exec_prefix@
50775
 
+host = @host@
50776
 
+host_alias = @host_alias@
50777
 
+host_cpu = @host_cpu@
50778
 
+host_os = @host_os@
50779
 
+host_vendor = @host_vendor@
50780
 
+htmldir = @htmldir@
50781
 
+includedir = @includedir@
50782
 
+infodir = @infodir@
50783
 
+install_sh = @install_sh@
50784
 
+libdir = @libdir@
50785
 
+libexecdir = @libexecdir@
50786
 
+localedir = @localedir@
50787
 
+localstatedir = @localstatedir@
50788
 
+lt_ECHO = @lt_ECHO@
50789
 
+mandir = @mandir@
50790
 
+mkdir_p = @mkdir_p@
50791
 
+moduledir = @moduledir@
50792
 
+oldincludedir = @oldincludedir@
50793
 
+pdfdir = @pdfdir@
50794
 
+prefix = @prefix@
50795
 
+program_transform_name = @program_transform_name@
50796
 
+psdir = @psdir@
50797
 
+sbindir = @sbindir@
50798
 
+sharedstatedir = @sharedstatedir@
50799
 
+srcdir = @srcdir@
50800
 
+sysconfdir = @sysconfdir@
50801
 
+target_alias = @target_alias@
50802
 
+top_build_prefix = @top_build_prefix@
50803
 
+top_builddir = @top_builddir@
50804
 
+top_srcdir = @top_srcdir@
50805
 
+noinst_LTLIBRARIES = libsieve_ext_copy.la
50806
 
+AM_CPPFLAGS = \
50807
 
+       -I../../ \
50808
 
+       -I$(dovecot_incdir) \
50809
 
+       -I$(dovecot_incdir)/src/lib \
50810
 
+       -I$(dovecot_incdir)/src/lib-mail \
50811
 
+       -I$(dovecot_incdir)/src/lib-storage 
50812
 
+
50813
 
+libsieve_ext_copy_la_SOURCES = \
50814
 
+       ext-copy.c
50815
 
+
50816
 
+all: all-am
50817
 
+
50818
 
+.SUFFIXES:
50819
 
+.SUFFIXES: .c .lo .o .obj
50820
 
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
50821
 
+       @for dep in $?; do \
50822
 
+         case '$(am__configure_deps)' in \
50823
 
+           *$$dep*) \
50824
 
+             ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
50825
 
+               && { if test -f $@; then exit 0; else break; fi; }; \
50826
 
+             exit 1;; \
50827
 
+         esac; \
50828
 
+       done; \
50829
 
+       echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign  src/lib-sieve/plugins/copy/Makefile'; \
50830
 
+       cd $(top_srcdir) && \
50831
 
+         $(AUTOMAKE) --foreign  src/lib-sieve/plugins/copy/Makefile
50832
 
+.PRECIOUS: Makefile
50833
 
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
50834
 
+       @case '$?' in \
50835
 
+         *config.status*) \
50836
 
+           cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
50837
 
+         *) \
50838
 
+           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
50839
 
+           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
50840
 
+       esac;
50841
 
+
50842
 
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
50843
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
50844
 
+
50845
 
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
50846
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
50847
 
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
50848
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
50849
 
+
50850
 
+clean-noinstLTLIBRARIES:
50851
 
+       -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
50852
 
+       @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
50853
 
+         dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
50854
 
+         test "$$dir" != "$$p" || dir=.; \
50855
 
+         echo "rm -f \"$${dir}/so_locations\""; \
50856
 
+         rm -f "$${dir}/so_locations"; \
50857
 
+       done
50858
 
+libsieve_ext_copy.la: $(libsieve_ext_copy_la_OBJECTS) $(libsieve_ext_copy_la_DEPENDENCIES) 
50859
 
+       $(LINK)  $(libsieve_ext_copy_la_OBJECTS) $(libsieve_ext_copy_la_LIBADD) $(LIBS)
50860
 
+
50861
 
+mostlyclean-compile:
50862
 
+       -rm -f *.$(OBJEXT)
50863
 
+
50864
 
+distclean-compile:
50865
 
+       -rm -f *.tab.c
50866
 
+
50867
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-copy.Plo@am__quote@
50868
 
+
50869
 
+.c.o:
50870
 
+@am__fastdepCC_TRUE@   $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
50871
 
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
50872
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
50873
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
50874
 
+@am__fastdepCC_FALSE@  $(COMPILE) -c $<
50875
 
+
50876
 
+.c.obj:
50877
 
+@am__fastdepCC_TRUE@   $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
50878
 
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
50879
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
50880
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
50881
 
+@am__fastdepCC_FALSE@  $(COMPILE) -c `$(CYGPATH_W) '$<'`
50882
 
+
50883
 
+.c.lo:
50884
 
+@am__fastdepCC_TRUE@   $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
50885
 
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
50886
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
50887
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
50888
 
+@am__fastdepCC_FALSE@  $(LTCOMPILE) -c -o $@ $<
50889
 
+
50890
 
+mostlyclean-libtool:
50891
 
+       -rm -f *.lo
50892
 
+
50893
 
+clean-libtool:
50894
 
+       -rm -rf .libs _libs
50895
 
+
50896
 
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
50897
 
+       list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
50898
 
+       unique=`for i in $$list; do \
50899
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
50900
 
+         done | \
50901
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
50902
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
50903
 
+       mkid -fID $$unique
50904
 
+tags: TAGS
50905
 
+
50906
 
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
50907
 
+               $(TAGS_FILES) $(LISP)
50908
 
+       tags=; \
50909
 
+       here=`pwd`; \
50910
 
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
50911
 
+       unique=`for i in $$list; do \
50912
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
50913
 
+         done | \
50914
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
50915
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
50916
 
+       if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
50917
 
+         test -n "$$unique" || unique=$$empty_fix; \
50918
 
+         $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
50919
 
+           $$tags $$unique; \
50920
 
+       fi
50921
 
+ctags: CTAGS
50922
 
+CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
50923
 
+               $(TAGS_FILES) $(LISP)
50924
 
+       tags=; \
50925
 
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
50926
 
+       unique=`for i in $$list; do \
50927
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
50928
 
+         done | \
50929
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
50930
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
50931
 
+       test -z "$(CTAGS_ARGS)$$tags$$unique" \
50932
 
+         || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
50933
 
+            $$tags $$unique
50934
 
+
50935
 
+GTAGS:
50936
 
+       here=`$(am__cd) $(top_builddir) && pwd` \
50937
 
+         && cd $(top_srcdir) \
50938
 
+         && gtags -i $(GTAGS_ARGS) $$here
50939
 
+
50940
 
+distclean-tags:
50941
 
+       -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
50942
 
+
50943
 
+distdir: $(DISTFILES)
50944
 
+       @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
50945
 
+       topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
50946
 
+       list='$(DISTFILES)'; \
50947
 
+         dist_files=`for file in $$list; do echo $$file; done | \
50948
 
+         sed -e "s|^$$srcdirstrip/||;t" \
50949
 
+             -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
50950
 
+       case $$dist_files in \
50951
 
+         */*) $(MKDIR_P) `echo "$$dist_files" | \
50952
 
+                          sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
50953
 
+                          sort -u` ;; \
50954
 
+       esac; \
50955
 
+       for file in $$dist_files; do \
50956
 
+         if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
50957
 
+         if test -d $$d/$$file; then \
50958
 
+           dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
50959
 
+           if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
50960
 
+             cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
50961
 
+           fi; \
50962
 
+           cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
50963
 
+         else \
50964
 
+           test -f $(distdir)/$$file \
50965
 
+           || cp -p $$d/$$file $(distdir)/$$file \
50966
 
+           || exit 1; \
50967
 
+         fi; \
50968
 
+       done
50969
 
+check-am: all-am
50970
 
+check: check-am
50971
 
+all-am: Makefile $(LTLIBRARIES)
50972
 
+installdirs:
50973
 
+install: install-am
50974
 
+install-exec: install-exec-am
50975
 
+install-data: install-data-am
50976
 
+uninstall: uninstall-am
50977
 
+
50978
 
+install-am: all-am
50979
 
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
50980
 
+
50981
 
+installcheck: installcheck-am
50982
 
+install-strip:
50983
 
+       $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
50984
 
+         install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
50985
 
+         `test -z '$(STRIP)' || \
50986
 
+           echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
50987
 
+mostlyclean-generic:
50988
 
+
50989
 
+clean-generic:
50990
 
+
50991
 
+distclean-generic:
50992
 
+       -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
50993
 
+
50994
 
+maintainer-clean-generic:
50995
 
+       @echo "This command is intended for maintainers to use"
50996
 
+       @echo "it deletes files that may require special tools to rebuild."
50997
 
+clean: clean-am
50998
 
+
50999
 
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
51000
 
+       mostlyclean-am
51001
 
+
51002
 
+distclean: distclean-am
51003
 
+       -rm -rf ./$(DEPDIR)
51004
 
+       -rm -f Makefile
51005
 
+distclean-am: clean-am distclean-compile distclean-generic \
51006
 
+       distclean-tags
51007
 
+
51008
 
+dvi: dvi-am
51009
 
+
51010
 
+dvi-am:
51011
 
+
51012
 
+html: html-am
51013
 
+
51014
 
+info: info-am
51015
 
+
51016
 
+info-am:
51017
 
+
51018
 
+install-data-am:
51019
 
+
51020
 
+install-dvi: install-dvi-am
51021
 
+
51022
 
+install-exec-am:
51023
 
+
51024
 
+install-html: install-html-am
51025
 
+
51026
 
+install-info: install-info-am
51027
 
+
51028
 
+install-man:
51029
 
+
51030
 
+install-pdf: install-pdf-am
51031
 
+
51032
 
+install-ps: install-ps-am
51033
 
+
51034
 
+installcheck-am:
51035
 
+
51036
 
+maintainer-clean: maintainer-clean-am
51037
 
+       -rm -rf ./$(DEPDIR)
51038
 
+       -rm -f Makefile
51039
 
+maintainer-clean-am: distclean-am maintainer-clean-generic
51040
 
+
51041
 
+mostlyclean: mostlyclean-am
51042
 
+
51043
 
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
51044
 
+       mostlyclean-libtool
51045
 
+
51046
 
+pdf: pdf-am
51047
 
+
51048
 
+pdf-am:
51049
 
+
51050
 
+ps: ps-am
51051
 
+
51052
 
+ps-am:
51053
 
+
51054
 
+uninstall-am:
51055
 
+
51056
 
+.MAKE: install-am install-strip
51057
 
+
51058
 
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
51059
 
+       clean-libtool clean-noinstLTLIBRARIES ctags distclean \
51060
 
+       distclean-compile distclean-generic distclean-libtool \
51061
 
+       distclean-tags distdir dvi dvi-am html html-am info info-am \
51062
 
+       install install-am install-data install-data-am install-dvi \
51063
 
+       install-dvi-am install-exec install-exec-am install-html \
51064
 
+       install-html-am install-info install-info-am install-man \
51065
 
+       install-pdf install-pdf-am install-ps install-ps-am \
51066
 
+       install-strip installcheck installcheck-am installdirs \
51067
 
+       maintainer-clean maintainer-clean-generic mostlyclean \
51068
 
+       mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
51069
 
+       pdf pdf-am ps ps-am tags uninstall uninstall-am
51070
 
+
51071
 
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
51072
 
+# Otherwise a system limit (for SysV at least) may be exceeded.
51073
 
+.NOEXPORT:
51074
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/date/ext-date.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/date/ext-date.c
51075
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/date/ext-date.c        1970-01-01 01:00:00.000000000 +0100
51076
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/date/ext-date.c 2009-08-21 00:52:15.000000000 +0200
51077
 
@@ -0,0 +1,67 @@
51078
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
51079
 
+ */
51080
 
+
51081
 
+/* Extension date
51082
 
+ * ------------------
51083
 
+ *
51084
 
+ * Authors: Stephan Bosch
51085
 
+ * Specification: RFC 5260
51086
 
+ * Implementation: full
51087
 
+ * Status: experimental
51088
 
+ *
51089
 
+ */
51090
 
51091
 
+#include "lib.h"
51092
 
+#include "array.h"
51093
 
+
51094
 
+#include "sieve-common.h"
51095
 
+
51096
 
+#include "sieve-extensions.h"
51097
 
+#include "sieve-commands.h"
51098
 
+#include "sieve-comparators.h"
51099
 
+#include "sieve-match-types.h"
51100
 
+#include "sieve-address-parts.h"
51101
 
+
51102
 
+#include "sieve-validator.h"
51103
 
+#include "sieve-generator.h"
51104
 
+#include "sieve-binary.h"
51105
 
+#include "sieve-interpreter.h"
51106
 
+#include "sieve-dump.h"
51107
 
+
51108
 
+#include "ext-date-common.h"
51109
 
+
51110
 
+/* 
51111
 
+ * Extension 
51112
 
+ */
51113
 
+
51114
 
+static bool ext_date_validator_load(struct sieve_validator *validator);
51115
 
+
51116
 
+int ext_date_my_id = -1;
51117
 
+
51118
 
+const struct sieve_operation *ext_date_operations[] = {
51119
 
+       &date_operation,
51120
 
+       &currentdate_operation
51121
 
+};
51122
 
+
51123
 
+const struct sieve_extension date_extension = { 
51124
 
+       "date", 
51125
 
+       &ext_date_my_id,
51126
 
+       NULL, NULL,
51127
 
+       ext_date_validator_load, 
51128
 
+       NULL, 
51129
 
+       ext_date_interpreter_load, 
51130
 
+       NULL, NULL, NULL,
51131
 
+       SIEVE_EXT_DEFINE_OPERATIONS(ext_date_operations), 
51132
 
+       SIEVE_EXT_DEFINE_NO_OPERANDS
51133
 
+};
51134
 
+
51135
 
+static bool ext_date_validator_load(struct sieve_validator *valdtr)
51136
 
+{
51137
 
+       /* Register new test */
51138
 
+       sieve_validator_register_command(valdtr, &date_test);
51139
 
+       sieve_validator_register_command(valdtr, &currentdate_test);
51140
 
+
51141
 
+       return TRUE;
51142
 
+}
51143
 
+
51144
 
+
51145
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/date/ext-date-common.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/date/ext-date-common.c
51146
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/date/ext-date-common.c 1970-01-01 01:00:00.000000000 +0100
51147
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/date/ext-date-common.c  2009-08-21 00:52:15.000000000 +0200
51148
 
@@ -0,0 +1,464 @@
51149
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
51150
 
+ */
51151
 
+
51152
 
+#include "lib.h"
51153
 
+#include "utc-offset.h"
51154
 
+
51155
 
+#include "sieve-common.h"
51156
 
+#include "sieve-interpreter.h"
51157
 
+#include "sieve-message.h"
51158
 
+
51159
 
+#include "ext-date-common.h"
51160
 
+
51161
 
+#include <time.h>
51162
 
+#include <ctype.h>
51163
 
+
51164
 
+struct ext_date_context {
51165
 
+       time_t current_date;
51166
 
+       int zone_offset;
51167
 
+};
51168
 
+
51169
 
+/*
51170
 
+ * Runtime initialization
51171
 
+ */
51172
 
+
51173
 
+static void ext_date_runtime_init
51174
 
+(const struct sieve_runtime_env *renv, void *context ATTR_UNUSED)
51175
 
+{
51176
 
+       struct ext_date_context *dctx;
51177
 
+       pool_t pool;
51178
 
+       struct tm *tm;
51179
 
+       time_t current_date;
51180
 
+       int zone_offset;
51181
 
+
51182
 
+       /* Get current time at instance main script is started */
51183
 
+       time(&current_date);    
51184
 
+
51185
 
+       tm = localtime(&current_date);
51186
 
+       zone_offset = utc_offset(tm, current_date);
51187
 
+
51188
 
+       /* Create context */
51189
 
+       pool = sieve_message_context_pool(renv->msgctx);
51190
 
+       dctx = p_new(pool, struct ext_date_context, 1);
51191
 
+       dctx->current_date = current_date;
51192
 
+       dctx->zone_offset = zone_offset;
51193
 
+
51194
 
+       sieve_message_context_extension_set
51195
 
+               (renv->msgctx, &date_extension, (void *) dctx);
51196
 
+}
51197
 
+
51198
 
+static struct sieve_interpreter_extension date_interpreter_extension = {
51199
 
+       &date_extension,
51200
 
+       ext_date_runtime_init,
51201
 
+       NULL,
51202
 
+};
51203
 
+
51204
 
+bool ext_date_interpreter_load
51205
 
+(const struct sieve_runtime_env *renv, sieve_size_t *address ATTR_UNUSED)
51206
 
+{      
51207
 
+       /* Register runtime hook to obtain stript start timestamp */
51208
 
+       if ( renv->msgctx == NULL ||
51209
 
+               sieve_message_context_extension_get(renv->msgctx, &date_extension)
51210
 
+               == NULL ) {
51211
 
+               sieve_interpreter_extension_register
51212
 
+                       (renv->interp, &date_interpreter_extension, NULL);
51213
 
+       }
51214
 
+
51215
 
+       return TRUE;
51216
 
+}
51217
 
+
51218
 
+/*
51219
 
+ * Zone string
51220
 
+ */
51221
 
+
51222
 
+bool ext_date_parse_timezone
51223
 
+(const char *zone, int *zone_offset_r)
51224
 
+{
51225
 
+       const unsigned char *str = (const unsigned char *) zone;
51226
 
+       size_t len = strlen(zone);
51227
 
+
51228
 
+       if (len == 5 && (*str == '+' || *str == '-')) {
51229
 
+               int offset;
51230
 
+
51231
 
+               if (!i_isdigit(str[1]) || !i_isdigit(str[2]) ||
51232
 
+                   !i_isdigit(str[3]) || !i_isdigit(str[4]))
51233
 
+                       return FALSE;
51234
 
+
51235
 
+               offset = ((str[1]-'0') * 10 + (str[2]-'0')) * 60  +
51236
 
+                       (str[3]-'0') * 10 + (str[4]-'0');
51237
 
+
51238
 
+               if ( zone_offset_r != NULL )            
51239
 
+                       *zone_offset_r = *str == '+' ? offset : -offset;
51240
 
+
51241
 
+               return TRUE;
51242
 
+       }
51243
 
+
51244
 
+       return FALSE;
51245
 
+}
51246
 
+
51247
 
+/*
51248
 
+ * Current date
51249
 
+ */
51250
 
+
51251
 
+time_t ext_date_get_current_date
51252
 
+(const struct sieve_runtime_env *renv, int *zone_offset_r)
51253
 
+{      
51254
 
+       struct ext_date_context *dctx = (struct ext_date_context *) 
51255
 
+               sieve_message_context_extension_get(renv->msgctx, &date_extension);
51256
 
+
51257
 
+       if ( dctx == NULL ) {
51258
 
+               ext_date_runtime_init(renv, NULL);
51259
 
+               dctx = (struct ext_date_context *) 
51260
 
+                       sieve_message_context_extension_get(renv->msgctx, &date_extension);
51261
 
+
51262
 
+               i_assert(dctx != NULL);
51263
 
+       }
51264
 
+
51265
 
+       /* Read script start timestamp from message context */
51266
 
+
51267
 
+       if ( zone_offset_r != NULL )
51268
 
+               *zone_offset_r = dctx->zone_offset;
51269
 
+
51270
 
+       return dctx->current_date;
51271
 
+}
51272
 
+
51273
 
+/* 
51274
 
+ * Date parts 
51275
 
+ */
51276
 
+
51277
 
+/* "year"      => the year, "0000" .. "9999". 
51278
 
+ */
51279
 
+
51280
 
+static const char *ext_date_year_part_get(struct tm *tm, int zone_offset);
51281
 
+
51282
 
+static const struct ext_date_part year_date_part = {
51283
 
+       "year",
51284
 
+       ext_date_year_part_get
51285
 
+};
51286
 
+
51287
 
+/* "month"     => the month, "01" .. "12".
51288
 
+ */
51289
 
+
51290
 
+static const char *ext_date_month_part_get(struct tm *tm, int zone_offset);
51291
 
+
51292
 
+static const struct ext_date_part month_date_part = {
51293
 
+       "month",
51294
 
+       ext_date_month_part_get
51295
 
+};
51296
 
+
51297
 
+/* "day"       => the day, "01" .. "31".
51298
 
+ */
51299
 
+
51300
 
+static const char *ext_date_day_part_get(struct tm *tm, int zone_offset);
51301
 
+
51302
 
+static const struct ext_date_part day_date_part = {
51303
 
+       "day",
51304
 
+       ext_date_day_part_get
51305
 
+};
51306
 
+
51307
 
+/* "date"      => the date in "yyyy-mm-dd" format.
51308
 
+ */
51309
 
+
51310
 
+static const char *ext_date_date_part_get(struct tm *tm, int zone_offset);
51311
 
+
51312
 
+static const struct ext_date_part date_date_part = {
51313
 
+       "date",
51314
 
+       ext_date_date_part_get
51315
 
+};
51316
 
+
51317
 
+/* "julian"    => the Modified Julian Day, that is, the date
51318
 
+ *              expressed as an integer number of days since
51319
 
+ *              00:00 UTC on November 17, 1858 (using the Gregorian
51320
 
+ *              calendar).  This corresponds to the regular
51321
 
+ *              Julian Day minus 2400000.5.  Sample routines to
51322
 
+ *              convert to and from modified Julian dates are
51323
 
+ *              given in Appendix A.
51324
 
+ */ 
51325
 
+
51326
 
+static const char *ext_date_julian_part_get(struct tm *tm, int zone_offset);
51327
 
+
51328
 
+static const struct ext_date_part julian_date_part = {
51329
 
+       "julian",
51330
 
+       ext_date_julian_part_get
51331
 
+};
51332
 
+
51333
 
+/* "hour"      => the hour, "00" .. "23". 
51334
 
+ */
51335
 
+static const char *ext_date_hour_part_get(struct tm *tm, int zone_offset);
51336
 
+
51337
 
+static const struct ext_date_part hour_date_part = {
51338
 
+       "hour",
51339
 
+       ext_date_hour_part_get
51340
 
+};
51341
 
+
51342
 
+/* "minute"    => the minute, "00" .. "59".
51343
 
+ */
51344
 
+static const char *ext_date_minute_part_get(struct tm *tm, int zone_offset);
51345
 
+
51346
 
+static const struct ext_date_part minute_date_part = {
51347
 
+       "minute",
51348
 
+       ext_date_minute_part_get
51349
 
+};
51350
 
+
51351
 
+/* "second"    => the second, "00" .. "60".
51352
 
+ */
51353
 
+static const char *ext_date_second_part_get(struct tm *tm, int zone_offset);
51354
 
+
51355
 
+static const struct ext_date_part second_date_part = {
51356
 
+       "second",
51357
 
+       ext_date_second_part_get
51358
 
+};
51359
 
+
51360
 
+/* "time"      => the time in "hh:mm:ss" format.
51361
 
+ */
51362
 
+static const char *ext_date_time_part_get(struct tm *tm, int zone_offset);
51363
 
+
51364
 
+static const struct ext_date_part time_date_part = {
51365
 
+       "time",
51366
 
+       ext_date_time_part_get
51367
 
+};
51368
 
+
51369
 
+/* "iso8601"   => the date and time in restricted ISO 8601 format.
51370
 
+ */
51371
 
+static const char *ext_date_iso8601_part_get(struct tm *tm, int zone_offset);
51372
 
+
51373
 
+static const struct ext_date_part iso8601_date_part = {
51374
 
+       "iso8601",
51375
 
+       ext_date_iso8601_part_get
51376
 
+};
51377
 
+
51378
 
+/* "std11"     => the date and time in a format appropriate
51379
 
+ *                for use in a Date: header field [RFC2822].
51380
 
+ */
51381
 
+static const char *ext_date_std11_part_get(struct tm *tm, int zone_offset);
51382
 
+
51383
 
+static const struct ext_date_part std11_date_part = {
51384
 
+       "std11",
51385
 
+       ext_date_std11_part_get
51386
 
+};
51387
 
+
51388
 
+/* "zone"      => the time zone in use.  If the user specified a
51389
 
+ *                time zone with ":zone", "zone" will
51390
 
+ *                contain that value.  If :originalzone is specified
51391
 
+ *                this value will be the original zone specified
51392
 
+ *                in the date-time value.  If neither argument is
51393
 
+ *                specified the value will be the server's default
51394
 
+ *                time zone in offset format "+hhmm" or "-hhmm".  An
51395
 
+ *                 offset of 0 (Zulu) always has a positive sign.
51396
 
+ */
51397
 
+static const char *ext_date_zone_part_get(struct tm *tm, int zone_offset);
51398
 
+
51399
 
+static const struct ext_date_part zone_date_part = {
51400
 
+       "zone",
51401
 
+       ext_date_zone_part_get
51402
 
+};
51403
 
51404
 
+/* "weekday"   => the day of the week expressed as an integer between
51405
 
+ *                "0" and "6". "0" is Sunday, "1" is Monday, etc.
51406
 
+ */
51407
 
+static const char *ext_date_weekday_part_get(struct tm *tm, int zone_offset);
51408
 
+
51409
 
+static const struct ext_date_part weekday_date_part = {
51410
 
+       "weekday",
51411
 
+       ext_date_weekday_part_get
51412
 
+};
51413
 
+
51414
 
+/*
51415
 
+ * Date part extraction
51416
 
+ */
51417
 
+
51418
 
+static const struct ext_date_part *date_parts[] = {
51419
 
+       &year_date_part, &month_date_part, &day_date_part, &date_date_part,
51420
 
+       &julian_date_part, &hour_date_part, &minute_date_part, &second_date_part,
51421
 
+       &time_date_part, &iso8601_date_part, &std11_date_part, &zone_date_part, 
51422
 
+       &weekday_date_part 
51423
 
+};
51424
 
+
51425
 
+unsigned int date_parts_count = N_ELEMENTS(date_parts);
51426
 
+
51427
 
+const char *ext_date_part_extract
51428
 
+(const char *part, struct tm *tm, int zone_offset)
51429
 
+{
51430
 
+       unsigned int i;
51431
 
+
51432
 
+       for ( i = 0; i < date_parts_count; i++ ) {
51433
 
+               if ( strcasecmp(date_parts[i]->identifier, part) == 0 ) {
51434
 
+                       if ( date_parts[i]->get_string != NULL )
51435
 
+                               return date_parts[i]->get_string(tm, zone_offset);
51436
 
+
51437
 
+                       return NULL;
51438
 
+               }
51439
 
+       }
51440
 
+       
51441
 
+       return NULL;
51442
 
+}
51443
 
+
51444
 
+/*
51445
 
+ * Date part implementations
51446
 
+ */
51447
 
+
51448
 
+static const char *month_names[] = {
51449
 
+       "Jan", "Feb", "Mar", "Apr", "May", "Jun",
51450
 
+       "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
51451
 
+};
51452
 
+
51453
 
+static const char *weekday_names[] = {
51454
 
+       "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
51455
 
+};
51456
 
+
51457
 
+static const char *ext_date_year_part_get
51458
 
+(struct tm *tm, int zone_offset ATTR_UNUSED)
51459
 
+{
51460
 
+       return t_strdup_printf("%04d", tm->tm_year + 1900);
51461
 
+}
51462
 
+
51463
 
+static const char *ext_date_month_part_get
51464
 
+(struct tm *tm, int zone_offset ATTR_UNUSED)
51465
 
+{
51466
 
+       return t_strdup_printf("%02d", tm->tm_mon + 1);
51467
 
+}
51468
 
+
51469
 
+static const char *ext_date_day_part_get
51470
 
+(struct tm *tm, int zone_offset ATTR_UNUSED)
51471
 
+{
51472
 
+       return t_strdup_printf("%02d", tm->tm_mday);
51473
 
+}
51474
 
+
51475
 
+static const char *ext_date_date_part_get
51476
 
+(struct tm *tm, int zone_offset ATTR_UNUSED)
51477
 
+{
51478
 
+       return t_strdup_printf("%04d-%02d-%02d", 
51479
 
+               tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday);
51480
 
+}
51481
 
+
51482
 
+static const char *ext_date_julian_part_get
51483
 
+(struct tm *tm, int zone_offset ATTR_UNUSED)
51484
 
+{
51485
 
+       int year = tm->tm_year+1900;
51486
 
+       int month = tm->tm_mon+1;
51487
 
+       int day = tm->tm_mday;
51488
 
+       int c, ya, jd;
51489
 
+       
51490
 
+       /* Modified from RFC 5260 Appendix A */ 
51491
 
+
51492
 
+       if ( month > 2 )
51493
 
+               month -= 3;
51494
 
+       else {
51495
 
+               month += 9;
51496
 
+               year--;
51497
 
+       }
51498
 
+
51499
 
+       c = year / 100;
51500
 
+       ya = year - c * 100;
51501
 
+
51502
 
+       jd = c * 146097 / 4 + ya * 1461 / 4 + (month * 153 + 2) / 5 + day + 1721119;
51503
 
+       
51504
 
+       return t_strdup_printf("%d", jd - 2400001);
51505
 
+}
51506
 
+
51507
 
+static const char *ext_date_hour_part_get
51508
 
+(struct tm *tm, int zone_offset ATTR_UNUSED)
51509
 
+{
51510
 
+       return t_strdup_printf("%02d", tm->tm_hour);
51511
 
+}
51512
 
+
51513
 
+static const char *ext_date_minute_part_get
51514
 
+(struct tm *tm, int zone_offset ATTR_UNUSED)
51515
 
+{
51516
 
+       return t_strdup_printf("%02d", tm->tm_min);
51517
 
+}
51518
 
+
51519
 
+static const char *ext_date_second_part_get
51520
 
+(struct tm *tm, int zone_offset ATTR_UNUSED)
51521
 
+{
51522
 
+       return t_strdup_printf("%02d", tm->tm_sec);
51523
 
+}
51524
 
+
51525
 
+static const char *ext_date_time_part_get
51526
 
+(struct tm *tm, int zone_offset ATTR_UNUSED)
51527
 
+{
51528
 
+       return t_strdup_printf("%02d:%02d:%02d", tm->tm_hour, tm->tm_min, tm->tm_sec);
51529
 
+}
51530
 
+
51531
 
+static const char *ext_date_iso8601_part_get
51532
 
+(struct tm *tm, int zone_offset)
51533
 
+{
51534
 
+       const char *time_offset;
51535
 
+
51536
 
+       /* 
51537
 
+        * RFC 3339: 5.6. Internet Date/Time Format
51538
 
+        * 
51539
 
+        * The following profile of ISO 8601 [ISO8601] dates SHOULD be used in
51540
 
+        * new protocols on the Internet.  This is specified using the syntax
51541
 
+        * description notation defined in [ABNF].
51542
 
+        * 
51543
 
+        * date-fullyear   = 4DIGIT
51544
 
+        * date-month      = 2DIGIT  ; 01-12
51545
 
+        * date-mday       = 2DIGIT  ; 01-28, 01-29, 01-30, 01-31 based on
51546
 
+        *                                   ; month/year
51547
 
+        * time-hour       = 2DIGIT  ; 00-23
51548
 
+        * time-minute     = 2DIGIT  ; 00-59
51549
 
+        * time-second     = 2DIGIT  ; 00-58, 00-59, 00-60 based on leap second
51550
 
+        *                                   ; rules
51551
 
+        * time-secfrac    = "." 1*DIGIT
51552
 
+        * time-numoffset  = ("+" / "-") time-hour ":" time-minute
51553
 
+        * time-offset     = "Z" / time-numoffset
51554
 
+        * 
51555
 
+        * partial-time    = time-hour ":" time-minute ":" time-second
51556
 
+        *                           [time-secfrac]
51557
 
+        * full-date       = date-fullyear "-" date-month "-" date-mday
51558
 
+        * full-time       = partial-time time-offset
51559
 
+        * 
51560
 
+        * date-time       = full-date "T" full-time
51561
 
+        * 
51562
 
+        */
51563
 
+
51564
 
+       if ( zone_offset == 0 )
51565
 
+               time_offset = "Z";
51566
 
+       else {
51567
 
+               int offset = zone_offset > 0 ? zone_offset : -zone_offset;
51568
 
+
51569
 
+               time_offset = t_strdup_printf
51570
 
+                       ("%c%02d:%02d", (zone_offset > 0 ? '+' : '-'), offset / 60, offset % 60);
51571
 
+       }
51572
 
+
51573
 
+       return t_strdup_printf("%04d-%02d-%02dT%02d:%02d:%02d%s",
51574
 
+               tm->tm_year + 1900, tm->tm_mon+1, tm->tm_mday, tm->tm_hour, tm->tm_min, 
51575
 
+               tm->tm_sec, time_offset); 
51576
 
+}
51577
 
+
51578
 
+static const char *ext_date_std11_part_get
51579
 
+(struct tm *tm, int zone_offset)
51580
 
+{
51581
 
+       return t_strdup_printf("%s, %02d %s %04d %02d:%02d:%02d %s",
51582
 
+               weekday_names[tm->tm_wday],
51583
 
+               tm->tm_mday,
51584
 
+               month_names[tm->tm_mon],
51585
 
+               tm->tm_year+1900,
51586
 
+               tm->tm_hour, tm->tm_min, tm->tm_sec, 
51587
 
+               ext_date_zone_part_get(tm, zone_offset));
51588
 
+}
51589
 
+
51590
 
+static const char *ext_date_zone_part_get
51591
 
+(struct tm *tm ATTR_UNUSED, int zone_offset)
51592
 
+{
51593
 
+       bool negative;
51594
 
+       int offset = zone_offset;
51595
 
+
51596
 
+       if (zone_offset >= 0)
51597
 
+               negative = FALSE;
51598
 
+       else {
51599
 
+               negative = TRUE;
51600
 
+               offset = -offset;
51601
 
+       }
51602
 
+
51603
 
+       return t_strdup_printf
51604
 
+               ("%c%02d%02d", negative ? '-' : '+', offset / 60, offset % 60);
51605
 
+}
51606
 
+
51607
 
+static const char *ext_date_weekday_part_get
51608
 
+(struct tm *tm, int zone_offset ATTR_UNUSED)
51609
 
+{
51610
 
+       return t_strdup_printf("%d", tm->tm_wday);
51611
 
+}
51612
 
+
51613
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/date/ext-date-common.h dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/date/ext-date-common.h
51614
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/date/ext-date-common.h 1970-01-01 01:00:00.000000000 +0100
51615
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/date/ext-date-common.h  2009-08-21 00:52:15.000000000 +0200
51616
 
@@ -0,0 +1,65 @@
51617
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
51618
 
+ */
51619
 
51620
 
+#ifndef __EXT_DATE_COMMON_H
51621
 
+#define __EXT_DATE_COMMON_H
51622
 
+
51623
 
+#include "sieve-common.h"
51624
 
+
51625
 
+#include <time.h>
51626
 
+
51627
 
+/*
51628
 
+ * Extension
51629
 
+ */
51630
 
51631
 
+extern const struct sieve_extension date_extension;
51632
 
+
51633
 
+bool ext_date_interpreter_load
51634
 
+       (const struct sieve_runtime_env *renv, sieve_size_t *address ATTR_UNUSED);
51635
 
+
51636
 
+/* 
51637
 
+ * Tests
51638
 
+ */
51639
 
+
51640
 
+extern const struct sieve_command date_test;
51641
 
+extern const struct sieve_command currentdate_test;
51642
 
51643
 
+/*
51644
 
+ * Operations
51645
 
+ */
51646
 
+
51647
 
+enum ext_date_opcode {
51648
 
+       EXT_DATE_OPERATION_DATE,
51649
 
+       EXT_DATE_OPERATION_CURRENTDATE
51650
 
+};
51651
 
+
51652
 
+extern const struct sieve_operation date_operation;
51653
 
+extern const struct sieve_operation currentdate_operation;
51654
 
+
51655
 
+/*
51656
 
+ * Zone string
51657
 
+ */
51658
 
+
51659
 
+bool ext_date_parse_timezone(const char *zone, int *zone_offset_r);
51660
 
+
51661
 
+/*
51662
 
+ * Current date
51663
 
+ */
51664
 
+
51665
 
+time_t ext_date_get_current_date
51666
 
+       (const struct sieve_runtime_env *renv, int *zone_offset_r);
51667
 
+
51668
 
+/*
51669
 
+ * Date part
51670
 
+ */
51671
 
+
51672
 
+struct ext_date_part {
51673
 
+       const char *identifier;
51674
 
+
51675
 
+       const char *(*get_string)(struct tm *tm, int zone_offset);
51676
 
+};
51677
 
+
51678
 
+const char *ext_date_part_extract
51679
 
+       (const char *part, struct tm *tm, int zone_offset);
51680
 
+
51681
 
+#endif /* __EXT_DATE_COMMON_H */
51682
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/date/Makefile.am dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/date/Makefile.am
51683
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/date/Makefile.am       1970-01-01 01:00:00.000000000 +0100
51684
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/date/Makefile.am        2009-08-10 09:55:31.000000000 +0200
51685
 
@@ -0,0 +1,19 @@
51686
 
+noinst_LTLIBRARIES = libsieve_ext_date.la
51687
 
+
51688
 
+AM_CPPFLAGS = \
51689
 
+       -I../../ \
51690
 
+       -I$(dovecot_incdir) \
51691
 
+       -I$(dovecot_incdir)/src/lib \
51692
 
+       -I$(dovecot_incdir)/src/lib-mail \
51693
 
+       -I$(dovecot_incdir)/src/lib-storage 
51694
 
+
51695
 
+tests = \
51696
 
+       tst-date.c
51697
 
+
51698
 
+libsieve_ext_date_la_SOURCES = \
51699
 
+       $(tests) \
51700
 
+       ext-date-common.c \
51701
 
+       ext-date.c
51702
 
+
51703
 
+noinst_HEADERS = \
51704
 
+       ext-date-common.h
51705
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/date/Makefile.in dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/date/Makefile.in
51706
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/date/Makefile.in       1970-01-01 01:00:00.000000000 +0100
51707
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/date/Makefile.in        2009-08-21 00:55:43.000000000 +0200
51708
 
@@ -0,0 +1,468 @@
51709
 
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
51710
 
+# @configure_input@
51711
 
+
51712
 
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
51713
 
+# 2003, 2004, 2005, 2006, 2007, 2008  Free Software Foundation, Inc.
51714
 
+# This Makefile.in is free software; the Free Software Foundation
51715
 
+# gives unlimited permission to copy and/or distribute it,
51716
 
+# with or without modifications, as long as this notice is preserved.
51717
 
+
51718
 
+# This program is distributed in the hope that it will be useful,
51719
 
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
51720
 
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
51721
 
+# PARTICULAR PURPOSE.
51722
 
+
51723
 
+@SET_MAKE@
51724
 
+
51725
 
+
51726
 
+VPATH = @srcdir@
51727
 
+pkgdatadir = $(datadir)/@PACKAGE@
51728
 
+pkglibdir = $(libdir)/@PACKAGE@
51729
 
+pkgincludedir = $(includedir)/@PACKAGE@
51730
 
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
51731
 
+install_sh_DATA = $(install_sh) -c -m 644
51732
 
+install_sh_PROGRAM = $(install_sh) -c
51733
 
+install_sh_SCRIPT = $(install_sh) -c
51734
 
+INSTALL_HEADER = $(INSTALL_DATA)
51735
 
+transform = $(program_transform_name)
51736
 
+NORMAL_INSTALL = :
51737
 
+PRE_INSTALL = :
51738
 
+POST_INSTALL = :
51739
 
+NORMAL_UNINSTALL = :
51740
 
+PRE_UNINSTALL = :
51741
 
+POST_UNINSTALL = :
51742
 
+build_triplet = @build@
51743
 
+host_triplet = @host@
51744
 
+subdir = src/lib-sieve/plugins/date
51745
 
+DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
51746
 
+       $(srcdir)/Makefile.in
51747
 
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
51748
 
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
51749
 
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
51750
 
+       $(ACLOCAL_M4)
51751
 
+mkinstalldirs = $(install_sh) -d
51752
 
+CONFIG_HEADER = $(top_builddir)/dummy-config.h \
51753
 
+       $(top_builddir)/dsieve-config.h
51754
 
+CONFIG_CLEAN_FILES =
51755
 
+LTLIBRARIES = $(noinst_LTLIBRARIES)
51756
 
+libsieve_ext_date_la_LIBADD =
51757
 
+am__objects_1 = tst-date.lo
51758
 
+am_libsieve_ext_date_la_OBJECTS = $(am__objects_1) ext-date-common.lo \
51759
 
+       ext-date.lo
51760
 
+libsieve_ext_date_la_OBJECTS = $(am_libsieve_ext_date_la_OBJECTS)
51761
 
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
51762
 
+depcomp = $(SHELL) $(top_srcdir)/depcomp
51763
 
+am__depfiles_maybe = depfiles
51764
 
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
51765
 
+       $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
51766
 
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
51767
 
+       --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
51768
 
+       $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
51769
 
+CCLD = $(CC)
51770
 
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
51771
 
+       --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
51772
 
+       $(LDFLAGS) -o $@
51773
 
+SOURCES = $(libsieve_ext_date_la_SOURCES)
51774
 
+DIST_SOURCES = $(libsieve_ext_date_la_SOURCES)
51775
 
+HEADERS = $(noinst_HEADERS)
51776
 
+ETAGS = etags
51777
 
+CTAGS = ctags
51778
 
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
51779
 
+ACLOCAL = @ACLOCAL@
51780
 
+AMTAR = @AMTAR@
51781
 
+AR = @AR@
51782
 
+AUTOCONF = @AUTOCONF@
51783
 
+AUTOHEADER = @AUTOHEADER@
51784
 
+AUTOMAKE = @AUTOMAKE@
51785
 
+AWK = @AWK@
51786
 
+CC = @CC@
51787
 
+CCDEPMODE = @CCDEPMODE@
51788
 
+CFLAGS = @CFLAGS@
51789
 
+CPP = @CPP@
51790
 
+CPPFLAGS = @CPPFLAGS@
51791
 
+CYGPATH_W = @CYGPATH_W@
51792
 
+DEFS = @DEFS@
51793
 
+DEPDIR = @DEPDIR@
51794
 
+DSYMUTIL = @DSYMUTIL@
51795
 
+DUMPBIN = @DUMPBIN@
51796
 
+ECHO_C = @ECHO_C@
51797
 
+ECHO_N = @ECHO_N@
51798
 
+ECHO_T = @ECHO_T@
51799
 
+EGREP = @EGREP@
51800
 
+EXEEXT = @EXEEXT@
51801
 
+FGREP = @FGREP@
51802
 
+GREP = @GREP@
51803
 
+INSTALL = @INSTALL@
51804
 
+INSTALL_DATA = @INSTALL_DATA@
51805
 
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
51806
 
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
51807
 
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
51808
 
+LD = @LD@
51809
 
+LDFLAGS = @LDFLAGS@
51810
 
+LIBICONV = @LIBICONV@
51811
 
+LIBOBJS = @LIBOBJS@
51812
 
+LIBS = @LIBS@
51813
 
+LIBTOOL = @LIBTOOL@
51814
 
+LIPO = @LIPO@
51815
 
+LN_S = @LN_S@
51816
 
+LTLIBOBJS = @LTLIBOBJS@
51817
 
+MAINT = @MAINT@
51818
 
+MAKEINFO = @MAKEINFO@
51819
 
+MKDIR_P = @MKDIR_P@
51820
 
+MODULE_LIBS = @MODULE_LIBS@
51821
 
+NM = @NM@
51822
 
+NMEDIT = @NMEDIT@
51823
 
+OBJDUMP = @OBJDUMP@
51824
 
+OBJEXT = @OBJEXT@
51825
 
+OTOOL = @OTOOL@
51826
 
+OTOOL64 = @OTOOL64@
51827
 
+PACKAGE = @PACKAGE@
51828
 
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
51829
 
+PACKAGE_NAME = @PACKAGE_NAME@
51830
 
+PACKAGE_STRING = @PACKAGE_STRING@
51831
 
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
51832
 
+PACKAGE_URL = @PACKAGE_URL@
51833
 
+PACKAGE_VERSION = @PACKAGE_VERSION@
51834
 
+PATH_SEPARATOR = @PATH_SEPARATOR@
51835
 
+RAND_LIBS = @RAND_LIBS@
51836
 
+RANLIB = @RANLIB@
51837
 
+SED = @SED@
51838
 
+SET_MAKE = @SET_MAKE@
51839
 
+SHELL = @SHELL@
51840
 
+STORAGE_LIBS = @STORAGE_LIBS@
51841
 
+STRIP = @STRIP@
51842
 
+VERSION = @VERSION@
51843
 
+abs_builddir = @abs_builddir@
51844
 
+abs_srcdir = @abs_srcdir@
51845
 
+abs_top_builddir = @abs_top_builddir@
51846
 
+abs_top_srcdir = @abs_top_srcdir@
51847
 
+ac_ct_CC = @ac_ct_CC@
51848
 
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
51849
 
+am__include = @am__include@
51850
 
+am__leading_dot = @am__leading_dot@
51851
 
+am__quote = @am__quote@
51852
 
+am__tar = @am__tar@
51853
 
+am__untar = @am__untar@
51854
 
+bindir = @bindir@
51855
 
+build = @build@
51856
 
+build_alias = @build_alias@
51857
 
+build_cpu = @build_cpu@
51858
 
+build_os = @build_os@
51859
 
+build_vendor = @build_vendor@
51860
 
+builddir = @builddir@
51861
 
+datadir = @datadir@
51862
 
+datarootdir = @datarootdir@
51863
 
+docdir = @docdir@
51864
 
+dovecot_incdir = @dovecot_incdir@
51865
 
+dovecotdir = @dovecotdir@
51866
 
+dvidir = @dvidir@
51867
 
+exec_prefix = @exec_prefix@
51868
 
+host = @host@
51869
 
+host_alias = @host_alias@
51870
 
+host_cpu = @host_cpu@
51871
 
+host_os = @host_os@
51872
 
+host_vendor = @host_vendor@
51873
 
+htmldir = @htmldir@
51874
 
+includedir = @includedir@
51875
 
+infodir = @infodir@
51876
 
+install_sh = @install_sh@
51877
 
+libdir = @libdir@
51878
 
+libexecdir = @libexecdir@
51879
 
+localedir = @localedir@
51880
 
+localstatedir = @localstatedir@
51881
 
+lt_ECHO = @lt_ECHO@
51882
 
+mandir = @mandir@
51883
 
+mkdir_p = @mkdir_p@
51884
 
+moduledir = @moduledir@
51885
 
+oldincludedir = @oldincludedir@
51886
 
+pdfdir = @pdfdir@
51887
 
+prefix = @prefix@
51888
 
+program_transform_name = @program_transform_name@
51889
 
+psdir = @psdir@
51890
 
+sbindir = @sbindir@
51891
 
+sharedstatedir = @sharedstatedir@
51892
 
+srcdir = @srcdir@
51893
 
+sysconfdir = @sysconfdir@
51894
 
+target_alias = @target_alias@
51895
 
+top_build_prefix = @top_build_prefix@
51896
 
+top_builddir = @top_builddir@
51897
 
+top_srcdir = @top_srcdir@
51898
 
+noinst_LTLIBRARIES = libsieve_ext_date.la
51899
 
+AM_CPPFLAGS = \
51900
 
+       -I../../ \
51901
 
+       -I$(dovecot_incdir) \
51902
 
+       -I$(dovecot_incdir)/src/lib \
51903
 
+       -I$(dovecot_incdir)/src/lib-mail \
51904
 
+       -I$(dovecot_incdir)/src/lib-storage 
51905
 
+
51906
 
+tests = \
51907
 
+       tst-date.c
51908
 
+
51909
 
+libsieve_ext_date_la_SOURCES = \
51910
 
+       $(tests) \
51911
 
+       ext-date-common.c \
51912
 
+       ext-date.c
51913
 
+
51914
 
+noinst_HEADERS = \
51915
 
+       ext-date-common.h
51916
 
+
51917
 
+all: all-am
51918
 
+
51919
 
+.SUFFIXES:
51920
 
+.SUFFIXES: .c .lo .o .obj
51921
 
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
51922
 
+       @for dep in $?; do \
51923
 
+         case '$(am__configure_deps)' in \
51924
 
+           *$$dep*) \
51925
 
+             ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
51926
 
+               && { if test -f $@; then exit 0; else break; fi; }; \
51927
 
+             exit 1;; \
51928
 
+         esac; \
51929
 
+       done; \
51930
 
+       echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign  src/lib-sieve/plugins/date/Makefile'; \
51931
 
+       cd $(top_srcdir) && \
51932
 
+         $(AUTOMAKE) --foreign  src/lib-sieve/plugins/date/Makefile
51933
 
+.PRECIOUS: Makefile
51934
 
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
51935
 
+       @case '$?' in \
51936
 
+         *config.status*) \
51937
 
+           cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
51938
 
+         *) \
51939
 
+           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
51940
 
+           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
51941
 
+       esac;
51942
 
+
51943
 
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
51944
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
51945
 
+
51946
 
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
51947
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
51948
 
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
51949
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
51950
 
+
51951
 
+clean-noinstLTLIBRARIES:
51952
 
+       -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
51953
 
+       @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
51954
 
+         dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
51955
 
+         test "$$dir" != "$$p" || dir=.; \
51956
 
+         echo "rm -f \"$${dir}/so_locations\""; \
51957
 
+         rm -f "$${dir}/so_locations"; \
51958
 
+       done
51959
 
+libsieve_ext_date.la: $(libsieve_ext_date_la_OBJECTS) $(libsieve_ext_date_la_DEPENDENCIES) 
51960
 
+       $(LINK)  $(libsieve_ext_date_la_OBJECTS) $(libsieve_ext_date_la_LIBADD) $(LIBS)
51961
 
+
51962
 
+mostlyclean-compile:
51963
 
+       -rm -f *.$(OBJEXT)
51964
 
+
51965
 
+distclean-compile:
51966
 
+       -rm -f *.tab.c
51967
 
+
51968
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-date-common.Plo@am__quote@
51969
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-date.Plo@am__quote@
51970
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tst-date.Plo@am__quote@
51971
 
+
51972
 
+.c.o:
51973
 
+@am__fastdepCC_TRUE@   $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
51974
 
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
51975
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
51976
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
51977
 
+@am__fastdepCC_FALSE@  $(COMPILE) -c $<
51978
 
+
51979
 
+.c.obj:
51980
 
+@am__fastdepCC_TRUE@   $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
51981
 
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
51982
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
51983
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
51984
 
+@am__fastdepCC_FALSE@  $(COMPILE) -c `$(CYGPATH_W) '$<'`
51985
 
+
51986
 
+.c.lo:
51987
 
+@am__fastdepCC_TRUE@   $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
51988
 
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
51989
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
51990
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
51991
 
+@am__fastdepCC_FALSE@  $(LTCOMPILE) -c -o $@ $<
51992
 
+
51993
 
+mostlyclean-libtool:
51994
 
+       -rm -f *.lo
51995
 
+
51996
 
+clean-libtool:
51997
 
+       -rm -rf .libs _libs
51998
 
+
51999
 
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
52000
 
+       list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
52001
 
+       unique=`for i in $$list; do \
52002
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
52003
 
+         done | \
52004
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
52005
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
52006
 
+       mkid -fID $$unique
52007
 
+tags: TAGS
52008
 
+
52009
 
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
52010
 
+               $(TAGS_FILES) $(LISP)
52011
 
+       tags=; \
52012
 
+       here=`pwd`; \
52013
 
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
52014
 
+       unique=`for i in $$list; do \
52015
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
52016
 
+         done | \
52017
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
52018
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
52019
 
+       if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
52020
 
+         test -n "$$unique" || unique=$$empty_fix; \
52021
 
+         $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
52022
 
+           $$tags $$unique; \
52023
 
+       fi
52024
 
+ctags: CTAGS
52025
 
+CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
52026
 
+               $(TAGS_FILES) $(LISP)
52027
 
+       tags=; \
52028
 
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
52029
 
+       unique=`for i in $$list; do \
52030
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
52031
 
+         done | \
52032
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
52033
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
52034
 
+       test -z "$(CTAGS_ARGS)$$tags$$unique" \
52035
 
+         || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
52036
 
+            $$tags $$unique
52037
 
+
52038
 
+GTAGS:
52039
 
+       here=`$(am__cd) $(top_builddir) && pwd` \
52040
 
+         && cd $(top_srcdir) \
52041
 
+         && gtags -i $(GTAGS_ARGS) $$here
52042
 
+
52043
 
+distclean-tags:
52044
 
+       -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
52045
 
+
52046
 
+distdir: $(DISTFILES)
52047
 
+       @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
52048
 
+       topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
52049
 
+       list='$(DISTFILES)'; \
52050
 
+         dist_files=`for file in $$list; do echo $$file; done | \
52051
 
+         sed -e "s|^$$srcdirstrip/||;t" \
52052
 
+             -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
52053
 
+       case $$dist_files in \
52054
 
+         */*) $(MKDIR_P) `echo "$$dist_files" | \
52055
 
+                          sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
52056
 
+                          sort -u` ;; \
52057
 
+       esac; \
52058
 
+       for file in $$dist_files; do \
52059
 
+         if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
52060
 
+         if test -d $$d/$$file; then \
52061
 
+           dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
52062
 
+           if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
52063
 
+             cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
52064
 
+           fi; \
52065
 
+           cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
52066
 
+         else \
52067
 
+           test -f $(distdir)/$$file \
52068
 
+           || cp -p $$d/$$file $(distdir)/$$file \
52069
 
+           || exit 1; \
52070
 
+         fi; \
52071
 
+       done
52072
 
+check-am: all-am
52073
 
+check: check-am
52074
 
+all-am: Makefile $(LTLIBRARIES) $(HEADERS)
52075
 
+installdirs:
52076
 
+install: install-am
52077
 
+install-exec: install-exec-am
52078
 
+install-data: install-data-am
52079
 
+uninstall: uninstall-am
52080
 
+
52081
 
+install-am: all-am
52082
 
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
52083
 
+
52084
 
+installcheck: installcheck-am
52085
 
+install-strip:
52086
 
+       $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
52087
 
+         install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
52088
 
+         `test -z '$(STRIP)' || \
52089
 
+           echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
52090
 
+mostlyclean-generic:
52091
 
+
52092
 
+clean-generic:
52093
 
+
52094
 
+distclean-generic:
52095
 
+       -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
52096
 
+
52097
 
+maintainer-clean-generic:
52098
 
+       @echo "This command is intended for maintainers to use"
52099
 
+       @echo "it deletes files that may require special tools to rebuild."
52100
 
+clean: clean-am
52101
 
+
52102
 
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
52103
 
+       mostlyclean-am
52104
 
+
52105
 
+distclean: distclean-am
52106
 
+       -rm -rf ./$(DEPDIR)
52107
 
+       -rm -f Makefile
52108
 
+distclean-am: clean-am distclean-compile distclean-generic \
52109
 
+       distclean-tags
52110
 
+
52111
 
+dvi: dvi-am
52112
 
+
52113
 
+dvi-am:
52114
 
+
52115
 
+html: html-am
52116
 
+
52117
 
+info: info-am
52118
 
+
52119
 
+info-am:
52120
 
+
52121
 
+install-data-am:
52122
 
+
52123
 
+install-dvi: install-dvi-am
52124
 
+
52125
 
+install-exec-am:
52126
 
+
52127
 
+install-html: install-html-am
52128
 
+
52129
 
+install-info: install-info-am
52130
 
+
52131
 
+install-man:
52132
 
+
52133
 
+install-pdf: install-pdf-am
52134
 
+
52135
 
+install-ps: install-ps-am
52136
 
+
52137
 
+installcheck-am:
52138
 
+
52139
 
+maintainer-clean: maintainer-clean-am
52140
 
+       -rm -rf ./$(DEPDIR)
52141
 
+       -rm -f Makefile
52142
 
+maintainer-clean-am: distclean-am maintainer-clean-generic
52143
 
+
52144
 
+mostlyclean: mostlyclean-am
52145
 
+
52146
 
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
52147
 
+       mostlyclean-libtool
52148
 
+
52149
 
+pdf: pdf-am
52150
 
+
52151
 
+pdf-am:
52152
 
+
52153
 
+ps: ps-am
52154
 
+
52155
 
+ps-am:
52156
 
+
52157
 
+uninstall-am:
52158
 
+
52159
 
+.MAKE: install-am install-strip
52160
 
+
52161
 
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
52162
 
+       clean-libtool clean-noinstLTLIBRARIES ctags distclean \
52163
 
+       distclean-compile distclean-generic distclean-libtool \
52164
 
+       distclean-tags distdir dvi dvi-am html html-am info info-am \
52165
 
+       install install-am install-data install-data-am install-dvi \
52166
 
+       install-dvi-am install-exec install-exec-am install-html \
52167
 
+       install-html-am install-info install-info-am install-man \
52168
 
+       install-pdf install-pdf-am install-ps install-ps-am \
52169
 
+       install-strip installcheck installcheck-am installdirs \
52170
 
+       maintainer-clean maintainer-clean-generic mostlyclean \
52171
 
+       mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
52172
 
+       pdf pdf-am ps ps-am tags uninstall uninstall-am
52173
 
+
52174
 
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
52175
 
+# Otherwise a system limit (for SysV at least) may be exceeded.
52176
 
+.NOEXPORT:
52177
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/date/tst-date.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/date/tst-date.c
52178
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/date/tst-date.c        1970-01-01 01:00:00.000000000 +0100
52179
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/date/tst-date.c 2009-08-21 00:52:15.000000000 +0200
52180
 
@@ -0,0 +1,546 @@
52181
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
52182
 
+ */
52183
 
+
52184
 
+#include "lib.h"
52185
 
+#include "str-sanitize.h"
52186
 
+#include "message-date.h"
52187
 
+
52188
 
+#include "sieve-common.h"
52189
 
+#include "sieve-commands.h"
52190
 
+#include "sieve-code.h"
52191
 
+#include "sieve-comparators.h"
52192
 
+#include "sieve-match-types.h"
52193
 
+#include "sieve-address-parts.h"
52194
 
+#include "sieve-validator.h"
52195
 
+#include "sieve-generator.h"
52196
 
+#include "sieve-interpreter.h"
52197
 
+#include "sieve-dump.h"
52198
 
+#include "sieve-match.h"
52199
 
+
52200
 
+#include "ext-date-common.h"
52201
 
+
52202
 
+#include <time.h>
52203
 
+
52204
 
+/*
52205
 
+ * Tests
52206
 
+ */
52207
 
+
52208
 
+static bool tst_date_validate
52209
 
+       (struct sieve_validator *valdtr, struct sieve_command_context *tst);
52210
 
+static bool tst_date_generate
52211
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx);
52212
 
52213
 
+/* Address test
52214
 
+ *
52215
 
+ * Syntax:
52216
 
+ *    date [<":zone" <time-zone: string>> / ":originalzone"]
52217
 
+ *         [COMPARATOR] [MATCH-TYPE] <header-name: string>
52218
 
+ *         <date-part: string> <key-list: string-list>
52219
 
+ */
52220
 
+
52221
 
+static bool tst_date_registered
52222
 
+       (struct sieve_validator *valdtr, struct sieve_command_registration *cmd_reg);
52223
 
+
52224
 
+const struct sieve_command date_test = { 
52225
 
+       "date", 
52226
 
+       SCT_TEST, 
52227
 
+       3, 0, FALSE, FALSE,
52228
 
+       tst_date_registered,
52229
 
+       NULL, 
52230
 
+       tst_date_validate, 
52231
 
+       tst_date_generate, 
52232
 
+       NULL 
52233
 
+};
52234
 
+
52235
 
+/* Currentdate test
52236
 
+ * 
52237
 
+ * Syntax:
52238
 
+ *    currentdate [":zone" <time-zone: string>]
52239
 
+ *                [COMPARATOR] [MATCH-TYPE]
52240
 
+ *                <date-part: string> <key-list: string-list>
52241
 
+ */
52242
 
+
52243
 
+static bool tst_currentdate_registered
52244
 
+       (struct sieve_validator *valdtr, struct sieve_command_registration *cmd_reg);
52245
 
+
52246
 
+const struct sieve_command currentdate_test = { 
52247
 
+       "currentdate", 
52248
 
+       SCT_TEST, 
52249
 
+       2, 0, FALSE, FALSE,
52250
 
+       tst_currentdate_registered,
52251
 
+       NULL, 
52252
 
+       tst_date_validate, 
52253
 
+       tst_date_generate, 
52254
 
+       NULL 
52255
 
+};
52256
 
+
52257
 
+/* 
52258
 
+ * Tagged arguments 
52259
 
+ */
52260
 
+
52261
 
+/* Forward declarations */
52262
 
+
52263
 
+static bool tag_zone_validate
52264
 
+       (struct sieve_validator *validator, struct sieve_ast_argument **arg,
52265
 
+               struct sieve_command_context *cmd);
52266
 
+static bool tag_zone_generate
52267
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg,
52268
 
+               struct sieve_command_context *cmd);
52269
 
+
52270
 
+/* Argument objects */
52271
 
+
52272
 
+static const struct sieve_argument date_zone_tag = {
52273
 
+       "zone",
52274
 
+       NULL, NULL,
52275
 
+       tag_zone_validate,
52276
 
+       NULL,
52277
 
+       tag_zone_generate
52278
 
+};
52279
 
+
52280
 
+static const struct sieve_argument date_originalzone_tag = {
52281
 
+       "originalzone",
52282
 
+       NULL, NULL,
52283
 
+       tag_zone_validate,
52284
 
+       NULL,
52285
 
+       tag_zone_generate
52286
 
+};
52287
 
+
52288
 
+/* 
52289
 
+ * Address operation 
52290
 
+ */
52291
 
+
52292
 
+static bool tst_date_operation_dump
52293
 
+       (const struct sieve_operation *op, 
52294
 
+               const struct sieve_dumptime_env *denv, sieve_size_t *address);
52295
 
+static int tst_date_operation_execute
52296
 
+       (const struct sieve_operation *op, 
52297
 
+               const struct sieve_runtime_env *renv, sieve_size_t *address);
52298
 
+
52299
 
+const struct sieve_operation date_operation = { 
52300
 
+       "DATE",
52301
 
+       &date_extension,
52302
 
+       EXT_DATE_OPERATION_DATE,
52303
 
+       tst_date_operation_dump, 
52304
 
+       tst_date_operation_execute 
52305
 
+};
52306
 
+
52307
 
+const struct sieve_operation currentdate_operation = { 
52308
 
+       "CURRENTDATE",
52309
 
+       &date_extension,
52310
 
+       EXT_DATE_OPERATION_CURRENTDATE,
52311
 
+       tst_date_operation_dump, 
52312
 
+       tst_date_operation_execute 
52313
 
+};
52314
 
+
52315
 
+/*
52316
 
+ * Optional operands
52317
 
+ */
52318
 
+
52319
 
+enum tst_date_optional {
52320
 
+       OPT_DATE_ZONE = SIEVE_MATCH_OPT_LAST,
52321
 
+       OPT_DATE_LAST
52322
 
+};
52323
 
+
52324
 
+/*
52325
 
+ * Tag implementation
52326
 
+ */
52327
 
+
52328
 
+static bool tag_zone_validate
52329
 
+(struct sieve_validator *validator, struct sieve_ast_argument **arg,
52330
 
+    struct sieve_command_context *cmd)
52331
 
+{
52332
 
+       struct sieve_ast_argument *tag = *arg;
52333
 
+
52334
 
+       if ( (bool) cmd->data ) {
52335
 
+               if ( cmd->command == &date_test ) {
52336
 
+                       sieve_argument_validate_error(validator, *arg,
52337
 
+                               "multiple :zone or :originalzone arguments specified for "
52338
 
+                               "the currentdate test");
52339
 
+               } else {
52340
 
+                       sieve_argument_validate_error(validator, *arg,
52341
 
+                               "multiple :zone arguments specified for the currentdate test");
52342
 
+               }
52343
 
+               return FALSE;
52344
 
+       }
52345
 
+
52346
 
+       /* Skip tag */
52347
 
+       *arg = sieve_ast_argument_next(*arg);
52348
 
+
52349
 
+       /* :content tag has a string-list argument */
52350
 
+       if ( tag->argument == &date_zone_tag ) {
52351
 
+
52352
 
+               /* Check syntax:
52353
 
+                *   :zone <time-zone: string>
52354
 
+                */
52355
 
+               if ( !sieve_validate_tag_parameter
52356
 
+                       (validator, cmd, tag, *arg, SAAT_STRING) ) {
52357
 
+                       return FALSE;
52358
 
+               }
52359
 
+
52360
 
+               /* Check it */
52361
 
+               if ( sieve_argument_is_string_literal(*arg) ) {
52362
 
+                       const char *zone = sieve_ast_argument_strc(*arg);
52363
 
+       
52364
 
+                       if ( !ext_date_parse_timezone(zone, NULL) ) {
52365
 
+                               sieve_argument_validate_warning(validator, *arg,
52366
 
+                                       "specified :zone argument '%s' is not a valid timezone",
52367
 
+                                       str_sanitize(zone, 40));
52368
 
+                       }               
52369
 
+               }
52370
 
+       
52371
 
+               /* Assign tag parameters */
52372
 
+               tag->parameters = *arg;
52373
 
+               *arg = sieve_ast_arguments_detach(*arg,1);
52374
 
+       } 
52375
 
+
52376
 
+       cmd->data = (void *) TRUE;
52377
 
+
52378
 
+       return TRUE;
52379
 
+}
52380
 
+
52381
 
+/* 
52382
 
+ * Test registration 
52383
 
+ */
52384
 
+
52385
 
+static bool tst_date_registered
52386
 
+(struct sieve_validator *valdtr, struct sieve_command_registration *cmd_reg) 
52387
 
+{
52388
 
+       sieve_comparators_link_tag(valdtr, cmd_reg, SIEVE_MATCH_OPT_COMPARATOR);
52389
 
+       sieve_match_types_link_tags(valdtr, cmd_reg, SIEVE_MATCH_OPT_MATCH_TYPE);
52390
 
+
52391
 
+       sieve_validator_register_tag
52392
 
+               (valdtr, cmd_reg, &date_zone_tag, OPT_DATE_ZONE);
52393
 
+       sieve_validator_register_tag
52394
 
+               (valdtr, cmd_reg, &date_originalzone_tag, OPT_DATE_ZONE);
52395
 
+
52396
 
+       return TRUE;
52397
 
+}
52398
 
+
52399
 
+static bool tst_currentdate_registered
52400
 
+(struct sieve_validator *valdtr, struct sieve_command_registration *cmd_reg) 
52401
 
+{
52402
 
+       sieve_comparators_link_tag(valdtr, cmd_reg, SIEVE_MATCH_OPT_COMPARATOR);
52403
 
+       sieve_match_types_link_tags(valdtr, cmd_reg, SIEVE_MATCH_OPT_MATCH_TYPE);
52404
 
+
52405
 
+       sieve_validator_register_tag
52406
 
+               (valdtr, cmd_reg, &date_zone_tag, OPT_DATE_ZONE);
52407
 
+
52408
 
+       return TRUE;
52409
 
+}
52410
 
+
52411
 
+/* 
52412
 
+ * Validation 
52413
 
+ */
52414
 
52415
 
+static bool tst_date_validate
52416
 
+       (struct sieve_validator *valdtr, struct sieve_command_context *tst) 
52417
 
+{
52418
 
+       struct sieve_ast_argument *arg = tst->first_positional;
52419
 
+       unsigned int arg_offset = 0 ;
52420
 
+               
52421
 
+       /* Check header name */
52422
 
+
52423
 
+       if ( tst->command == &date_test ) {
52424
 
+               arg_offset = 1;
52425
 
+
52426
 
+               if ( !sieve_validate_positional_argument
52427
 
+                       (valdtr, tst, arg, "header name", 1, SAAT_STRING) ) {
52428
 
+                       return FALSE;
52429
 
+               }
52430
 
+       
52431
 
+               if ( !sieve_validator_argument_activate(valdtr, tst, arg, FALSE) )
52432
 
+                       return FALSE;
52433
 
+
52434
 
+               if ( !sieve_command_verify_headers_argument(valdtr, arg) )
52435
 
+           return FALSE;
52436
 
+
52437
 
+               arg = sieve_ast_argument_next(arg);
52438
 
+       }
52439
 
+
52440
 
+       /* Check date part */
52441
 
+
52442
 
+       if ( !sieve_validate_positional_argument
52443
 
+               (valdtr, tst, arg, "date part", arg_offset + 1, SAAT_STRING) ) {
52444
 
+               return FALSE;
52445
 
+       }
52446
 
+       
52447
 
+       if ( !sieve_validator_argument_activate(valdtr, tst, arg, FALSE) )
52448
 
+               return FALSE;
52449
 
+
52450
 
+       arg = sieve_ast_argument_next(arg);
52451
 
+
52452
 
+       /* Check key list */
52453
 
+               
52454
 
+       if ( !sieve_validate_positional_argument
52455
 
+               (valdtr, tst, arg, "key list", arg_offset + 2, SAAT_STRING_LIST) ) {
52456
 
+               return FALSE;
52457
 
+       }
52458
 
+
52459
 
+       if ( !sieve_validator_argument_activate(valdtr, tst, arg, FALSE) )
52460
 
+               return FALSE;
52461
 
+       
52462
 
+       /* Validate the key argument to a specified match type */
52463
 
+       return sieve_match_type_validate
52464
 
+               (valdtr, tst, arg, &is_match_type, &i_ascii_casemap_comparator); 
52465
 
+}
52466
 
+
52467
 
+/* 
52468
 
+ * Code generation 
52469
 
+ */
52470
 
+
52471
 
+static bool tst_date_generate
52472
 
+(const struct sieve_codegen_env *cgenv, struct sieve_command_context *tst) 
52473
 
+{
52474
 
+       if ( tst->command == &date_test )
52475
 
+               sieve_operation_emit_code(cgenv->sbin, &date_operation);
52476
 
+       else if ( tst->command == &currentdate_test )
52477
 
+               sieve_operation_emit_code(cgenv->sbin, &currentdate_operation);
52478
 
+       else
52479
 
+               i_unreached();
52480
 
+
52481
 
+       /* Generate arguments */        
52482
 
+       return sieve_generate_arguments(cgenv, tst, NULL);
52483
 
+}
52484
 
+
52485
 
+static bool tag_zone_generate
52486
 
+(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg,
52487
 
+    struct sieve_command_context *cmd)
52488
 
+{
52489
 
+       struct sieve_ast_argument *param = arg->parameters;
52490
 
+
52491
 
+       if ( param == NULL ) {
52492
 
+               sieve_opr_omitted_emit(cgenv->sbin);
52493
 
+               return TRUE;
52494
 
+       }
52495
 
+
52496
 
+       if ( param->argument != NULL && param->argument->generate != NULL )
52497
 
+               return param->argument->generate(cgenv, param, cmd);
52498
 
+
52499
 
+       return FALSE;   
52500
 
+}
52501
 
+
52502
 
+/* 
52503
 
+ * Code dump 
52504
 
+ */
52505
 
+
52506
 
+static bool tst_date_operation_dump
52507
 
+(const struct sieve_operation *op,     
52508
 
+       const struct sieve_dumptime_env *denv, sieve_size_t *address)
52509
 
+{
52510
 
+       int opt_code = 0;
52511
 
+       const struct sieve_operand *operand;
52512
 
+
52513
 
+       sieve_code_dumpf(denv, "%s", op->mnemonic);
52514
 
+       sieve_code_descend(denv);
52515
 
+       
52516
 
+       /* Handle any optional arguments */
52517
 
+  do {
52518
 
+               if ( !sieve_match_dump_optional_operands(denv, address, &opt_code) )
52519
 
+                       return FALSE;
52520
 
+
52521
 
+               switch ( opt_code ) {
52522
 
+               case SIEVE_MATCH_OPT_END:
52523
 
+                       break;
52524
 
+               case OPT_DATE_ZONE:
52525
 
+                       operand = sieve_operand_read(denv->sbin, address);
52526
 
+                       if ( operand == NULL ) {
52527
 
+                               sieve_code_dumpf(denv, "ERROR: INVALID OPERAND");
52528
 
+                               return FALSE;
52529
 
+                       }                               
52530
 
+
52531
 
+                       if ( sieve_operand_is_omitted(operand) ) {
52532
 
+                               sieve_code_dumpf(denv, "zone: ORIGINAL");
52533
 
+                       } else {
52534
 
+                               if ( !sieve_opr_string_dump_data
52535
 
+                                       (denv, operand, address, "zone") )
52536
 
+                                       return FALSE;
52537
 
+                       }
52538
 
+                       break;
52539
 
+    default:
52540
 
+                       return FALSE;
52541
 
+               }
52542
 
+       } while ( opt_code != SIEVE_MATCH_OPT_END );
52543
 
+
52544
 
+       if ( op == &date_operation &&
52545
 
+               !sieve_opr_string_dump(denv, address, "header name") )
52546
 
+               return FALSE;
52547
 
+
52548
 
+       return
52549
 
+               sieve_opr_string_dump(denv, address, "date part") && 
52550
 
+               sieve_opr_stringlist_dump(denv, address, "key list");
52551
 
+}
52552
 
+
52553
 
+/* 
52554
 
+ * Code execution 
52555
 
+ */
52556
 
+
52557
 
+static int tst_date_operation_execute
52558
 
+(const struct sieve_operation *op, 
52559
 
+       const struct sieve_runtime_env *renv, sieve_size_t *address)
52560
 
+{      
52561
 
+       bool result = TRUE, zone_specified = FALSE, got_date = FALSE, matched = FALSE;
52562
 
+       int opt_code = 0;
52563
 
+       const struct sieve_message_data *msgdata = renv->msgdata;
52564
 
+       const struct sieve_comparator *cmp = &i_ascii_casemap_comparator;
52565
 
+       const struct sieve_match_type *mtch = &is_match_type;
52566
 
+       const struct sieve_operand *operand;
52567
 
+       struct sieve_match_context *mctx;
52568
 
+       string_t *header_name = NULL, *date_part = NULL, *zone = NULL;
52569
 
+       struct sieve_coded_stringlist *key_list;
52570
 
+       time_t date_value, local_time;
52571
 
+       struct tm *date_tm;
52572
 
+       const char *part_value;
52573
 
+       int local_zone = 0, original_zone = 0, wanted_zone = 0;
52574
 
+       int ret;
52575
 
+       
52576
 
+       /* Read optional operands */
52577
 
+       do {
52578
 
+               if ( (ret=sieve_match_read_optional_operands
52579
 
+                       (renv, address, &opt_code, &cmp, &mtch)) <= 0 )
52580
 
+                       return ret;
52581
 
+
52582
 
+               switch ( opt_code ) {
52583
 
+               case SIEVE_MATCH_OPT_END:
52584
 
+                       break;
52585
 
+               case OPT_DATE_ZONE:
52586
 
+                       operand = sieve_operand_read(renv->sbin, address);
52587
 
+                       if ( operand == NULL ) {
52588
 
+                               sieve_runtime_trace_error(renv, "invalid operand");
52589
 
+                               return SIEVE_EXEC_BIN_CORRUPT;
52590
 
+                       }
52591
 
+
52592
 
+                       if ( !sieve_operand_is_omitted(operand) ) {
52593
 
+                               if ( !sieve_opr_string_read_data
52594
 
+                                       (renv, operand, address, &zone) ) {
52595
 
+                                       sieve_runtime_trace_error(renv, "invalid zone operand");
52596
 
+                                       return SIEVE_EXEC_BIN_CORRUPT;
52597
 
+                               }
52598
 
+                       }
52599
 
+
52600
 
+                       zone_specified = TRUE;
52601
 
+                       break;
52602
 
+               default:
52603
 
+                       sieve_runtime_trace_error(renv, "unknown optional operand");
52604
 
+                       return SIEVE_EXEC_BIN_CORRUPT;
52605
 
+               }
52606
 
+       } while ( opt_code != SIEVE_MATCH_OPT_END );
52607
 
+
52608
 
+
52609
 
+       if ( op == &date_operation ) {
52610
 
+               /* Read header name */
52611
 
+               if ( !sieve_opr_string_read(renv, address, &header_name) ) {
52612
 
+                       sieve_runtime_trace_error(renv, "invalid header-name operand");
52613
 
+                       return SIEVE_EXEC_BIN_CORRUPT;
52614
 
+               }
52615
 
+       }
52616
 
+
52617
 
+       /* Read date part */
52618
 
+       if ( !sieve_opr_string_read(renv, address, &date_part) ) {
52619
 
+               sieve_runtime_trace_error(renv, "invalid date-part operand");
52620
 
+               return SIEVE_EXEC_BIN_CORRUPT;
52621
 
+       }
52622
 
+               
52623
 
+       /* Read key-list */
52624
 
+       if ( (key_list=sieve_opr_stringlist_read(renv, address)) == NULL ) {
52625
 
+               sieve_runtime_trace_error(renv, "invalid key-list operand");
52626
 
+               return SIEVE_EXEC_BIN_CORRUPT;
52627
 
+       }
52628
 
+
52629
 
+       /* Perform test */
52630
 
+
52631
 
+       sieve_runtime_trace(renv, "%s test", op->mnemonic);
52632
 
+
52633
 
+       /* Get the date value */
52634
 
+
52635
 
+       local_time = ext_date_get_current_date(renv, &local_zone);
52636
 
+
52637
 
+       if ( op ==      &date_operation ) {
52638
 
+               const char *header_value;
52639
 
+               const char *date_string;
52640
 
+
52641
 
+               /* Get date from the message */
52642
 
+
52643
 
+               /* Read first header
52644
 
+                *   NOTE: need something for index extension to hook into some time. 
52645
 
+                */
52646
 
+               if ( (ret=mail_get_first_header
52647
 
+                       (msgdata->mail, str_c(header_name), &header_value)) > 0 ) {
52648
 
+
52649
 
+                       /* Extract the date string value */
52650
 
+                       date_string = strrchr(header_value, ';');
52651
 
+                       if ( date_string == NULL )
52652
 
+                               /* Direct header value */
52653
 
+                               date_string = header_value;
52654
 
+                       else {
52655
 
+                               /* Delimited by ';', e.g. a Received: header */
52656
 
+                               date_string++; 
52657
 
+                       }
52658
 
+
52659
 
+                       /* Parse the date value */
52660
 
+                       if ( message_date_parse((const unsigned char *) date_string,
52661
 
+                               strlen(date_string), &date_value, &original_zone) ) {
52662
 
+                               got_date = TRUE;
52663
 
+                       }
52664
 
+               }
52665
 
+       } else if ( op == &currentdate_operation ) {
52666
 
+               /* Use time stamp recorded at the time the script first started */
52667
 
+
52668
 
+               date_value = local_time;
52669
 
+               original_zone = local_zone;
52670
 
+               got_date = TRUE;
52671
 
+
52672
 
+       } else {
52673
 
+               i_unreached();
52674
 
+       }
52675
 
+
52676
 
+       if ( got_date ) {
52677
 
+               /* Apply wanted timezone */
52678
 
+
52679
 
+               if ( !zone_specified )
52680
 
+                       wanted_zone = local_zone;
52681
 
+               else if ( zone == NULL 
52682
 
+                       || !ext_date_parse_timezone(str_c(zone), &wanted_zone) ) {
52683
 
+
52684
 
+                       /* FIXME: warn about parse failures */
52685
 
+                       wanted_zone = original_zone;
52686
 
+               }
52687
 
+
52688
 
+               date_value += wanted_zone * 60;
52689
 
+
52690
 
+               /* Convert timestamp to struct tm */
52691
 
+
52692
 
+               if ( (date_tm=gmtime(&date_value)) == NULL ) {
52693
 
+                       got_date = FALSE;
52694
 
+               } else {
52695
 
+                       /* Extract the date part */
52696
 
+                       part_value = ext_date_part_extract
52697
 
+                               (str_c(date_part), date_tm, wanted_zone);
52698
 
+               }
52699
 
+       }
52700
 
+
52701
 
+       /* Initialize match */
52702
 
+       mctx = sieve_match_begin(renv->interp, mtch, cmp, NULL, key_list);      
52703
 
+       
52704
 
+       if ( got_date && part_value != NULL ) {         
52705
 
+               /* Match value */
52706
 
+               if ( (ret=sieve_match_value(mctx, part_value, strlen(part_value))) < 0 )
52707
 
+                       result = FALSE;
52708
 
+               else
52709
 
+                       matched = ret > 0;
52710
 
+       }
52711
 
+
52712
 
+       /* Finish match */
52713
 
+       if ( (ret=sieve_match_end(&mctx)) < 0 ) 
52714
 
+               result = FALSE;
52715
 
+       else
52716
 
+               matched = ( ret > 0 || matched );
52717
 
+       
52718
 
+       /* Set test result for subsequent conditional jump */
52719
 
+       if ( result ) {
52720
 
+               sieve_interpreter_set_test_result(renv->interp, matched);
52721
 
+               return SIEVE_EXEC_OK;
52722
 
+       }       
52723
 
+
52724
 
+       sieve_runtime_trace_error(renv, "invalid string-list item");
52725
 
+       return SIEVE_EXEC_BIN_CORRUPT;
52726
 
+}
52727
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/enotify/cmd-notify.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/enotify/cmd-notify.c
52728
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/enotify/cmd-notify.c   1970-01-01 01:00:00.000000000 +0100
52729
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/enotify/cmd-notify.c    2009-07-21 02:40:42.000000000 +0200
52730
 
@@ -0,0 +1,597 @@
52731
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
52732
 
+ */
52733
 
+
52734
 
+#include "lib.h"
52735
 
+
52736
 
+#include "sieve-common.h"
52737
 
+#include "sieve-code.h"
52738
 
+#include "sieve-extensions.h"
52739
 
+#include "sieve-commands.h"
52740
 
+#include "sieve-actions.h"
52741
 
+#include "sieve-validator.h"
52742
 
+#include "sieve-generator.h"
52743
 
+#include "sieve-interpreter.h"
52744
 
+#include "sieve-dump.h"
52745
 
+#include "sieve-result.h"
52746
 
+
52747
 
+#include "ext-enotify-common.h"
52748
 
+
52749
 
+/* 
52750
 
+ * Forward declarations 
52751
 
+ */
52752
 
52753
 
+static const struct sieve_argument notify_importance_tag;
52754
 
+static const struct sieve_argument notify_from_tag;
52755
 
+static const struct sieve_argument notify_options_tag;
52756
 
+static const struct sieve_argument notify_message_tag;
52757
 
+
52758
 
+/* 
52759
 
+ * Notify command 
52760
 
+ *     
52761
 
+ * Syntax: 
52762
 
+ *    notify [":from" string]
52763
 
+ *           [":importance" <"1" / "2" / "3">]
52764
 
+ *           [":options" string-list]
52765
 
+ *           [":message" string]
52766
 
+ *           <method: string>
52767
 
+ */
52768
 
+
52769
 
+static bool cmd_notify_registered
52770
 
+       (struct sieve_validator *valdtr, 
52771
 
+               struct sieve_command_registration *cmd_reg);
52772
 
+static bool cmd_notify_pre_validate
52773
 
+       (struct sieve_validator *validator, struct sieve_command_context *cmd);
52774
 
+static bool cmd_notify_validate
52775
 
+       (struct sieve_validator *valdtr, struct sieve_command_context *cmd);
52776
 
+static bool cmd_notify_generate
52777
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx);
52778
 
+
52779
 
+const struct sieve_command notify_command = { 
52780
 
+       "notify",
52781
 
+       SCT_COMMAND, 
52782
 
+       1, 0, FALSE, FALSE, 
52783
 
+       cmd_notify_registered,
52784
 
+       cmd_notify_pre_validate,
52785
 
+       cmd_notify_validate, 
52786
 
+       cmd_notify_generate, 
52787
 
+       NULL 
52788
 
+};
52789
 
+
52790
 
+/*
52791
 
+ * Notify command tags
52792
 
+ */
52793
 
+
52794
 
+/* Forward declarations */
52795
 
+
52796
 
+static bool cmd_notify_validate_string_tag
52797
 
+       (struct sieve_validator *valdtr, struct sieve_ast_argument **arg, 
52798
 
+               struct sieve_command_context *cmd);
52799
 
+static bool cmd_notify_validate_stringlist_tag
52800
 
+       (struct sieve_validator *valdtr, struct sieve_ast_argument **arg, 
52801
 
+               struct sieve_command_context *cmd);
52802
 
+static bool cmd_notify_validate_importance_tag
52803
 
+       (struct sieve_validator *valdtr, struct sieve_ast_argument **arg, 
52804
 
+               struct sieve_command_context *cmd);
52805
 
+
52806
 
+/* Argument objects */
52807
 
+
52808
 
+static const struct sieve_argument notify_from_tag = { 
52809
 
+       "from", 
52810
 
+       NULL, NULL,
52811
 
+       cmd_notify_validate_string_tag, 
52812
 
+       NULL, NULL 
52813
 
+};
52814
 
+
52815
 
+static const struct sieve_argument notify_options_tag = { 
52816
 
+       "options", 
52817
 
+       NULL, NULL,
52818
 
+       cmd_notify_validate_stringlist_tag, 
52819
 
+       NULL, NULL 
52820
 
+};
52821
 
+
52822
 
+static const struct sieve_argument notify_message_tag = { 
52823
 
+       "message", 
52824
 
+       NULL, NULL, 
52825
 
+       cmd_notify_validate_string_tag, 
52826
 
+       NULL, NULL 
52827
 
+};
52828
 
+
52829
 
+static const struct sieve_argument notify_importance_tag = { 
52830
 
+       "importance", 
52831
 
+       NULL, NULL,
52832
 
+       cmd_notify_validate_importance_tag, 
52833
 
+       NULL, NULL 
52834
 
+};
52835
 
+
52836
 
+/* 
52837
 
+ * Notify operation 
52838
 
+ */
52839
 
+
52840
 
+static bool cmd_notify_operation_dump
52841
 
+       (const struct sieve_operation *op,      
52842
 
+               const struct sieve_dumptime_env *denv, sieve_size_t *address);
52843
 
+static int cmd_notify_operation_execute
52844
 
+       (const struct sieve_operation *op, 
52845
 
+               const struct sieve_runtime_env *renv, sieve_size_t *address);
52846
 
+
52847
 
+const struct sieve_operation notify_operation = { 
52848
 
+       "NOTIFY",
52849
 
+       &enotify_extension,
52850
 
+       EXT_ENOTIFY_OPERATION_NOTIFY,
52851
 
+       cmd_notify_operation_dump, 
52852
 
+       cmd_notify_operation_execute
52853
 
+};
52854
 
+
52855
 
+/* 
52856
 
+ * Notify action 
52857
 
+ */
52858
 
+
52859
 
+/* Forward declarations */
52860
 
+
52861
 
+static int act_notify_check_duplicate
52862
 
+       (const struct sieve_runtime_env *renv, 
52863
 
+               const struct sieve_action_data *act,
52864
 
+               const struct sieve_action_data *act_other);
52865
 
+static void act_notify_print
52866
 
+       (const struct sieve_action *action, const struct sieve_result_print_env *rpenv,
52867
 
+               void *context, bool *keep);     
52868
 
+static bool act_notify_commit
52869
 
+       (const struct sieve_action *action,     const struct sieve_action_exec_env *aenv, 
52870
 
+               void *tr_context, bool *keep);
52871
 
+
52872
 
+/* Action object */
52873
 
+
52874
 
+const struct sieve_action act_notify = {
52875
 
+       "notify",
52876
 
+       0,
52877
 
+       NULL,
52878
 
+       act_notify_check_duplicate, 
52879
 
+       NULL,
52880
 
+       act_notify_print,
52881
 
+       NULL, NULL,
52882
 
+       act_notify_commit,
52883
 
+       NULL
52884
 
+};
52885
 
+
52886
 
+/*
52887
 
+ * Command validation context
52888
 
+ */
52889
 
52890
 
+struct cmd_notify_context_data {
52891
 
+       struct sieve_ast_argument *from;
52892
 
+       struct sieve_ast_argument *message;
52893
 
+       struct sieve_ast_argument *options;
52894
 
+};
52895
 
+
52896
 
+/* 
52897
 
+ * Tag validation 
52898
 
+ */
52899
 
+
52900
 
+static bool cmd_notify_validate_string_tag
52901
 
+(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, 
52902
 
+       struct sieve_command_context *cmd)
52903
 
+{
52904
 
+       struct sieve_ast_argument *tag = *arg;
52905
 
+       struct cmd_notify_context_data *ctx_data = 
52906
 
+               (struct cmd_notify_context_data *) cmd->data; 
52907
 
+
52908
 
+       /* Detach the tag itself */
52909
 
+       *arg = sieve_ast_arguments_detach(*arg,1);
52910
 
+       
52911
 
+       /* Check syntax:
52912
 
+        *   :from <string>
52913
 
+        *   :message <string>
52914
 
+        */
52915
 
+       if ( !sieve_validate_tag_parameter(valdtr, cmd, tag, *arg, SAAT_STRING) )
52916
 
+               return FALSE;
52917
 
+
52918
 
+       if ( tag->argument == &notify_from_tag ) {
52919
 
+               ctx_data->from = *arg;
52920
 
+               
52921
 
+               /* Skip parameter */
52922
 
+               *arg = sieve_ast_argument_next(*arg);
52923
 
+               
52924
 
+       } else if ( tag->argument == &notify_message_tag ) {
52925
 
+               ctx_data->message = *arg;
52926
 
+
52927
 
+               /* Skip parameter */
52928
 
+               *arg = sieve_ast_argument_next(*arg);   
52929
 
+       }
52930
 
+                       
52931
 
+       return TRUE;
52932
 
+}
52933
 
+
52934
 
+static bool cmd_notify_validate_stringlist_tag
52935
 
+(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, 
52936
 
+       struct sieve_command_context *cmd)
52937
 
+{
52938
 
+       struct sieve_ast_argument *tag = *arg;
52939
 
+       struct cmd_notify_context_data *ctx_data = 
52940
 
+               (struct cmd_notify_context_data *) cmd->data; 
52941
 
+
52942
 
+       /* Detach the tag itself */
52943
 
+       *arg = sieve_ast_arguments_detach(*arg,1);
52944
 
+       
52945
 
+       /* Check syntax:
52946
 
+        *   :options string-list
52947
 
+        */
52948
 
+       if ( !sieve_validate_tag_parameter(valdtr, cmd, tag, *arg, SAAT_STRING_LIST) ) 
52949
 
+               return FALSE;
52950
 
+               
52951
 
+       /* Assign context */
52952
 
+       ctx_data->options = *arg;       
52953
 
+       
52954
 
+       /* Skip parameter */
52955
 
+       *arg = sieve_ast_argument_next(*arg);
52956
 
+
52957
 
+       return TRUE;
52958
 
+}
52959
 
+
52960
 
+static bool cmd_notify_validate_importance_tag
52961
 
+(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, 
52962
 
+       struct sieve_command_context *cmd ATTR_UNUSED)
52963
 
+{
52964
 
+       const struct sieve_ast_argument *tag = *arg;
52965
 
+       const char *impstr;
52966
 
+
52967
 
+       /* Detach the tag itself */
52968
 
+       *arg = sieve_ast_arguments_detach(*arg,1);
52969
 
+
52970
 
+       /* Check syntax: 
52971
 
+        *   :importance <"1" / "2" / "3">
52972
 
+        */
52973
 
+
52974
 
+       if ( sieve_ast_argument_type(*arg) != SAAT_STRING ) {
52975
 
+               /* Not a string */
52976
 
+               sieve_argument_validate_error(valdtr, *arg, 
52977
 
+                       "the :importance tag for the notify command requires a string parameter, "
52978
 
+                       "but %s was found", sieve_ast_argument_name(*arg));
52979
 
+               return FALSE;
52980
 
+       }
52981
 
+
52982
 
+       impstr = sieve_ast_argument_strc(*arg);
52983
 
+
52984
 
+       if ( impstr[0] < '1' || impstr[0]  > '3' || impstr[1] != '\0' ) {
52985
 
+               /* Invalid importance */
52986
 
+               sieve_argument_validate_error(valdtr, *arg, 
52987
 
+                       "invalid :importance value for notify command: %s", impstr);
52988
 
+               return FALSE;
52989
 
+       } 
52990
 
+
52991
 
+       sieve_ast_argument_number_substitute(*arg, impstr[0] - '0');
52992
 
+       (*arg)->arg_id_code = tag->arg_id_code;
52993
 
+       (*arg)->argument = &number_argument;
52994
 
+
52995
 
+       /* Skip parameter */
52996
 
+       *arg = sieve_ast_argument_next(*arg);
52997
 
+                       
52998
 
+       return TRUE;
52999
 
+}
53000
 
+
53001
 
+
53002
 
+/* 
53003
 
+ * Command registration 
53004
 
+ */
53005
 
+
53006
 
+static bool cmd_notify_registered
53007
 
+(struct sieve_validator *valdtr, struct sieve_command_registration *cmd_reg) 
53008
 
+{
53009
 
+       sieve_validator_register_tag
53010
 
+               (valdtr, cmd_reg, &notify_importance_tag, CMD_NOTIFY_OPT_IMPORTANCE);   
53011
 
+       sieve_validator_register_tag
53012
 
+               (valdtr, cmd_reg, &notify_from_tag, CMD_NOTIFY_OPT_FROM);       
53013
 
+       sieve_validator_register_tag
53014
 
+               (valdtr, cmd_reg, &notify_options_tag, CMD_NOTIFY_OPT_OPTIONS);         
53015
 
+       sieve_validator_register_tag
53016
 
+               (valdtr, cmd_reg, &notify_message_tag, CMD_NOTIFY_OPT_MESSAGE);         
53017
 
+
53018
 
+       return TRUE;
53019
 
+}
53020
 
+
53021
 
+/* 
53022
 
+ * Command validation 
53023
 
+ */
53024
 
+
53025
 
+static bool cmd_notify_pre_validate
53026
 
+(struct sieve_validator *validator ATTR_UNUSED, 
53027
 
+       struct sieve_command_context *cmd) 
53028
 
+{
53029
 
+       struct cmd_notify_context_data *ctx_data;
53030
 
+       
53031
 
+       /* Assign context */
53032
 
+       ctx_data = p_new(sieve_command_pool(cmd), 
53033
 
+               struct cmd_notify_context_data, 1);
53034
 
+       cmd->data = ctx_data;
53035
 
+
53036
 
+       return TRUE;
53037
 
+}
53038
 
53039
 
+static bool cmd_notify_validate
53040
 
+(struct sieve_validator *valdtr, struct sieve_command_context *cmd) 
53041
 
+{      
53042
 
+       struct sieve_ast_argument *arg = cmd->first_positional;
53043
 
+       struct cmd_notify_context_data *ctx_data = 
53044
 
+               (struct cmd_notify_context_data *) cmd->data; 
53045
 
+
53046
 
+       if ( !sieve_validate_positional_argument
53047
 
+               (valdtr, cmd, arg, "method", 1, SAAT_STRING) ) {
53048
 
+               return FALSE;
53049
 
+       }
53050
 
+       
53051
 
+       if ( !sieve_validator_argument_activate(valdtr, cmd, arg, FALSE) )
53052
 
+               return FALSE;
53053
 
+               
53054
 
+       return ext_enotify_compile_check_arguments
53055
 
+               (valdtr, arg, ctx_data->message, ctx_data->from, ctx_data->options);
53056
 
+}
53057
 
+
53058
 
+/*
53059
 
+ * Code generation
53060
 
+ */
53061
 
53062
 
+static bool cmd_notify_generate
53063
 
+(const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx) 
53064
 
+{               
53065
 
+       sieve_operation_emit_code(cgenv->sbin, &notify_operation);
53066
 
+
53067
 
+       /* Emit source line */
53068
 
+       sieve_code_source_line_emit(cgenv->sbin, sieve_command_source_line(ctx));
53069
 
+
53070
 
+       /* Generate arguments */
53071
 
+       return sieve_generate_arguments(cgenv, ctx, NULL);
53072
 
+}
53073
 
+
53074
 
+/* 
53075
 
+ * Code dump
53076
 
+ */
53077
 
53078
 
+static bool cmd_notify_operation_dump
53079
 
+(const struct sieve_operation *op ATTR_UNUSED,
53080
 
+       const struct sieve_dumptime_env *denv, sieve_size_t *address)
53081
 
+{      
53082
 
+       int opt_code = 1;
53083
 
+       
53084
 
+       sieve_code_dumpf(denv, "NOTIFY");
53085
 
+       sieve_code_descend(denv);       
53086
 
+
53087
 
+       /* Source line */
53088
 
+       if ( !sieve_code_source_line_dump(denv, address) )
53089
 
+               return FALSE;
53090
 
+
53091
 
+       /* Dump optional operands */
53092
 
+       if ( sieve_operand_optional_present(denv->sbin, address) ) {
53093
 
+               while ( opt_code != 0 ) {
53094
 
+                       sieve_code_mark(denv);
53095
 
+                       
53096
 
+                       if ( !sieve_operand_optional_read(denv->sbin, address, &opt_code) ) 
53097
 
+                               return FALSE;
53098
 
+
53099
 
+                       switch ( opt_code ) {
53100
 
+                       case 0:
53101
 
+                               break;
53102
 
+                       case CMD_NOTIFY_OPT_IMPORTANCE:
53103
 
+                               if ( !sieve_opr_number_dump(denv, address, "importance") )
53104
 
+                                       return FALSE;
53105
 
+                               break;
53106
 
+                       case CMD_NOTIFY_OPT_FROM:
53107
 
+                               if ( !sieve_opr_string_dump(denv, address, "from") )
53108
 
+                                       return FALSE;
53109
 
+                               break;
53110
 
+                       case CMD_NOTIFY_OPT_OPTIONS:
53111
 
+                               if ( !sieve_opr_stringlist_dump(denv, address, "options") )
53112
 
+                                       return FALSE;
53113
 
+                               break;
53114
 
+                       case CMD_NOTIFY_OPT_MESSAGE:
53115
 
+                               if ( !sieve_opr_string_dump(denv, address, "message") )
53116
 
+                                       return FALSE;
53117
 
+                               break;
53118
 
+                       default:
53119
 
+                               return FALSE;
53120
 
+                       }
53121
 
+               }
53122
 
+       }
53123
 
+       
53124
 
+       /* Dump reason and handle operands */
53125
 
+       return 
53126
 
+               sieve_opr_string_dump(denv, address, "method");
53127
 
+}
53128
 
+
53129
 
+/* 
53130
 
+ * Code execution
53131
 
+ */
53132
 
53133
 
+static int cmd_notify_operation_execute
53134
 
+(const struct sieve_operation *op ATTR_UNUSED,
53135
 
+       const struct sieve_runtime_env *renv, sieve_size_t *address)
53136
 
+{      
53137
 
+       struct sieve_side_effects_list *slist = NULL;
53138
 
+       struct sieve_enotify_action *act;
53139
 
+       void *method_context;
53140
 
+       pool_t pool;
53141
 
+       int opt_code = 1, result = SIEVE_EXEC_OK;
53142
 
+       sieve_number_t importance = 1;
53143
 
+       struct sieve_coded_stringlist *options = NULL;
53144
 
+       const struct sieve_enotify_method *method;
53145
 
+       string_t *method_uri, *message = NULL, *from = NULL; 
53146
 
+       unsigned int source_line;
53147
 
+
53148
 
+       /*
53149
 
+        * Read operands
53150
 
+        */
53151
 
+               
53152
 
+       /* Source line */
53153
 
+       if ( !sieve_code_source_line_read(renv, address, &source_line) ) {
53154
 
+               sieve_runtime_trace_error(renv, "invalid source line");
53155
 
+               return SIEVE_EXEC_BIN_CORRUPT;
53156
 
+       }
53157
 
+       
53158
 
+       /* Optional operands */ 
53159
 
+       if ( sieve_operand_optional_present(renv->sbin, address) ) {
53160
 
+               while ( opt_code != 0 ) {
53161
 
+                       if ( !sieve_operand_optional_read(renv->sbin, address, &opt_code) ) {
53162
 
+                               sieve_runtime_trace_error(renv, "invalid optional operand");
53163
 
+                               return SIEVE_EXEC_BIN_CORRUPT;
53164
 
+                       }
53165
 
+
53166
 
+                       switch ( opt_code ) {
53167
 
+                       case 0:
53168
 
+                               break;
53169
 
+                       case CMD_NOTIFY_OPT_IMPORTANCE:
53170
 
+                               if ( !sieve_opr_number_read(renv, address, &importance) ) {
53171
 
+                                       sieve_runtime_trace_error(renv, "invalid importance operand");
53172
 
+                                       return SIEVE_EXEC_BIN_CORRUPT;
53173
 
+                               }
53174
 
+       
53175
 
+                               /* Enforce 0 < importance < 4 (just to be sure) */
53176
 
+                               if ( importance < 1 ) 
53177
 
+                                       importance = 1;
53178
 
+                               else if ( importance > 3 )
53179
 
+                                       importance = 3;
53180
 
+                               break;
53181
 
+                       case CMD_NOTIFY_OPT_FROM:
53182
 
+                               if ( !sieve_opr_string_read(renv, address, &from) ) {
53183
 
+                                       sieve_runtime_trace_error(renv, "invalid from operand");
53184
 
+                                       return SIEVE_EXEC_BIN_CORRUPT;
53185
 
+                               }
53186
 
+                               break;
53187
 
+                       case CMD_NOTIFY_OPT_MESSAGE:
53188
 
+                               if ( !sieve_opr_string_read(renv, address, &message) ) {
53189
 
+                                       sieve_runtime_trace_error(renv, "invalid from operand");
53190
 
+                                       return SIEVE_EXEC_BIN_CORRUPT;
53191
 
+                               }
53192
 
+                               break;
53193
 
+                       case CMD_NOTIFY_OPT_OPTIONS:
53194
 
+                               if ( (options=sieve_opr_stringlist_read(renv, address)) == NULL ) {
53195
 
+                                       sieve_runtime_trace_error(renv, "invalid options operand");
53196
 
+                                       return SIEVE_EXEC_BIN_CORRUPT;
53197
 
+                               }
53198
 
+                               break;
53199
 
+                       default:
53200
 
+                               sieve_runtime_trace_error(renv, "unknown optional operand: %d", 
53201
 
+                                       opt_code);
53202
 
+                               return SIEVE_EXEC_BIN_CORRUPT;
53203
 
+                       }
53204
 
+               }
53205
 
+       }
53206
 
+       
53207
 
+       /* Reason operand */
53208
 
+       if ( !sieve_opr_string_read(renv, address, &method_uri) ) {
53209
 
+               sieve_runtime_trace_error(renv, "invalid method operand");
53210
 
+               return SIEVE_EXEC_BIN_CORRUPT;
53211
 
+       }
53212
 
+               
53213
 
+       /*
53214
 
+        * Perform operation
53215
 
+        */
53216
 
+
53217
 
+       sieve_runtime_trace(renv, "NOTIFY action");     
53218
 
+
53219
 
+       /* Check operands */
53220
 
+
53221
 
+       if ( (result=ext_enotify_runtime_check_operands
53222
 
+               (renv, source_line, method_uri, message, from, options, &method, 
53223
 
+                       &method_context)) ) 
53224
 
+       {
53225
 
+               /* Add notify action to the result */
53226
 
+
53227
 
+               pool = sieve_result_pool(renv->result);
53228
 
+               act = p_new(pool, struct sieve_enotify_action, 1);
53229
 
+               act->method = method;
53230
 
+               act->method_context = method_context;
53231
 
+               act->importance = importance;
53232
 
+               if ( message != NULL )
53233
 
+                       act->message = p_strdup(pool, str_c(message));
53234
 
+               if ( from != NULL )
53235
 
+                       act->from = p_strdup(pool, str_c(from));
53236
 
+               
53237
 
+               return ( sieve_result_add_action
53238
 
+                       (renv, &act_notify, slist, source_line, (void *) act, 0) >= 0 );
53239
 
+       }
53240
 
+       
53241
 
+       return result;
53242
 
+}
53243
 
+
53244
 
+/*
53245
 
+ * Action
53246
 
+ */
53247
 
+
53248
 
+/* Runtime verification */
53249
 
+
53250
 
+static int act_notify_check_duplicate
53251
 
+(const struct sieve_runtime_env *renv ATTR_UNUSED, 
53252
 
+       const struct sieve_action_data *act ATTR_UNUSED,
53253
 
+       const struct sieve_action_data *act_other ATTR_UNUSED)
53254
 
+{
53255
 
+       const struct sieve_enotify_action *nact1, *nact2;
53256
 
+       struct sieve_enotify_log nlog;
53257
 
+               
53258
 
+       if ( act->context == NULL || act_other->context == NULL )
53259
 
+               return 0;
53260
 
+
53261
 
+       nact1 = (const struct sieve_enotify_action *) act->context;
53262
 
+       nact2 = (const struct sieve_enotify_action *) act_other->context;
53263
 
+
53264
 
+       if ( nact1->method == NULL || nact1->method->action_check_duplicates == NULL )
53265
 
+               return 0;
53266
 
+
53267
 
+       memset(&nlog, 0, sizeof(nlog));
53268
 
+       nlog.location = act->location;
53269
 
+       nlog.ehandler = sieve_result_get_error_handler(renv->result);
53270
 
+
53271
 
+       return nact1->method->action_check_duplicates
53272
 
+               (&nlog, nact1->method_context, nact2->method_context, act_other->location);
53273
 
+}
53274
 
+
53275
 
+/* Result printing */
53276
 
53277
 
+static void act_notify_print
53278
 
+(const struct sieve_action *action ATTR_UNUSED, 
53279
 
+       const struct sieve_result_print_env *rpenv, void *context, 
53280
 
+       bool *keep ATTR_UNUSED) 
53281
 
+{
53282
 
+       const struct sieve_enotify_action *act = 
53283
 
+               (const struct sieve_enotify_action *) context;
53284
 
+
53285
 
+       sieve_result_action_printf
53286
 
+               ( rpenv, "send notification with method '%s:':", act->method->identifier);
53287
 
+               
53288
 
+       if ( act->method->action_print != NULL ) {
53289
 
+               struct sieve_enotify_print_env penv;
53290
 
+
53291
 
+               memset(&penv, 0, sizeof(penv));
53292
 
+               penv.result_penv = rpenv;
53293
 
+
53294
 
+               act->method->action_print(&penv, act);
53295
 
+       }
53296
 
+}
53297
 
+
53298
 
+/* Result execution */
53299
 
+
53300
 
+static bool act_notify_commit
53301
 
+(const struct sieve_action *action ATTR_UNUSED, 
53302
 
+       const struct sieve_action_exec_env *aenv, void *tr_context, 
53303
 
+       bool *keep ATTR_UNUSED)
53304
 
+{
53305
 
+       const struct sieve_enotify_action *act = 
53306
 
+               (const struct sieve_enotify_action *) tr_context;
53307
 
+       struct sieve_enotify_exec_env nenv;
53308
 
+       struct sieve_enotify_log nlog;
53309
 
+               
53310
 
+       memset(&nlog, 0, sizeof(nlog));
53311
 
+       nlog.location = sieve_action_get_location(aenv);
53312
 
+       nlog.ehandler = sieve_result_get_error_handler(aenv->result);
53313
 
+
53314
 
+       nenv.scriptenv = aenv->scriptenv;
53315
 
+       nenv.msgdata = aenv->msgdata;
53316
 
+       nenv.msgctx = aenv->msgctx;
53317
 
+       nenv.notify_log = &nlog;
53318
 
+
53319
 
+       if ( act->method->action_execute != NULL )
53320
 
+               return act->method->action_execute(&nenv, act);
53321
 
+                       
53322
 
+       return TRUE;
53323
 
+}
53324
 
+
53325
 
+
53326
 
+
53327
 
+
53328
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/enotify/ext-enotify.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/enotify/ext-enotify.c
53329
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/enotify/ext-enotify.c  1970-01-01 01:00:00.000000000 +0100
53330
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/enotify/ext-enotify.c   2009-02-02 10:17:30.000000000 +0100
53331
 
@@ -0,0 +1,88 @@
53332
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
53333
 
+ */
53334
 
+
53335
 
+/* Extension enotify
53336
 
+ * ------------------
53337
 
+ *
53338
 
+ * Authors: Stephan Bosch
53339
 
+ * Specification: RFC 5435
53340
 
+ * Implementation: full
53341
 
+ * Status: testing
53342
 
+ * 
53343
 
+ */
53344
 
+       
53345
 
+#include <stdio.h>
53346
 
+
53347
 
+#include "sieve-common.h"
53348
 
+
53349
 
+#include "sieve-code.h"
53350
 
+#include "sieve-extensions.h"
53351
 
+#include "sieve-actions.h"
53352
 
+#include "sieve-commands.h"
53353
 
+#include "sieve-validator.h"
53354
 
+#include "sieve-generator.h"
53355
 
+#include "sieve-interpreter.h"
53356
 
+#include "sieve-result.h"
53357
 
+
53358
 
+#include "sieve-ext-variables.h"
53359
 
+
53360
 
+#include "ext-enotify-common.h"
53361
 
+
53362
 
+/*
53363
 
+ * Operations
53364
 
+ */
53365
 
+
53366
 
+const struct sieve_operation *ext_enotify_operations[] = {
53367
 
+       &notify_operation,
53368
 
+       &valid_notify_method_operation,
53369
 
+       &notify_method_capability_operation
53370
 
+};
53371
 
+
53372
 
+/* 
53373
 
+ * Extension
53374
 
+ */
53375
 
+
53376
 
+static bool ext_enotify_load(void);
53377
 
+static void ext_enotify_unload(void);
53378
 
+static bool ext_enotify_validator_load(struct sieve_validator *valdtr);
53379
 
+
53380
 
+static int ext_my_id = -1;
53381
 
+
53382
 
+const struct sieve_extension enotify_extension = { 
53383
 
+       "enotify", 
53384
 
+       &ext_my_id,
53385
 
+       ext_enotify_load,
53386
 
+       ext_enotify_unload,
53387
 
+       ext_enotify_validator_load, 
53388
 
+       NULL, NULL, NULL, NULL, NULL,
53389
 
+       SIEVE_EXT_DEFINE_OPERATIONS(ext_enotify_operations),
53390
 
+       SIEVE_EXT_DEFINE_OPERAND(encodeurl_operand)
53391
 
+};
53392
 
+
53393
 
+static bool ext_enotify_load(void)
53394
 
+{
53395
 
+       ext_enotify_methods_init();
53396
 
+
53397
 
+       sieve_extension_capabilities_register(&notify_capabilities);
53398
 
+
53399
 
+       return TRUE;
53400
 
+}
53401
 
+
53402
 
+static void ext_enotify_unload(void)
53403
 
+{
53404
 
+       ext_enotify_methods_deinit();
53405
 
+}
53406
 
+
53407
 
+static bool ext_enotify_validator_load(struct sieve_validator *valdtr)
53408
 
+{
53409
 
+       /* Register new commands */
53410
 
+       sieve_validator_register_command(valdtr, &notify_command);
53411
 
+       sieve_validator_register_command(valdtr, &valid_notify_method_test);
53412
 
+       sieve_validator_register_command(valdtr, &notify_method_capability_test);
53413
 
+       
53414
 
+       /* Register new set modifier for variables extension */
53415
 
+       sieve_variables_modifier_register(valdtr, &encodeurl_modifier);
53416
 
+       
53417
 
+       return TRUE;
53418
 
+}
53419
 
+
53420
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/enotify/ext-enotify-common.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/enotify/ext-enotify-common.c
53421
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/enotify/ext-enotify-common.c   1970-01-01 01:00:00.000000000 +0100
53422
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/enotify/ext-enotify-common.c    2009-01-21 23:50:10.000000000 +0100
53423
 
@@ -0,0 +1,629 @@
53424
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file 
53425
 
+ */
53426
 
53427
 
+#include "lib.h"
53428
 
+#include "str.h"
53429
 
+#include "str-sanitize.h"
53430
 
+#include "array.h"
53431
 
+
53432
 
+#include "sieve-common.h"
53433
 
+#include "sieve-ast.h"
53434
 
+#include "sieve-code.h"
53435
 
+#include "sieve-commands.h"
53436
 
+#include "sieve-validator.h"
53437
 
+#include "sieve-interpreter.h"
53438
 
+#include "sieve-result.h"
53439
 
+
53440
 
+#include "ext-enotify-limits.h"
53441
 
+#include "ext-enotify-common.h"
53442
 
+
53443
 
+#include <ctype.h>
53444
 
+
53445
 
+/* FIXME: (from draft RFC)
53446
 
+ *
53447
 
+ * Header/envelope tests [Sieve] together with Sieve variables can be
53448
 
+ * used to extract the list of users to receive notifications from the
53449
 
+ * incoming email message or its envelope.  This is potentially quite
53450
 
+ * dangerous, as this can be used for Deny Of Service attacks on
53451
 
+ * recipients controlled by the message sender.  For this reason
53452
 
+ * implementations SHOULD NOT allow use of variables containing values
53453
 
+ * extracted from the email message in the method parameter to the
53454
 
+ * notify action.  Note that violation of this SHOULD NOT may result in
53455
 
+ * the creation of an open relay, i.e. any sender would be able to
53456
 
+ * create specially crafted email messages that would result in
53457
 
+ * notifications delivered to recipients under the control of the
53458
 
+ * sender.  In worst case this might result in financial loss by user
53459
 
+ * controlling the Sieve script and/or by recipients of notifications
53460
 
+ * (e.g. if a notification is an SMS message).
53461
 
+ *
53462
 
+ * --> This is currently not possible to check.
53463
 
+ */
53464
 
+
53465
 
+/*
53466
 
+ * Notify capability
53467
 
+ */
53468
 
+
53469
 
+static const char *ext_notify_get_methods_string(void);
53470
 
+
53471
 
+const struct sieve_extension_capabilities notify_capabilities = {
53472
 
+       "notify",
53473
 
+       &enotify_extension,
53474
 
+       ext_notify_get_methods_string
53475
 
+};
53476
 
+
53477
 
+/*
53478
 
+ * Notify method registry
53479
 
+ */
53480
 
53481
 
+static ARRAY_DEFINE(ext_enotify_methods, const struct sieve_enotify_method *); 
53482
 
+
53483
 
+void ext_enotify_methods_init(void)
53484
 
+{
53485
 
+       p_array_init(&ext_enotify_methods, default_pool, 4);
53486
 
+
53487
 
+       sieve_enotify_method_register(&mailto_notify);
53488
 
+}
53489
 
+
53490
 
+void ext_enotify_methods_deinit(void)
53491
 
+{
53492
 
+       array_free(&ext_enotify_methods);
53493
 
+}
53494
 
+
53495
 
+void sieve_enotify_method_register(const struct sieve_enotify_method *method) 
53496
 
+{
53497
 
+       array_append(&ext_enotify_methods, &method, 1);
53498
 
+}
53499
 
+
53500
 
+const struct sieve_enotify_method *ext_enotify_method_find
53501
 
+(const char *identifier) 
53502
 
+{
53503
 
+       unsigned int meth_count, i;
53504
 
+       const struct sieve_enotify_method *const *methods;
53505
 
+        
53506
 
+       methods = array_get(&ext_enotify_methods, &meth_count);
53507
 
+               
53508
 
+       for ( i = 0; i < meth_count; i++ ) {
53509
 
+               if ( strcasecmp(methods[i]->identifier, identifier) == 0 ) {
53510
 
+                       return methods[i];
53511
 
+               }
53512
 
+       }
53513
 
+       
53514
 
+       return NULL;
53515
 
+}
53516
 
+
53517
 
+static const char *ext_notify_get_methods_string(void)
53518
 
+{
53519
 
+       unsigned int meth_count, i;
53520
 
+       const struct sieve_enotify_method *const *methods;
53521
 
+       string_t *result = t_str_new(128);
53522
 
+        
53523
 
+       methods = array_get(&ext_enotify_methods, &meth_count);
53524
 
+               
53525
 
+       if ( meth_count > 0 ) {
53526
 
+               str_append(result, methods[0]->identifier);
53527
 
+               
53528
 
+               for ( i = 1; i < meth_count; i++ ) {
53529
 
+                       str_append_c(result, ' ');
53530
 
+                       str_append(result, methods[i]->identifier);
53531
 
+               }
53532
 
+               
53533
 
+               return str_c(result);
53534
 
+       }
53535
 
+       
53536
 
+       return NULL;
53537
 
+}
53538
 
+
53539
 
+/*
53540
 
+ * Compile-time argument validation
53541
 
+ */
53542
 
53543
 
+static const char *ext_enotify_uri_scheme_parse(const char **uri_p)
53544
 
+{
53545
 
+       string_t *scheme = t_str_new(EXT_ENOTIFY_MAX_SCHEME_LEN);
53546
 
+       const char *p = *uri_p;
53547
 
+       unsigned int len = 0;
53548
 
+       
53549
 
+       /* RFC 3968:
53550
 
+        *
53551
 
+        *   scheme  = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
53552
 
+        *
53553
 
+        * FIXME: we do not allow '%' in schemes. Is this correct?
53554
 
+        */
53555
 
+        
53556
 
+       if ( !i_isalpha(*p) )
53557
 
+               return NULL;
53558
 
+               
53559
 
+       str_append_c(scheme, *p);
53560
 
+       p++;
53561
 
+               
53562
 
+       while ( *p != '\0' && len < EXT_ENOTIFY_MAX_SCHEME_LEN ) {
53563
 
+                       
53564
 
+               if ( !i_isalnum(*p) && *p != '+' && *p != '-' && *p != '.' )
53565
 
+                       break;
53566
 
+       
53567
 
+               str_append_c(scheme, *p);
53568
 
+               p++;
53569
 
+               len++;
53570
 
+       }
53571
 
+       
53572
 
+       if ( *p != ':' )
53573
 
+               return NULL;
53574
 
+       p++;
53575
 
+       
53576
 
+       *uri_p = p;
53577
 
+       return str_c(scheme);
53578
 
+}
53579
 
+
53580
 
+static bool ext_enotify_option_parse
53581
 
+(struct sieve_enotify_log *nlog, const char *option, bool name_only,
53582
 
+       const char **opt_name_r, const char **opt_value_r)
53583
 
+{
53584
 
+       const char *p = option;
53585
 
+       
53586
 
+       /* "<optionname>=<value>".
53587
 
+        * 
53588
 
+        * l-d = ALPHA / DIGIT
53589
 
+        * l-d-p = l-d / "." / "-" / "_"
53590
 
+        * optionname = l-d *l-d-p
53591
 
+        * value = *(%x01-09 / %x0B-0C / %x0E-FF)
53592
 
+        */
53593
 
+                               
53594
 
+       /* 
53595
 
+        * Parse option name 
53596
 
+        *
53597
 
+        * optionname = l-d *l-d-p
53598
 
+        */
53599
 
+       
53600
 
+       /* Explicitly report empty option as such */
53601
 
+       if ( *p == '\0' ) {
53602
 
+               sieve_enotify_error(nlog, "empty option specified");
53603
 
+               return FALSE;
53604
 
+       }
53605
 
+
53606
 
+       /* l-d = ALPHA / DIGIT */
53607
 
+       if ( i_isalnum(*p) ) {
53608
 
+               p++;
53609
 
+       
53610
 
+               /* l-d-p = l-d / "." / "-" / "_" */
53611
 
+               while ( i_isalnum(*p) || *p == '.' || *p == '-' || *p == '_' )
53612
 
+                       p++;
53613
 
+       }
53614
 
+       
53615
 
+       /* Parsing must end at '=' and we must parse at least one character */
53616
 
+       if ( *p != '=' || p == option ) {
53617
 
+               sieve_enotify_error(nlog, "invalid option name specified in option '%s'",
53618
 
+                               str_sanitize(option, 80));
53619
 
+               return FALSE;
53620
 
+       }
53621
 
+       
53622
 
+       /* Assign option name */
53623
 
+       if ( opt_name_r != NULL ) 
53624
 
+               *opt_name_r = t_strdup_until(option, p);
53625
 
+       
53626
 
+       /* Skip '=' */
53627
 
+       p++;
53628
 
+       
53629
 
+       /* Exit now if only the option name is of interest */
53630
 
+       if ( name_only )
53631
 
+               return TRUE;
53632
 
+                       
53633
 
+       /* 
53634
 
+        * Parse option value
53635
 
+        */
53636
 
+        
53637
 
+       /* value = *(%x01-09 / %x0B-0C / %x0E-FF) */
53638
 
+       while ( *p != '\0' && *p != 0x0A && *p != 0x0D )
53639
 
+               p++;
53640
 
+               
53641
 
+       /* Parse must end at end of string */
53642
 
+       if ( *p != '\0' ) {
53643
 
+               sieve_enotify_error(nlog, 
53644
 
+                       "notify command: invalid option value specified in option '%s'",
53645
 
+                               str_sanitize(option, 80));
53646
 
+               return FALSE;
53647
 
+       }
53648
 
+       
53649
 
+       /* Assign option value */
53650
 
+       if ( opt_value_r != NULL )
53651
 
+               *opt_value_r = p;
53652
 
+               
53653
 
+       return TRUE;
53654
 
+} 
53655
 
+
53656
 
+struct _ext_enotify_option_check_context {
53657
 
+       struct sieve_validator *valdtr;
53658
 
+       const struct sieve_enotify_method *method;
53659
 
+};
53660
 
+
53661
 
+static int _ext_enotify_option_check
53662
 
+(void *context, struct sieve_ast_argument *arg)
53663
 
+{
53664
 
+       struct _ext_enotify_option_check_context *optn_context = 
53665
 
+               (struct _ext_enotify_option_check_context *) context;
53666
 
+       struct sieve_validator *valdtr = optn_context->valdtr;
53667
 
+       const struct sieve_enotify_method *method = optn_context->method;
53668
 
+       struct sieve_enotify_log nlog;
53669
 
+       const char *option = sieve_ast_argument_strc(arg);
53670
 
+       const char *opt_name = NULL, *opt_value = NULL;
53671
 
+       bool literal = sieve_argument_is_string_literal(arg);
53672
 
+       
53673
 
+       /* Compose log structure */
53674
 
+       memset(&nlog, 0, sizeof(nlog));
53675
 
+       nlog.ehandler = sieve_validator_error_handler(valdtr);
53676
 
+       nlog.prefix = "notify command";
53677
 
+       nlog.location = sieve_error_script_location
53678
 
+               (sieve_validator_script(valdtr), arg->source_line);
53679
 
+               
53680
 
+       /* Parse option */
53681
 
+       if ( !literal ) {
53682
 
+               /* Variable string: partial option parse
53683
 
+                * 
53684
 
+                * If the string item is not a string literal, it cannot be validated fully
53685
 
+                * at compile time. We can however check whether the '=' is in the string
53686
 
+                * specification and whether the part before the '=' is a valid option name.
53687
 
+                * In that case, the method option check function is called with the value
53688
 
+                * parameter equal to NULL, meaning that it should only check the validity
53689
 
+                * of the option itself and not the assigned value.
53690
 
+                */ 
53691
 
+               if ( !ext_enotify_option_parse(NULL, option, TRUE, &opt_name, &opt_value) )
53692
 
+                       return TRUE;
53693
 
+       } else {
53694
 
+               /* Literal string: full option parse */
53695
 
+               if ( !ext_enotify_option_parse
53696
 
+                       (&nlog, option, FALSE, &opt_name, &opt_value) )
53697
 
+                       return FALSE;
53698
 
+       }
53699
 
+       
53700
 
+       /* Call method's option check function */
53701
 
+       if ( method->compile_check_option != NULL ) 
53702
 
+               return method->compile_check_option(&nlog, opt_name, opt_value); 
53703
 
+       
53704
 
+       return TRUE;
53705
 
+}
53706
 
+
53707
 
+bool ext_enotify_compile_check_arguments
53708
 
+(struct sieve_validator *valdtr, struct sieve_ast_argument *uri_arg,
53709
 
+       struct sieve_ast_argument *msg_arg, struct sieve_ast_argument *from_arg,
53710
 
+       struct sieve_ast_argument *options_arg)
53711
 
+{
53712
 
+       const char *uri = sieve_ast_argument_strc(uri_arg);
53713
 
+       const char *scheme;
53714
 
+       const struct sieve_enotify_method *method;
53715
 
+       struct sieve_enotify_log nlog;
53716
 
+
53717
 
+       /* If the uri string is not a constant literal, we cannot determine which
53718
 
+        * method is used, so we bail out successfully and defer checking to runtime.
53719
 
+        */
53720
 
+       if ( !sieve_argument_is_string_literal(uri_arg) )
53721
 
+               return TRUE;
53722
 
+       
53723
 
+       /* Parse scheme part of URI */
53724
 
+       if ( (scheme=ext_enotify_uri_scheme_parse(&uri)) == NULL ) {
53725
 
+               sieve_argument_validate_error(valdtr, uri_arg, 
53726
 
+                       "notify command: invalid scheme part for method URI '%s'", 
53727
 
+                       str_sanitize(sieve_ast_argument_strc(uri_arg), 80));
53728
 
+               return FALSE;
53729
 
+       }
53730
 
+       
53731
 
+       /* Find used method with the parsed scheme identifier */
53732
 
+       if ( (method=ext_enotify_method_find(scheme)) == NULL ) {
53733
 
+               sieve_argument_validate_error(valdtr, uri_arg, 
53734
 
+                       "notify command: invalid method '%s'", scheme);
53735
 
+               return FALSE;
53736
 
+       }
53737
 
+
53738
 
+       /* Compose log structure */
53739
 
+       memset(&nlog, 0, sizeof(nlog));
53740
 
+       nlog.ehandler = sieve_validator_error_handler(valdtr);
53741
 
+       nlog.prefix = "notify command";
53742
 
+       
53743
 
+       /* Check URI itself */
53744
 
+       if ( method->compile_check_uri != NULL ) {
53745
 
+               /* Set log location to location of URI argument */
53746
 
+               nlog.location = sieve_error_script_location
53747
 
+                       (sieve_validator_script(valdtr), uri_arg->source_line);
53748
 
+
53749
 
+               /* Execute method check function */
53750
 
+               if ( !method->compile_check_uri
53751
 
+                       (&nlog, sieve_ast_argument_strc(uri_arg), uri) )
53752
 
+                       return FALSE;
53753
 
+       }
53754
 
+
53755
 
+       /* Check :message argument */
53756
 
+       if ( msg_arg != NULL && sieve_argument_is_string_literal(msg_arg) && 
53757
 
+               method->compile_check_message != NULL ) {
53758
 
+               /* Set log location to location of :message argument */
53759
 
+               nlog.location = sieve_error_script_location
53760
 
+                       (sieve_validator_script(valdtr), msg_arg->source_line);
53761
 
+
53762
 
+               /* Execute method check function */
53763
 
+               if ( !method->compile_check_message
53764
 
+                       (&nlog, sieve_ast_argument_str(msg_arg)) )
53765
 
+                       return FALSE;
53766
 
+       }
53767
 
+
53768
 
+       /* Check :from argument */
53769
 
+       if ( from_arg != NULL && sieve_argument_is_string_literal(from_arg) &&
53770
 
+               method->compile_check_from != NULL ) {
53771
 
+               /* Set log location to location of :from argument */
53772
 
+               nlog.location = sieve_error_script_location
53773
 
+                       (sieve_validator_script(valdtr), from_arg->source_line);
53774
 
+
53775
 
+               /* Execute method check function */
53776
 
+               if ( !method->compile_check_from(&nlog, sieve_ast_argument_str(from_arg)) )
53777
 
+                       return FALSE;
53778
 
+       }
53779
 
+       
53780
 
+       /* Check :options argument */
53781
 
+       if ( options_arg != NULL ) {
53782
 
+               struct sieve_ast_argument *option = options_arg;
53783
 
+               struct _ext_enotify_option_check_context optn_context = { valdtr, method };
53784
 
+               
53785
 
+               /* Parse and check options */
53786
 
+               if ( sieve_ast_stringlist_map
53787
 
+                       (&option, (void *) &optn_context, _ext_enotify_option_check) <= 0 )
53788
 
+                       return FALSE;
53789
 
+                       
53790
 
+               /* Discard argument if options are not accepted by method */
53791
 
+               if ( method->compile_check_option == NULL ) {
53792
 
+                       sieve_argument_validate_warning(valdtr, options_arg, 
53793
 
+                               "notify command: method '%s' accepts no options", scheme);
53794
 
+                       (void)sieve_ast_arguments_detach(options_arg,1);
53795
 
+               }
53796
 
+       }
53797
 
+       
53798
 
+       return TRUE;
53799
 
+}
53800
 
+
53801
 
+/*
53802
 
+ * Runtime operand checking
53803
 
+ */
53804
 
53805
 
+bool ext_enotify_runtime_method_validate
53806
 
+(const struct sieve_runtime_env *renv, unsigned int source_line,
53807
 
+       string_t *method_uri)
53808
 
+{
53809
 
+       const struct sieve_enotify_method *method;
53810
 
+       const char *uri = str_c(method_uri);
53811
 
+       const char *scheme;
53812
 
+       
53813
 
+       /* Get the method */
53814
 
+       
53815
 
+       if ( (scheme=ext_enotify_uri_scheme_parse(&uri)) == NULL )
53816
 
+               return FALSE;
53817
 
+       
53818
 
+       if ( (method=ext_enotify_method_find(scheme)) == NULL )
53819
 
+               return FALSE;
53820
 
+               
53821
 
+       /* Validate the provided URI */
53822
 
+       
53823
 
+       if ( method->runtime_check_uri != NULL ) {
53824
 
+               struct sieve_enotify_log nlog;
53825
 
+               
53826
 
+               memset(&nlog, 0, sizeof(nlog));
53827
 
+               nlog.location = sieve_error_script_location(renv->script, source_line);
53828
 
+               nlog.ehandler = sieve_interpreter_get_error_handler(renv->interp);
53829
 
+               nlog.prefix = "valid_notify_method test";
53830
 
+
53831
 
+               /* Use the method check function to validate the URI */
53832
 
+               return method->runtime_check_uri(&nlog, str_c(method_uri), uri);
53833
 
+       }
53834
 
+
53835
 
+       /* Method has no check function */
53836
 
+       return TRUE;
53837
 
+}
53838
 
53839
 
+static const struct sieve_enotify_method *ext_enotify_get_method
53840
 
+(const struct sieve_runtime_env *renv, unsigned int source_line,
53841
 
+       string_t *method_uri, const char **uri_body_r)
53842
 
+{
53843
 
+       const struct sieve_enotify_method *method;
53844
 
+       const char *uri = str_c(method_uri);
53845
 
+       const char *scheme;
53846
 
+       
53847
 
+       /* Parse part before ':' of the uri (the scheme) and use it to identify
53848
 
+        * notify method.
53849
 
+        */
53850
 
+       if ( (scheme=ext_enotify_uri_scheme_parse(&uri)) == NULL ) {
53851
 
+               sieve_runtime_error
53852
 
+                       (renv, sieve_error_script_location(renv->script, source_line),
53853
 
+                               "invalid scheme part for method URI '%s'", 
53854
 
+                               str_sanitize(str_c(method_uri), 80));
53855
 
+               return NULL;
53856
 
+       }
53857
 
+       
53858
 
+       /* Find the notify method */
53859
 
+       if ( (method=ext_enotify_method_find(scheme)) == NULL ) {
53860
 
+               sieve_runtime_error
53861
 
+                       (renv, sieve_error_script_location(renv->script, source_line),
53862
 
+                               "invalid notify method '%s'", scheme);
53863
 
+               return NULL;
53864
 
+       }
53865
 
+
53866
 
+       /* Return the parse pointer and the found method */
53867
 
+       *uri_body_r = uri;
53868
 
+       return method;
53869
 
+}
53870
 
+
53871
 
+const char *ext_enotify_runtime_get_method_capability
53872
 
+(const struct sieve_runtime_env *renv, unsigned int source_line,
53873
 
+       string_t *method_uri, const char *capability)
53874
 
+{
53875
 
+       const struct sieve_enotify_method *method;
53876
 
+       const char *uri;
53877
 
+       
53878
 
+       /* Get method */
53879
 
+       method = ext_enotify_get_method(renv, source_line, method_uri, &uri);
53880
 
+       if ( method == NULL ) return NULL;
53881
 
+       
53882
 
+       /* Get requested capability */
53883
 
+       if ( method->runtime_get_method_capability != NULL ) {
53884
 
+               struct sieve_enotify_log nlog;
53885
 
+               
53886
 
+               /* Compose log structure */
53887
 
+               memset(&nlog, 0, sizeof(nlog));
53888
 
+               nlog.location = sieve_error_script_location(renv->script, source_line);
53889
 
+               nlog.ehandler = sieve_interpreter_get_error_handler(renv->interp);
53890
 
+               nlog.prefix = "notify_method_capability test";
53891
 
+
53892
 
+               /* Execute method function to acquire capability value */
53893
 
+               return method->runtime_get_method_capability
53894
 
+                       (&nlog, str_c(method_uri), uri, capability);
53895
 
+       }
53896
 
+
53897
 
+       return NULL;
53898
 
+}
53899
 
+
53900
 
+int ext_enotify_runtime_check_operands
53901
 
+(const struct sieve_runtime_env *renv, unsigned int source_line,
53902
 
+       string_t *method_uri, string_t *message, string_t *from, 
53903
 
+       struct sieve_coded_stringlist *options, 
53904
 
+       const struct sieve_enotify_method **method_r, void **method_context)
53905
 
+{
53906
 
+       const struct sieve_enotify_method *method;
53907
 
+       const char *uri;
53908
 
+       
53909
 
+       /* Get method */
53910
 
+       method = ext_enotify_get_method(renv, source_line, method_uri, &uri);
53911
 
+       if ( method == NULL ) return SIEVE_EXEC_FAILURE;
53912
 
+       
53913
 
+       /* Check provided operands */
53914
 
+       if ( method->runtime_check_operands != NULL ) {
53915
 
+               struct sieve_enotify_log nlog;
53916
 
+               
53917
 
+               /* Compose log structure */
53918
 
+               memset(&nlog, 0, sizeof(nlog));
53919
 
+               nlog.location = sieve_error_script_location(renv->script, source_line);
53920
 
+               nlog.ehandler = sieve_interpreter_get_error_handler(renv->interp);
53921
 
+               nlog.prefix = "notify action";
53922
 
+
53923
 
+               /* Execute check function */
53924
 
+               if ( method->runtime_check_operands(&nlog, str_c(method_uri), uri, message, 
53925
 
+                       from, sieve_result_pool(renv->result), method_context) ) {
53926
 
+                       
53927
 
+                       /* Check any provided options */
53928
 
+                       if ( options != NULL ) {                        
53929
 
+                               int result = TRUE;
53930
 
+                               string_t *option = NULL;
53931
 
+                       
53932
 
+                               /* Iterate through all provided options */
53933
 
+                               while ( result && 
53934
 
+                                       (result=sieve_coded_stringlist_next_item(options, &option)) && 
53935
 
+                                       option != NULL ) {
53936
 
+                                       const char *opt_name = NULL, *opt_value = NULL;
53937
 
+                               
53938
 
+                                       /* Parse option into <optionname> and <value> */
53939
 
+                                       if ( ext_enotify_option_parse
53940
 
+                                               (&nlog, str_c(option), FALSE, &opt_name, &opt_value) ) {
53941
 
+                                       
53942
 
+                                               /* Set option */
53943
 
+                                               if ( method->runtime_set_option != NULL ) {
53944
 
+                                                       (void) method->runtime_set_option
53945
 
+                                                               (&nlog, *method_context, opt_name, opt_value);
53946
 
+                                               }
53947
 
+                                       }
53948
 
+                               }
53949
 
+                       
53950
 
+                               /* Check for binary corruptions encountered during string list iteration
53951
 
+                                */
53952
 
+                               if ( result ) {
53953
 
+                                       *method_r = method;
53954
 
+                                       return SIEVE_EXEC_OK;
53955
 
+                               }
53956
 
+       
53957
 
+                               /* Binary corrupt */
53958
 
+                               sieve_runtime_trace_error(renv, "invalid item in options string list");
53959
 
+                               return SIEVE_EXEC_BIN_CORRUPT;
53960
 
+                       }
53961
 
+
53962
 
+                       /* No options */                        
53963
 
+                       *method_r = method;
53964
 
+                       return SIEVE_EXEC_OK;
53965
 
+               }
53966
 
+               
53967
 
+               /* Check failed */
53968
 
+               return SIEVE_EXEC_FAILURE;
53969
 
+       }
53970
 
+
53971
 
+       /* No check function defined: a most unlikely situation */
53972
 
+       *method_context = NULL; 
53973
 
+       *method_r = method;
53974
 
+       return SIEVE_EXEC_OK;
53975
 
+}
53976
 
+
53977
 
+/*
53978
 
+ * Notify method printing
53979
 
+ */
53980
 
+
53981
 
+void sieve_enotify_method_printf
53982
 
+(const struct sieve_enotify_print_env *penv, const char *fmt, ...)
53983
 
+{
53984
 
+       va_list args;
53985
 
+       
53986
 
+       va_start(args, fmt);    
53987
 
+       sieve_result_vprintf(penv->result_penv, fmt, args);
53988
 
+       va_end(args);    
53989
 
+}
53990
 
+
53991
 
+/*
53992
 
+ * Method logging
53993
 
+ */
53994
 
+
53995
 
+void sieve_enotify_error
53996
 
+(const struct sieve_enotify_log *nlog, const char *fmt, ...) 
53997
 
+{
53998
 
+       va_list args;
53999
 
+       va_start(args, fmt);
54000
 
+       
54001
 
+       if ( nlog == NULL ) return;
54002
 
+       
54003
 
+       T_BEGIN {
54004
 
+               if ( nlog->prefix == NULL )
54005
 
+                       sieve_verror(nlog->ehandler, nlog->location, fmt, args);
54006
 
+               else
54007
 
+                       sieve_error(nlog->ehandler, nlog->location, "%s: %s", nlog->prefix, 
54008
 
+                               t_strdup_vprintf(fmt, args));
54009
 
+       } T_END;
54010
 
+       
54011
 
+       va_end(args);
54012
 
+}
54013
 
+
54014
 
+void sieve_enotify_warning
54015
 
+(const struct sieve_enotify_log *nlog, const char *fmt, ...) 
54016
 
+{
54017
 
+       va_list args;
54018
 
+       va_start(args, fmt);
54019
 
+       
54020
 
+       if ( nlog == NULL ) return;
54021
 
+       
54022
 
+       T_BEGIN { 
54023
 
+               if ( nlog->prefix == NULL )
54024
 
+                       sieve_vwarning(nlog->ehandler, nlog->location, fmt, args);
54025
 
+               else                    
54026
 
+                       sieve_warning(nlog->ehandler, nlog->location, "%s: %s", nlog->prefix, 
54027
 
+                               t_strdup_vprintf(fmt, args));
54028
 
+       } T_END;
54029
 
+       
54030
 
+       va_end(args);
54031
 
+}
54032
 
+
54033
 
+void sieve_enotify_log
54034
 
+(const struct sieve_enotify_log *nlog, const char *fmt, ...) 
54035
 
+{
54036
 
+       va_list args;
54037
 
+       va_start(args, fmt);
54038
 
+
54039
 
+       if ( nlog == NULL ) return;
54040
 
+       
54041
 
+       T_BEGIN { 
54042
 
+               if ( nlog->prefix == NULL )
54043
 
+                       sieve_vinfo(nlog->ehandler, nlog->location, fmt, args);
54044
 
+               else
54045
 
+                       sieve_info(nlog->ehandler, nlog->location, "%s: %s", nlog->prefix, 
54046
 
+                               t_strdup_vprintf(fmt, args));   
54047
 
+       } T_END;
54048
 
+       
54049
 
+       va_end(args);
54050
 
+}
54051
 
+
54052
 
+
54053
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/enotify/ext-enotify-common.h dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/enotify/ext-enotify-common.h
54054
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/enotify/ext-enotify-common.h   1970-01-01 01:00:00.000000000 +0100
54055
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/enotify/ext-enotify-common.h    2009-07-08 18:55:52.000000000 +0200
54056
 
@@ -0,0 +1,126 @@
54057
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
54058
 
+ */
54059
 
+
54060
 
+#ifndef __EXT_ENOTIFY_COMMON_H
54061
 
+#define __EXT_ENOTIFY_COMMON_H
54062
 
+
54063
 
+#include "sieve-ext-variables.h"
54064
 
+
54065
 
+#include "sieve-ext-enotify.h"
54066
 
+
54067
 
+/*
54068
 
+ * Extension
54069
 
+ */
54070
 
+
54071
 
+extern const struct sieve_extension enotify_extension;
54072
 
+extern const struct sieve_extension notify_extension;
54073
 
+extern const struct sieve_extension_capabilities notify_capabilities;
54074
 
+
54075
 
+/*
54076
 
+ * Commands
54077
 
+ */
54078
 
+
54079
 
+extern const struct sieve_command notify_command;
54080
 
+
54081
 
+/* Codes for optional arguments */
54082
 
+
54083
 
+enum cmd_notify_optional {
54084
 
+    CMD_NOTIFY_OPT_END,
54085
 
+    CMD_NOTIFY_OPT_FROM,
54086
 
+    CMD_NOTIFY_OPT_OPTIONS,
54087
 
+    CMD_NOTIFY_OPT_MESSAGE,
54088
 
+    CMD_NOTIFY_OPT_IMPORTANCE
54089
 
+};
54090
 
+
54091
 
+/*
54092
 
+ * Tests
54093
 
+ */
54094
 
+
54095
 
+extern const struct sieve_command valid_notify_method_test;
54096
 
+extern const struct sieve_command notify_method_capability_test;
54097
 
+
54098
 
+/*
54099
 
+ * Operations
54100
 
+ */
54101
 
+
54102
 
+extern const struct sieve_operation notify_operation;
54103
 
+extern const struct sieve_operation valid_notify_method_operation;
54104
 
+extern const struct sieve_operation notify_method_capability_operation;
54105
 
+
54106
 
+enum ext_variables_opcode {
54107
 
+       EXT_ENOTIFY_OPERATION_NOTIFY,
54108
 
+       EXT_ENOTIFY_OPERATION_VALID_NOTIFY_METHOD,
54109
 
+       EXT_ENOTIFY_OPERATION_NOTIFY_METHOD_CAPABILITY
54110
 
+};
54111
 
+
54112
 
+/*
54113
 
+ * Operands
54114
 
+ */
54115
 
54116
 
+extern const struct sieve_operand encodeurl_operand;
54117
 
+
54118
 
+/*
54119
 
+ * Modifiers
54120
 
+ */
54121
 
+
54122
 
+extern const struct sieve_variables_modifier encodeurl_modifier;
54123
 
+
54124
 
+/*
54125
 
+ * Notify methods
54126
 
+ */
54127
 
54128
 
+extern const struct sieve_enotify_method mailto_notify;
54129
 
54130
 
+void ext_enotify_methods_init(void);
54131
 
+void ext_enotify_methods_deinit(void);
54132
 
+
54133
 
+const struct sieve_enotify_method *ext_enotify_method_find
54134
 
+       (const char *identifier);
54135
 
+       
54136
 
+/*
54137
 
+ * Validation
54138
 
+ */
54139
 
54140
 
+bool ext_enotify_compile_check_arguments
54141
 
+(struct sieve_validator *valdtr, struct sieve_ast_argument *uri_arg,
54142
 
+       struct sieve_ast_argument *msg_arg, struct sieve_ast_argument *from_arg,
54143
 
+       struct sieve_ast_argument *options_arg);
54144
 
+
54145
 
+/*
54146
 
+ * Runtime
54147
 
+ */
54148
 
54149
 
+bool ext_enotify_runtime_method_validate
54150
 
+       (const struct sieve_runtime_env *renv, unsigned int source_line,
54151
 
+               string_t *method_uri);
54152
 
54153
 
+const char *ext_enotify_runtime_get_method_capability
54154
 
+       (const struct sieve_runtime_env *renv, unsigned int source_line,
54155
 
+               string_t *method_uri, const char *capability);
54156
 
+
54157
 
+int ext_enotify_runtime_check_operands
54158
 
+       (const struct sieve_runtime_env *renv, unsigned int source_line,
54159
 
+               string_t *method_uri, string_t *message, string_t *from, 
54160
 
+               struct sieve_coded_stringlist *options, 
54161
 
+               const struct sieve_enotify_method **method_r, void **method_context);
54162
 
+               
54163
 
+/*
54164
 
+ * Method printing
54165
 
+ */
54166
 
+
54167
 
+struct sieve_enotify_print_env {
54168
 
+       const struct sieve_result_print_env *result_penv;
54169
 
+};
54170
 
+
54171
 
+/*
54172
 
+ * Method logging
54173
 
+ */ 
54174
 
+
54175
 
+struct sieve_enotify_log {
54176
 
+       struct sieve_error_handler *ehandler;
54177
 
+       
54178
 
+       const char *location;
54179
 
+       const char *prefix;
54180
 
+};
54181
 
+
54182
 
+#endif /* __EXT_ENOTIFY_COMMON_H */
54183
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/enotify/ext-enotify-limits.h dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/enotify/ext-enotify-limits.h
54184
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/enotify/ext-enotify-limits.h   1970-01-01 01:00:00.000000000 +0100
54185
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/enotify/ext-enotify-limits.h    2009-01-06 00:15:52.000000000 +0100
54186
 
@@ -0,0 +1,9 @@
54187
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
54188
 
+ */
54189
 
54190
 
+#ifndef __EXT_ENOTIFY_LIMITS_H
54191
 
+#define __EXT_ENOTIFY_LIMITS_H
54192
 
+
54193
 
+#define EXT_ENOTIFY_MAX_SCHEME_LEN  32
54194
 
+
54195
 
+#endif /* __EXT_ENOTIFY_LIMITS_H */
54196
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/enotify/Makefile.am dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/enotify/Makefile.am
54197
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/enotify/Makefile.am    1970-01-01 01:00:00.000000000 +0100
54198
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/enotify/Makefile.am     2009-07-19 15:54:39.000000000 +0200
54199
 
@@ -0,0 +1,36 @@
54200
 
+noinst_LTLIBRARIES = libsieve_ext_enotify.la
54201
 
+
54202
 
+AM_CPPFLAGS = \
54203
 
+       -I../../ \
54204
 
+       -I../variables \
54205
 
+       -I$(dovecot_incdir) \
54206
 
+       -I$(dovecot_incdir)/src/lib \
54207
 
+       -I$(dovecot_incdir)/src/lib-mail \
54208
 
+       -I$(dovecot_incdir)/src/lib-storage 
54209
 
+
54210
 
+commands = \
54211
 
+       cmd-notify.c
54212
 
+
54213
 
+tests = \
54214
 
+       tst-valid-notify-method.c \
54215
 
+       tst-notify-method-capability.c
54216
 
+
54217
 
+var_modifiers = \
54218
 
+       vmodf-encodeurl.c
54219
 
+
54220
 
+notify_methods = \
54221
 
+       ntfy-mailto.c
54222
 
+
54223
 
+libsieve_ext_enotify_la_SOURCES = \
54224
 
+       ext-enotify.c \
54225
 
+       ext-enotify-common.c \
54226
 
+       $(commands) \
54227
 
+       $(tests) \
54228
 
+       $(var_modifiers) \
54229
 
+       $(notify_methods)
54230
 
+
54231
 
+noinst_HEADERS = \
54232
 
+       sieve-ext-enotify.h \
54233
 
+       ext-enotify-limits.h \
54234
 
+       ext-enotify-common.h
54235
 
+
54236
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/enotify/Makefile.in dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/enotify/Makefile.in
54237
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/enotify/Makefile.in    1970-01-01 01:00:00.000000000 +0100
54238
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/enotify/Makefile.in     2009-08-21 00:55:43.000000000 +0200
54239
 
@@ -0,0 +1,494 @@
54240
 
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
54241
 
+# @configure_input@
54242
 
+
54243
 
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
54244
 
+# 2003, 2004, 2005, 2006, 2007, 2008  Free Software Foundation, Inc.
54245
 
+# This Makefile.in is free software; the Free Software Foundation
54246
 
+# gives unlimited permission to copy and/or distribute it,
54247
 
+# with or without modifications, as long as this notice is preserved.
54248
 
+
54249
 
+# This program is distributed in the hope that it will be useful,
54250
 
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
54251
 
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
54252
 
+# PARTICULAR PURPOSE.
54253
 
+
54254
 
+@SET_MAKE@
54255
 
+
54256
 
+
54257
 
+VPATH = @srcdir@
54258
 
+pkgdatadir = $(datadir)/@PACKAGE@
54259
 
+pkglibdir = $(libdir)/@PACKAGE@
54260
 
+pkgincludedir = $(includedir)/@PACKAGE@
54261
 
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
54262
 
+install_sh_DATA = $(install_sh) -c -m 644
54263
 
+install_sh_PROGRAM = $(install_sh) -c
54264
 
+install_sh_SCRIPT = $(install_sh) -c
54265
 
+INSTALL_HEADER = $(INSTALL_DATA)
54266
 
+transform = $(program_transform_name)
54267
 
+NORMAL_INSTALL = :
54268
 
+PRE_INSTALL = :
54269
 
+POST_INSTALL = :
54270
 
+NORMAL_UNINSTALL = :
54271
 
+PRE_UNINSTALL = :
54272
 
+POST_UNINSTALL = :
54273
 
+build_triplet = @build@
54274
 
+host_triplet = @host@
54275
 
+subdir = src/lib-sieve/plugins/enotify
54276
 
+DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
54277
 
+       $(srcdir)/Makefile.in
54278
 
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
54279
 
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
54280
 
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
54281
 
+       $(ACLOCAL_M4)
54282
 
+mkinstalldirs = $(install_sh) -d
54283
 
+CONFIG_HEADER = $(top_builddir)/dummy-config.h \
54284
 
+       $(top_builddir)/dsieve-config.h
54285
 
+CONFIG_CLEAN_FILES =
54286
 
+LTLIBRARIES = $(noinst_LTLIBRARIES)
54287
 
+libsieve_ext_enotify_la_LIBADD =
54288
 
+am__objects_1 = cmd-notify.lo
54289
 
+am__objects_2 = tst-valid-notify-method.lo \
54290
 
+       tst-notify-method-capability.lo
54291
 
+am__objects_3 = vmodf-encodeurl.lo
54292
 
+am__objects_4 = ntfy-mailto.lo
54293
 
+am_libsieve_ext_enotify_la_OBJECTS = ext-enotify.lo \
54294
 
+       ext-enotify-common.lo $(am__objects_1) $(am__objects_2) \
54295
 
+       $(am__objects_3) $(am__objects_4)
54296
 
+libsieve_ext_enotify_la_OBJECTS =  \
54297
 
+       $(am_libsieve_ext_enotify_la_OBJECTS)
54298
 
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
54299
 
+depcomp = $(SHELL) $(top_srcdir)/depcomp
54300
 
+am__depfiles_maybe = depfiles
54301
 
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
54302
 
+       $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
54303
 
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
54304
 
+       --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
54305
 
+       $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
54306
 
+CCLD = $(CC)
54307
 
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
54308
 
+       --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
54309
 
+       $(LDFLAGS) -o $@
54310
 
+SOURCES = $(libsieve_ext_enotify_la_SOURCES)
54311
 
+DIST_SOURCES = $(libsieve_ext_enotify_la_SOURCES)
54312
 
+HEADERS = $(noinst_HEADERS)
54313
 
+ETAGS = etags
54314
 
+CTAGS = ctags
54315
 
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
54316
 
+ACLOCAL = @ACLOCAL@
54317
 
+AMTAR = @AMTAR@
54318
 
+AR = @AR@
54319
 
+AUTOCONF = @AUTOCONF@
54320
 
+AUTOHEADER = @AUTOHEADER@
54321
 
+AUTOMAKE = @AUTOMAKE@
54322
 
+AWK = @AWK@
54323
 
+CC = @CC@
54324
 
+CCDEPMODE = @CCDEPMODE@
54325
 
+CFLAGS = @CFLAGS@
54326
 
+CPP = @CPP@
54327
 
+CPPFLAGS = @CPPFLAGS@
54328
 
+CYGPATH_W = @CYGPATH_W@
54329
 
+DEFS = @DEFS@
54330
 
+DEPDIR = @DEPDIR@
54331
 
+DSYMUTIL = @DSYMUTIL@
54332
 
+DUMPBIN = @DUMPBIN@
54333
 
+ECHO_C = @ECHO_C@
54334
 
+ECHO_N = @ECHO_N@
54335
 
+ECHO_T = @ECHO_T@
54336
 
+EGREP = @EGREP@
54337
 
+EXEEXT = @EXEEXT@
54338
 
+FGREP = @FGREP@
54339
 
+GREP = @GREP@
54340
 
+INSTALL = @INSTALL@
54341
 
+INSTALL_DATA = @INSTALL_DATA@
54342
 
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
54343
 
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
54344
 
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
54345
 
+LD = @LD@
54346
 
+LDFLAGS = @LDFLAGS@
54347
 
+LIBICONV = @LIBICONV@
54348
 
+LIBOBJS = @LIBOBJS@
54349
 
+LIBS = @LIBS@
54350
 
+LIBTOOL = @LIBTOOL@
54351
 
+LIPO = @LIPO@
54352
 
+LN_S = @LN_S@
54353
 
+LTLIBOBJS = @LTLIBOBJS@
54354
 
+MAINT = @MAINT@
54355
 
+MAKEINFO = @MAKEINFO@
54356
 
+MKDIR_P = @MKDIR_P@
54357
 
+MODULE_LIBS = @MODULE_LIBS@
54358
 
+NM = @NM@
54359
 
+NMEDIT = @NMEDIT@
54360
 
+OBJDUMP = @OBJDUMP@
54361
 
+OBJEXT = @OBJEXT@
54362
 
+OTOOL = @OTOOL@
54363
 
+OTOOL64 = @OTOOL64@
54364
 
+PACKAGE = @PACKAGE@
54365
 
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
54366
 
+PACKAGE_NAME = @PACKAGE_NAME@
54367
 
+PACKAGE_STRING = @PACKAGE_STRING@
54368
 
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
54369
 
+PACKAGE_URL = @PACKAGE_URL@
54370
 
+PACKAGE_VERSION = @PACKAGE_VERSION@
54371
 
+PATH_SEPARATOR = @PATH_SEPARATOR@
54372
 
+RAND_LIBS = @RAND_LIBS@
54373
 
+RANLIB = @RANLIB@
54374
 
+SED = @SED@
54375
 
+SET_MAKE = @SET_MAKE@
54376
 
+SHELL = @SHELL@
54377
 
+STORAGE_LIBS = @STORAGE_LIBS@
54378
 
+STRIP = @STRIP@
54379
 
+VERSION = @VERSION@
54380
 
+abs_builddir = @abs_builddir@
54381
 
+abs_srcdir = @abs_srcdir@
54382
 
+abs_top_builddir = @abs_top_builddir@
54383
 
+abs_top_srcdir = @abs_top_srcdir@
54384
 
+ac_ct_CC = @ac_ct_CC@
54385
 
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
54386
 
+am__include = @am__include@
54387
 
+am__leading_dot = @am__leading_dot@
54388
 
+am__quote = @am__quote@
54389
 
+am__tar = @am__tar@
54390
 
+am__untar = @am__untar@
54391
 
+bindir = @bindir@
54392
 
+build = @build@
54393
 
+build_alias = @build_alias@
54394
 
+build_cpu = @build_cpu@
54395
 
+build_os = @build_os@
54396
 
+build_vendor = @build_vendor@
54397
 
+builddir = @builddir@
54398
 
+datadir = @datadir@
54399
 
+datarootdir = @datarootdir@
54400
 
+docdir = @docdir@
54401
 
+dovecot_incdir = @dovecot_incdir@
54402
 
+dovecotdir = @dovecotdir@
54403
 
+dvidir = @dvidir@
54404
 
+exec_prefix = @exec_prefix@
54405
 
+host = @host@
54406
 
+host_alias = @host_alias@
54407
 
+host_cpu = @host_cpu@
54408
 
+host_os = @host_os@
54409
 
+host_vendor = @host_vendor@
54410
 
+htmldir = @htmldir@
54411
 
+includedir = @includedir@
54412
 
+infodir = @infodir@
54413
 
+install_sh = @install_sh@
54414
 
+libdir = @libdir@
54415
 
+libexecdir = @libexecdir@
54416
 
+localedir = @localedir@
54417
 
+localstatedir = @localstatedir@
54418
 
+lt_ECHO = @lt_ECHO@
54419
 
+mandir = @mandir@
54420
 
+mkdir_p = @mkdir_p@
54421
 
+moduledir = @moduledir@
54422
 
+oldincludedir = @oldincludedir@
54423
 
+pdfdir = @pdfdir@
54424
 
+prefix = @prefix@
54425
 
+program_transform_name = @program_transform_name@
54426
 
+psdir = @psdir@
54427
 
+sbindir = @sbindir@
54428
 
+sharedstatedir = @sharedstatedir@
54429
 
+srcdir = @srcdir@
54430
 
+sysconfdir = @sysconfdir@
54431
 
+target_alias = @target_alias@
54432
 
+top_build_prefix = @top_build_prefix@
54433
 
+top_builddir = @top_builddir@
54434
 
+top_srcdir = @top_srcdir@
54435
 
+noinst_LTLIBRARIES = libsieve_ext_enotify.la
54436
 
+AM_CPPFLAGS = \
54437
 
+       -I../../ \
54438
 
+       -I../variables \
54439
 
+       -I$(dovecot_incdir) \
54440
 
+       -I$(dovecot_incdir)/src/lib \
54441
 
+       -I$(dovecot_incdir)/src/lib-mail \
54442
 
+       -I$(dovecot_incdir)/src/lib-storage 
54443
 
+
54444
 
+commands = \
54445
 
+       cmd-notify.c
54446
 
+
54447
 
+tests = \
54448
 
+       tst-valid-notify-method.c \
54449
 
+       tst-notify-method-capability.c
54450
 
+
54451
 
+var_modifiers = \
54452
 
+       vmodf-encodeurl.c
54453
 
+
54454
 
+notify_methods = \
54455
 
+       ntfy-mailto.c
54456
 
+
54457
 
+libsieve_ext_enotify_la_SOURCES = \
54458
 
+       ext-enotify.c \
54459
 
+       ext-enotify-common.c \
54460
 
+       $(commands) \
54461
 
+       $(tests) \
54462
 
+       $(var_modifiers) \
54463
 
+       $(notify_methods)
54464
 
+
54465
 
+noinst_HEADERS = \
54466
 
+       sieve-ext-enotify.h \
54467
 
+       ext-enotify-limits.h \
54468
 
+       ext-enotify-common.h
54469
 
+
54470
 
+all: all-am
54471
 
+
54472
 
+.SUFFIXES:
54473
 
+.SUFFIXES: .c .lo .o .obj
54474
 
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
54475
 
+       @for dep in $?; do \
54476
 
+         case '$(am__configure_deps)' in \
54477
 
+           *$$dep*) \
54478
 
+             ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
54479
 
+               && { if test -f $@; then exit 0; else break; fi; }; \
54480
 
+             exit 1;; \
54481
 
+         esac; \
54482
 
+       done; \
54483
 
+       echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign  src/lib-sieve/plugins/enotify/Makefile'; \
54484
 
+       cd $(top_srcdir) && \
54485
 
+         $(AUTOMAKE) --foreign  src/lib-sieve/plugins/enotify/Makefile
54486
 
+.PRECIOUS: Makefile
54487
 
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
54488
 
+       @case '$?' in \
54489
 
+         *config.status*) \
54490
 
+           cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
54491
 
+         *) \
54492
 
+           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
54493
 
+           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
54494
 
+       esac;
54495
 
+
54496
 
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
54497
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
54498
 
+
54499
 
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
54500
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
54501
 
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
54502
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
54503
 
+
54504
 
+clean-noinstLTLIBRARIES:
54505
 
+       -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
54506
 
+       @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
54507
 
+         dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
54508
 
+         test "$$dir" != "$$p" || dir=.; \
54509
 
+         echo "rm -f \"$${dir}/so_locations\""; \
54510
 
+         rm -f "$${dir}/so_locations"; \
54511
 
+       done
54512
 
+libsieve_ext_enotify.la: $(libsieve_ext_enotify_la_OBJECTS) $(libsieve_ext_enotify_la_DEPENDENCIES) 
54513
 
+       $(LINK)  $(libsieve_ext_enotify_la_OBJECTS) $(libsieve_ext_enotify_la_LIBADD) $(LIBS)
54514
 
+
54515
 
+mostlyclean-compile:
54516
 
+       -rm -f *.$(OBJEXT)
54517
 
+
54518
 
+distclean-compile:
54519
 
+       -rm -f *.tab.c
54520
 
+
54521
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd-notify.Plo@am__quote@
54522
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-enotify-common.Plo@am__quote@
54523
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-enotify.Plo@am__quote@
54524
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ntfy-mailto.Plo@am__quote@
54525
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tst-notify-method-capability.Plo@am__quote@
54526
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tst-valid-notify-method.Plo@am__quote@
54527
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vmodf-encodeurl.Plo@am__quote@
54528
 
+
54529
 
+.c.o:
54530
 
+@am__fastdepCC_TRUE@   $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
54531
 
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
54532
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
54533
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
54534
 
+@am__fastdepCC_FALSE@  $(COMPILE) -c $<
54535
 
+
54536
 
+.c.obj:
54537
 
+@am__fastdepCC_TRUE@   $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
54538
 
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
54539
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
54540
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
54541
 
+@am__fastdepCC_FALSE@  $(COMPILE) -c `$(CYGPATH_W) '$<'`
54542
 
+
54543
 
+.c.lo:
54544
 
+@am__fastdepCC_TRUE@   $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
54545
 
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
54546
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
54547
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
54548
 
+@am__fastdepCC_FALSE@  $(LTCOMPILE) -c -o $@ $<
54549
 
+
54550
 
+mostlyclean-libtool:
54551
 
+       -rm -f *.lo
54552
 
+
54553
 
+clean-libtool:
54554
 
+       -rm -rf .libs _libs
54555
 
+
54556
 
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
54557
 
+       list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
54558
 
+       unique=`for i in $$list; do \
54559
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
54560
 
+         done | \
54561
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
54562
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
54563
 
+       mkid -fID $$unique
54564
 
+tags: TAGS
54565
 
+
54566
 
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
54567
 
+               $(TAGS_FILES) $(LISP)
54568
 
+       tags=; \
54569
 
+       here=`pwd`; \
54570
 
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
54571
 
+       unique=`for i in $$list; do \
54572
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
54573
 
+         done | \
54574
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
54575
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
54576
 
+       if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
54577
 
+         test -n "$$unique" || unique=$$empty_fix; \
54578
 
+         $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
54579
 
+           $$tags $$unique; \
54580
 
+       fi
54581
 
+ctags: CTAGS
54582
 
+CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
54583
 
+               $(TAGS_FILES) $(LISP)
54584
 
+       tags=; \
54585
 
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
54586
 
+       unique=`for i in $$list; do \
54587
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
54588
 
+         done | \
54589
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
54590
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
54591
 
+       test -z "$(CTAGS_ARGS)$$tags$$unique" \
54592
 
+         || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
54593
 
+            $$tags $$unique
54594
 
+
54595
 
+GTAGS:
54596
 
+       here=`$(am__cd) $(top_builddir) && pwd` \
54597
 
+         && cd $(top_srcdir) \
54598
 
+         && gtags -i $(GTAGS_ARGS) $$here
54599
 
+
54600
 
+distclean-tags:
54601
 
+       -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
54602
 
+
54603
 
+distdir: $(DISTFILES)
54604
 
+       @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
54605
 
+       topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
54606
 
+       list='$(DISTFILES)'; \
54607
 
+         dist_files=`for file in $$list; do echo $$file; done | \
54608
 
+         sed -e "s|^$$srcdirstrip/||;t" \
54609
 
+             -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
54610
 
+       case $$dist_files in \
54611
 
+         */*) $(MKDIR_P) `echo "$$dist_files" | \
54612
 
+                          sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
54613
 
+                          sort -u` ;; \
54614
 
+       esac; \
54615
 
+       for file in $$dist_files; do \
54616
 
+         if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
54617
 
+         if test -d $$d/$$file; then \
54618
 
+           dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
54619
 
+           if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
54620
 
+             cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
54621
 
+           fi; \
54622
 
+           cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
54623
 
+         else \
54624
 
+           test -f $(distdir)/$$file \
54625
 
+           || cp -p $$d/$$file $(distdir)/$$file \
54626
 
+           || exit 1; \
54627
 
+         fi; \
54628
 
+       done
54629
 
+check-am: all-am
54630
 
+check: check-am
54631
 
+all-am: Makefile $(LTLIBRARIES) $(HEADERS)
54632
 
+installdirs:
54633
 
+install: install-am
54634
 
+install-exec: install-exec-am
54635
 
+install-data: install-data-am
54636
 
+uninstall: uninstall-am
54637
 
+
54638
 
+install-am: all-am
54639
 
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
54640
 
+
54641
 
+installcheck: installcheck-am
54642
 
+install-strip:
54643
 
+       $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
54644
 
+         install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
54645
 
+         `test -z '$(STRIP)' || \
54646
 
+           echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
54647
 
+mostlyclean-generic:
54648
 
+
54649
 
+clean-generic:
54650
 
+
54651
 
+distclean-generic:
54652
 
+       -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
54653
 
+
54654
 
+maintainer-clean-generic:
54655
 
+       @echo "This command is intended for maintainers to use"
54656
 
+       @echo "it deletes files that may require special tools to rebuild."
54657
 
+clean: clean-am
54658
 
+
54659
 
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
54660
 
+       mostlyclean-am
54661
 
+
54662
 
+distclean: distclean-am
54663
 
+       -rm -rf ./$(DEPDIR)
54664
 
+       -rm -f Makefile
54665
 
+distclean-am: clean-am distclean-compile distclean-generic \
54666
 
+       distclean-tags
54667
 
+
54668
 
+dvi: dvi-am
54669
 
+
54670
 
+dvi-am:
54671
 
+
54672
 
+html: html-am
54673
 
+
54674
 
+info: info-am
54675
 
+
54676
 
+info-am:
54677
 
+
54678
 
+install-data-am:
54679
 
+
54680
 
+install-dvi: install-dvi-am
54681
 
+
54682
 
+install-exec-am:
54683
 
+
54684
 
+install-html: install-html-am
54685
 
+
54686
 
+install-info: install-info-am
54687
 
+
54688
 
+install-man:
54689
 
+
54690
 
+install-pdf: install-pdf-am
54691
 
+
54692
 
+install-ps: install-ps-am
54693
 
+
54694
 
+installcheck-am:
54695
 
+
54696
 
+maintainer-clean: maintainer-clean-am
54697
 
+       -rm -rf ./$(DEPDIR)
54698
 
+       -rm -f Makefile
54699
 
+maintainer-clean-am: distclean-am maintainer-clean-generic
54700
 
+
54701
 
+mostlyclean: mostlyclean-am
54702
 
+
54703
 
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
54704
 
+       mostlyclean-libtool
54705
 
+
54706
 
+pdf: pdf-am
54707
 
+
54708
 
+pdf-am:
54709
 
+
54710
 
+ps: ps-am
54711
 
+
54712
 
+ps-am:
54713
 
+
54714
 
+uninstall-am:
54715
 
+
54716
 
+.MAKE: install-am install-strip
54717
 
+
54718
 
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
54719
 
+       clean-libtool clean-noinstLTLIBRARIES ctags distclean \
54720
 
+       distclean-compile distclean-generic distclean-libtool \
54721
 
+       distclean-tags distdir dvi dvi-am html html-am info info-am \
54722
 
+       install install-am install-data install-data-am install-dvi \
54723
 
+       install-dvi-am install-exec install-exec-am install-html \
54724
 
+       install-html-am install-info install-info-am install-man \
54725
 
+       install-pdf install-pdf-am install-ps install-ps-am \
54726
 
+       install-strip installcheck installcheck-am installdirs \
54727
 
+       maintainer-clean maintainer-clean-generic mostlyclean \
54728
 
+       mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
54729
 
+       pdf pdf-am ps ps-am tags uninstall uninstall-am
54730
 
+
54731
 
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
54732
 
+# Otherwise a system limit (for SysV at least) may be exceeded.
54733
 
+.NOEXPORT:
54734
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/enotify/ntfy-mailto.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/enotify/ntfy-mailto.c
54735
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/enotify/ntfy-mailto.c  1970-01-01 01:00:00.000000000 +0100
54736
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/enotify/ntfy-mailto.c   2009-07-21 03:15:57.000000000 +0200
54737
 
@@ -0,0 +1,1104 @@
54738
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file 
54739
 
+ */
54740
 
54741
 
+/* Notify method mailto
54742
 
+ * --------------------
54743
 
+ *
54744
 
+ * Authors: Stephan Bosch
54745
 
+ * Specification: RFC 5436
54746
 
+ * Implementation: full
54747
 
+ * Status: testing
54748
 
+ * 
54749
 
+ */
54750
 
54751
 
+/* FIXME: URI syntax conforms to something somewhere in between RFC 2368 and
54752
 
+ *   draft-duerst-mailto-bis-05.txt. Should fully migrate to new specification
54753
 
+ *   when it matures. This requires modifications to the address parser (no
54754
 
+ *   whitespace allowed within the address itself) and UTF-8 support will be
54755
 
+ *   required in the URL.
54756
 
+ */
54757
 
54758
 
+#include "lib.h"
54759
 
+#include "array.h"
54760
 
+#include "str.h"
54761
 
+#include "ioloop.h"
54762
 
+#include "str-sanitize.h"
54763
 
+#include "message-date.h"
54764
 
+#include "mail-storage.h"
54765
 
+
54766
 
+#include "rfc2822.h"
54767
 
+
54768
 
+#include "sieve-ext-enotify.h"
54769
 
+#include "sieve-address.h"
54770
 
+#include "sieve-message.h"
54771
 
+
54772
 
+/*
54773
 
+ * Configuration
54774
 
+ */
54775
 
54776
 
+#define NTFY_MAILTO_MAX_RECIPIENTS  8
54777
 
+#define NTFY_MAILTO_MAX_HEADERS     16
54778
 
+#define NTFY_MAILTO_MAX_SUBJECT     256
54779
 
+
54780
 
+/* 
54781
 
+ * Types 
54782
 
+ */
54783
 
+
54784
 
+struct ntfy_mailto_header_field {
54785
 
+       const char *name;
54786
 
+       const char *body;
54787
 
+};
54788
 
+
54789
 
+struct ntfy_mailto_recipient {
54790
 
+       const char *full;
54791
 
+       const char *normalized;
54792
 
+       bool carbon_copy;
54793
 
+};
54794
 
+
54795
 
+ARRAY_DEFINE_TYPE(recipients, struct ntfy_mailto_recipient);
54796
 
+ARRAY_DEFINE_TYPE(headers, struct ntfy_mailto_header_field);
54797
 
+
54798
 
+/* 
54799
 
+ * Mailto notification method
54800
 
+ */
54801
 
54802
 
+static bool ntfy_mailto_compile_check_uri
54803
 
+       (const struct sieve_enotify_log *nlog, const char *uri, const char *uri_body);
54804
 
+static bool ntfy_mailto_compile_check_from
54805
 
+       (const struct sieve_enotify_log *nlog, string_t *from);
54806
 
+
54807
 
+static const char *ntfy_mailto_runtime_get_notify_capability
54808
 
+       (const struct sieve_enotify_log *nlog, const char *uri, const char *uri_body, 
54809
 
+               const char *capability);
54810
 
+static bool ntfy_mailto_runtime_check_uri
54811
 
+       (const struct sieve_enotify_log *nlog, const char *uri, const char *uri_body);
54812
 
+static bool ntfy_mailto_runtime_check_operands
54813
 
+       (const struct sieve_enotify_log *nlog, const char *uri,const char *uri_body, 
54814
 
+               string_t *message, string_t *from, pool_t context_pool, 
54815
 
+               void **method_context);
54816
 
+
54817
 
+static int ntfy_mailto_action_check_duplicates
54818
 
+       (const struct sieve_enotify_log *nlog, void *method_ctx1, void *method_ctx2,
54819
 
+               const char *dupl_location);
54820
 
+
54821
 
+static void ntfy_mailto_action_print
54822
 
+       (const struct sieve_enotify_print_env *penv, 
54823
 
+               const struct sieve_enotify_action *act);        
54824
 
+
54825
 
+static bool ntfy_mailto_action_execute
54826
 
+       (const struct sieve_enotify_exec_env *nenv, 
54827
 
+               const struct sieve_enotify_action *act);
54828
 
+
54829
 
+const struct sieve_enotify_method mailto_notify = {
54830
 
+       "mailto",
54831
 
+       ntfy_mailto_compile_check_uri,
54832
 
+       NULL,
54833
 
+       ntfy_mailto_compile_check_from,
54834
 
+       NULL,
54835
 
+       ntfy_mailto_runtime_check_uri,
54836
 
+       ntfy_mailto_runtime_get_notify_capability,
54837
 
+       ntfy_mailto_runtime_check_operands,
54838
 
+       NULL,
54839
 
+       ntfy_mailto_action_check_duplicates,
54840
 
+       ntfy_mailto_action_print,
54841
 
+       ntfy_mailto_action_execute
54842
 
+};
54843
 
+
54844
 
+/*
54845
 
+ * Method context data
54846
 
+ */
54847
 
54848
 
+struct ntfy_mailto_context {
54849
 
+       ARRAY_TYPE(recipients) recipients;
54850
 
+       ARRAY_TYPE(headers) headers;
54851
 
+       const char *subject;
54852
 
+       const char *body;
54853
 
+       const char *from_normalized;
54854
 
+};
54855
 
+
54856
 
+/*
54857
 
+ * Reserved headers
54858
 
+ */
54859
 
54860
 
+static const char *_reserved_headers[] = {
54861
 
+       "auto-submitted",
54862
 
+       "received",
54863
 
+       "message-id",
54864
 
+       "data",
54865
 
+       "bcc",
54866
 
+       "in-reply-to",
54867
 
+       "references",
54868
 
+       "resent-date",
54869
 
+       "resent-from",
54870
 
+       "resent-sender",
54871
 
+       "resent-to",
54872
 
+       "resent-cc",
54873
 
+       "resent-bcc",
54874
 
+       "resent-msg-id",
54875
 
+       "from",
54876
 
+       "sender",
54877
 
+       NULL
54878
 
+};
54879
 
+
54880
 
+static const char *_unique_headers[] = {
54881
 
+       "reply-to",
54882
 
+       NULL
54883
 
+};
54884
 
+
54885
 
+static inline bool _ntfy_mailto_header_allowed(const char *field_name)
54886
 
+{
54887
 
+       const char **rhdr = _reserved_headers;
54888
 
+
54889
 
+       /* Check whether it is reserved */
54890
 
+       while ( *rhdr != NULL ) {
54891
 
+               if ( strcasecmp(field_name, *rhdr) == 0 )
54892
 
+                       return FALSE;
54893
 
+               rhdr++;
54894
 
+       }
54895
 
+
54896
 
+       return TRUE;
54897
 
+}
54898
 
+
54899
 
+static inline bool _ntfy_mailto_header_unique(const char *field_name)
54900
 
+{
54901
 
+       const char **rhdr = _unique_headers;
54902
 
+
54903
 
+       /* Check whether it is supposed to be unique */
54904
 
+       while ( *rhdr != NULL ) {
54905
 
+               if ( strcasecmp(field_name, *rhdr) == 0 )
54906
 
+                       return TRUE;
54907
 
+               rhdr++;
54908
 
+       }
54909
 
+
54910
 
+       return FALSE;
54911
 
+}
54912
 
+
54913
 
+/*
54914
 
+ * Mailto URI parsing
54915
 
+ */
54916
 
54917
 
+/* Util functions */
54918
 
+
54919
 
+#define _uri_parse_error(LOG, ...) \
54920
 
+       sieve_enotify_error(LOG, "invalid mailto URI: " __VA_ARGS__ )
54921
 
+       
54922
 
+#define _uri_parse_warning(LOG, ...) \
54923
 
+       sieve_enotify_warning(LOG, "mailto URI: " __VA_ARGS__ )
54924
 
+
54925
 
+/* FIXME: much of this implementation will be common to other URI schemes. This
54926
 
+ *        should be merged into a common implementation.
54927
 
+ */
54928
 
+
54929
 
+static const char _qchar_lookup[256] = {
54930
 
+       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 00
54931
 
+       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 10
54932
 
+       0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0,  // 20
54933
 
+       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0,  // 30
54934
 
+       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 40
54935
 
+       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,  // 50
54936
 
+       0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 60
54937
 
+       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0,  // 70
54938
 
+
54939
 
+       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 80
54940
 
+       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 90
54941
 
+       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // A0
54942
 
+       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // B0
54943
 
+       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // C0
54944
 
+       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // D0
54945
 
+       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // E0
54946
 
+       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // F0
54947
 
+};
54948
 
+
54949
 
+static inline bool _is_qchar(unsigned char c)
54950
 
+{
54951
 
+       return _qchar_lookup[c];
54952
 
+}
54953
 
+  
54954
 
+static inline int _decode_hex_digit(char digit)
54955
 
+{
54956
 
+       switch ( digit ) {
54957
 
+       case '0': case '1': case '2': case '3': case '4': 
54958
 
+       case '5': case '6': case '7': case '8': case '9': 
54959
 
+               return (int) digit - '0';
54960
 
+
54961
 
+       case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
54962
 
+               return (int) digit - 'a' + 0x0a;
54963
 
+               
54964
 
+       case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
54965
 
+               return (int) digit - 'A' + 0x0A;
54966
 
+       }
54967
 
+       
54968
 
+       return -1;
54969
 
+}
54970
 
+
54971
 
+static bool _parse_hex_value(const char **in, char *out)
54972
 
+{
54973
 
+       char value;
54974
 
+               
54975
 
+       if ( **in == '\0' || (value=_decode_hex_digit(**in)) < 0 )
54976
 
+               return FALSE;
54977
 
+       
54978
 
+       *out = value << 4;
54979
 
+       (*in)++;
54980
 
+       
54981
 
+       if ( **in == '\0' || (value=_decode_hex_digit(**in)) < 0 )
54982
 
+               return FALSE;   
54983
 
+
54984
 
+       *out |= value;
54985
 
+       (*in)++;
54986
 
+       return (*out != '\0');  
54987
 
+}
54988
 
+
54989
 
+static bool _uri_add_valid_recipient
54990
 
+(const struct sieve_enotify_log *nlog, ARRAY_TYPE(recipients) *recipients, 
54991
 
+       string_t *recipient, bool cc)
54992
 
+{
54993
 
+       const char *error;
54994
 
+       const char *normalized;
54995
 
+        
54996
 
+       /* Verify recipient */
54997
 
+       if ( (normalized=sieve_address_normalize(recipient, &error)) == NULL ) {
54998
 
+               _uri_parse_error(nlog, "invalid recipient '%s': %s",
54999
 
+                       str_sanitize(str_c(recipient), 80), error);
55000
 
+               return FALSE;
55001
 
+       }
55002
 
+                                       
55003
 
+       /* Add recipient to the list */
55004
 
+       if ( recipients != NULL ) {
55005
 
+               struct ntfy_mailto_recipient *new_recipient;
55006
 
+               struct ntfy_mailto_recipient *rcpts;
55007
 
+               unsigned int count, i;
55008
 
+               pool_t pool;
55009
 
+
55010
 
+               rcpts = array_get_modifiable(recipients, &count);
55011
 
+               
55012
 
+               /* Enforce limits */
55013
 
+               if ( count >= NTFY_MAILTO_MAX_RECIPIENTS ) {
55014
 
+                       if ( count == NTFY_MAILTO_MAX_RECIPIENTS ) {
55015
 
+                               _uri_parse_warning(nlog, 
55016
 
+                                       "more than the maximum %u recipients specified; "
55017
 
+                                       "rest is discarded", NTFY_MAILTO_MAX_RECIPIENTS);
55018
 
+                       }
55019
 
+                       return TRUE;    
55020
 
+               }
55021
 
+               
55022
 
+               /* Check for duplicate first */
55023
 
+               for ( i = 0; i < count; i++ ) {
55024
 
+                       if ( sieve_address_compare(rcpts[i].normalized, normalized, TRUE) == 0 ) 
55025
 
+                               {
55026
 
+                               /* Upgrade existing Cc: recipient to a To: recipient if possible */
55027
 
+                               rcpts[i].carbon_copy = ( rcpts[i].carbon_copy && cc );
55028
 
+                               
55029
 
+                               _uri_parse_warning(nlog, "ignored duplicate recipient '%s'",
55030
 
+                                       str_sanitize(str_c(recipient), 80));
55031
 
+                               return TRUE;
55032
 
+                       } 
55033
 
+               }                       
55034
 
+
55035
 
+               /* Add */
55036
 
+               pool = array_get_pool(recipients);
55037
 
+               new_recipient = array_append_space(recipients);
55038
 
+               new_recipient->carbon_copy = cc;
55039
 
+               new_recipient->full = p_strdup(pool, str_c(recipient));
55040
 
+               new_recipient->normalized = p_strdup(pool, normalized);
55041
 
+       }
55042
 
+
55043
 
+       return TRUE;
55044
 
+}
55045
 
+
55046
 
+static bool _uri_parse_recipients
55047
 
+(const struct sieve_enotify_log *nlog, const char **uri_p, 
55048
 
+       ARRAY_TYPE(recipients) *recipients_r)
55049
 
+{
55050
 
+       string_t *to = t_str_new(128);
55051
 
+       const char *p = *uri_p;
55052
 
+       
55053
 
+       if ( *p == '\0' || *p == '?' )
55054
 
+               return TRUE;
55055
 
+               
55056
 
+       while ( *p != '\0' && *p != '?' ) {
55057
 
+               if ( *p == '%' ) {
55058
 
+                       /* % encoded character */
55059
 
+                       char ch;
55060
 
+                       
55061
 
+                       p++;
55062
 
+                       
55063
 
+                       /* Parse 2-digit hex value */
55064
 
+                       if ( !_parse_hex_value(&p, &ch) ) {
55065
 
+                               _uri_parse_error(nlog, "invalid %% encoding");
55066
 
+                               return FALSE;
55067
 
+                       }
55068
 
+
55069
 
+                       /* Check for delimiter */
55070
 
+                       if ( ch == ',' ) {
55071
 
+                               /* Verify and add recipient */
55072
 
+                               if ( !_uri_add_valid_recipient(nlog, recipients_r, to, FALSE) )
55073
 
+                                       return FALSE;
55074
 
+                       
55075
 
+                               /* Reset for next recipient */
55076
 
+                               str_truncate(to, 0);
55077
 
+                       }       else {
55078
 
+                               /* Content character */
55079
 
+                               str_append_c(to, ch);
55080
 
+                       }
55081
 
+               } else {
55082
 
+                       if ( *p == ':' || *p == ';' || *p == ',' || !_is_qchar(*p) ) {
55083
 
+                               _uri_parse_error
55084
 
+                                       (nlog, "invalid character '%c' in 'to' part", *p);
55085
 
+                               return FALSE;
55086
 
+                       }
55087
 
+
55088
 
+                       /* Content character */
55089
 
+                       str_append_c(to, *p);
55090
 
+                       p++;
55091
 
+               }
55092
 
+       }       
55093
 
+       
55094
 
+       /* Skip '?' */
55095
 
+       if ( *p != '\0' ) p++;
55096
 
+       
55097
 
+       /* Verify and add recipient */
55098
 
+       if ( !_uri_add_valid_recipient(nlog, recipients_r, to, FALSE) )
55099
 
+               return FALSE;
55100
 
+
55101
 
+       *uri_p = p;
55102
 
+       return TRUE;
55103
 
+}
55104
 
+
55105
 
+static bool _uri_parse_header_recipients
55106
 
+(const struct sieve_enotify_log *nlog, string_t *rcpt_header, 
55107
 
+       ARRAY_TYPE(recipients) *recipients_r, bool cc)
55108
 
+{
55109
 
+       string_t *to = t_str_new(128);
55110
 
+       const char *p = (const char *) str_data(rcpt_header);
55111
 
+       const char *pend = p + str_len(rcpt_header);
55112
 
+               
55113
 
+       while ( p < pend ) {
55114
 
+               if ( *p == ',' ) {
55115
 
+                       /* Verify and add recipient */
55116
 
+                       if ( !_uri_add_valid_recipient(nlog, recipients_r, to, cc) )
55117
 
+                               return FALSE;
55118
 
+                       
55119
 
+                       /* Reset for next recipient */
55120
 
+                       str_truncate(to, 0);
55121
 
+               } else {
55122
 
+                       /* Content character */
55123
 
+                       str_append_c(to, *p);
55124
 
+               }
55125
 
+               p++;
55126
 
+       }       
55127
 
+       
55128
 
+       /* Verify and add recipient */
55129
 
+       if ( !_uri_add_valid_recipient(nlog, recipients_r, to, cc) )
55130
 
+               return FALSE;
55131
 
+
55132
 
+       return TRUE;    
55133
 
+}
55134
 
+
55135
 
+static bool _uri_header_is_duplicate
55136
 
+(ARRAY_TYPE(headers) *headers, const char *field_name)
55137
 
+{      
55138
 
+       if ( _ntfy_mailto_header_unique(field_name) ) {
55139
 
+               const struct ntfy_mailto_header_field *hdrs;
55140
 
+               unsigned int count, i;
55141
 
+
55142
 
+               hdrs = array_get(headers, &count);      
55143
 
+               for ( i = 0; i < count; i++ ) {
55144
 
+                       if ( strcasecmp(hdrs[i].name, field_name) == 0 ) 
55145
 
+                               return TRUE;
55146
 
+               }
55147
 
+       }
55148
 
+       
55149
 
+       return FALSE;
55150
 
+}
55151
 
+
55152
 
+static bool _uri_parse_headers
55153
 
+(const struct sieve_enotify_log *nlog, const char **uri_p, 
55154
 
+       ARRAY_TYPE(headers) *headers_r, ARRAY_TYPE(recipients) *recipients_r,
55155
 
+       const char **body, const char **subject)
55156
 
+{
55157
 
+       unsigned int header_count = 0;
55158
 
+       string_t *field = t_str_new(128);
55159
 
+       const char *p = *uri_p;
55160
 
+       pool_t pool = NULL;
55161
 
+
55162
 
+       if ( body != NULL )
55163
 
+               *body = NULL;
55164
 
+               
55165
 
+       if ( subject != NULL )
55166
 
+               *subject = NULL;
55167
 
+                       
55168
 
+       if ( headers_r != NULL )
55169
 
+               pool = array_get_pool(headers_r);
55170
 
+               
55171
 
+       while ( *p != '\0' ) {
55172
 
+               enum {
55173
 
+                       _HNAME_IGNORED, 
55174
 
+                       _HNAME_GENERIC,
55175
 
+                       _HNAME_TO,
55176
 
+                       _HNAME_CC,
55177
 
+                       _HNAME_SUBJECT, 
55178
 
+                       _HNAME_BODY 
55179
 
+               } hname_type = _HNAME_GENERIC;
55180
 
+               struct ntfy_mailto_header_field *hdrf = NULL;
55181
 
+               const char *field_name;
55182
 
+               
55183
 
+               /* Parse field name */
55184
 
+               while ( *p != '\0' && *p != '=' ) {
55185
 
+                       char ch = *p;
55186
 
+                       p++;
55187
 
+                       
55188
 
+                       if ( ch == '%' ) {
55189
 
+                               /* Encoded, parse 2-digit hex value */
55190
 
+                               if ( !_parse_hex_value(&p, &ch) ) {
55191
 
+                                       _uri_parse_error(nlog, "invalid %% encoding");
55192
 
+                                       return FALSE;
55193
 
+                               }
55194
 
+                       } else if ( ch != '=' && !_is_qchar(ch) ) {
55195
 
+                               _uri_parse_error
55196
 
+                                       (nlog, "invalid character '%c' in header field name part", ch);
55197
 
+                               return FALSE;
55198
 
+                       }
55199
 
+
55200
 
+                       str_append_c(field, ch);
55201
 
+               }
55202
 
+               if ( *p != '\0' ) p++;
55203
 
+
55204
 
+               /* Verify field name */
55205
 
+               if ( !rfc2822_header_field_name_verify(str_c(field), str_len(field)) ) {
55206
 
+                       _uri_parse_error(nlog, "invalid header field name");
55207
 
+                       return FALSE;
55208
 
+               }
55209
 
+
55210
 
+               if ( header_count >= NTFY_MAILTO_MAX_HEADERS ) {
55211
 
+                       /* Refuse to accept more headers than allowed by policy */
55212
 
+                       if ( header_count == NTFY_MAILTO_MAX_HEADERS ) {
55213
 
+                               _uri_parse_warning(nlog, "more than the maximum %u headers specified; "
55214
 
+                                       "rest is discarded", NTFY_MAILTO_MAX_HEADERS);
55215
 
+                       }
55216
 
+                       
55217
 
+                       hname_type = _HNAME_IGNORED;
55218
 
+               } else {
55219
 
+                       /* Add new header field to array and assign its name */
55220
 
+                       
55221
 
+                       field_name = str_c(field);
55222
 
+                       if ( strcasecmp(field_name, "to") == 0 )
55223
 
+                               hname_type = _HNAME_TO;
55224
 
+                       else if ( strcasecmp(field_name, "cc") == 0 )
55225
 
+                               hname_type = _HNAME_CC;
55226
 
+                       else if ( strcasecmp(field_name, "subject") == 0 )
55227
 
+                               hname_type = _HNAME_SUBJECT;
55228
 
+                       else if ( strcasecmp(field_name, "body") == 0 )
55229
 
+                               hname_type = _HNAME_BODY;
55230
 
+                       else if ( _ntfy_mailto_header_allowed(field_name) ) {
55231
 
+                               if ( headers_r != NULL ) {
55232
 
+                                       if ( !_uri_header_is_duplicate(headers_r, field_name) ) {
55233
 
+                                               hdrf = array_append_space(headers_r);
55234
 
+                                               hdrf->name = p_strdup(pool, field_name);
55235
 
+                                       } else {
55236
 
+                                               _uri_parse_warning(nlog, 
55237
 
+                                                       "ignored duplicate for unique header field '%s'",
55238
 
+                                                       str_sanitize(field_name, 32));
55239
 
+                                               hname_type = _HNAME_IGNORED;
55240
 
+                                       }
55241
 
+                               } else {
55242
 
+                                       hname_type = _HNAME_IGNORED;
55243
 
+                               }
55244
 
+                       } else {
55245
 
+                               _uri_parse_warning(nlog, "ignored reserved header field '%s'",
55246
 
+                                       str_sanitize(field_name, 32));
55247
 
+                               hname_type = _HNAME_IGNORED;
55248
 
+                       }
55249
 
+               }
55250
 
+               
55251
 
+               header_count++;
55252
 
+                       
55253
 
+               /* Reset for field body */
55254
 
+               str_truncate(field, 0);
55255
 
+               
55256
 
+               /* Parse field body */          
55257
 
+               while ( *p != '\0' && *p != '&' ) {
55258
 
+                       char ch = *p;
55259
 
+                       p++;
55260
 
+                       
55261
 
+                       if ( ch == '%' ) {
55262
 
+                               /* Encoded, parse 2-digit hex value */
55263
 
+                               if ( !_parse_hex_value(&p, &ch) ) {
55264
 
+                                       _uri_parse_error(nlog, "invalid %% encoding");
55265
 
+                                       return FALSE;
55266
 
+                               }
55267
 
+                       } else if ( ch != '=' && !_is_qchar(ch) ) {
55268
 
+                               _uri_parse_error
55269
 
+                                       (nlog, "invalid character '%c' in header field value part", ch);
55270
 
+                               return FALSE;
55271
 
+                       }
55272
 
+                       str_append_c(field, ch);
55273
 
+               }
55274
 
+               if ( *p != '\0' ) p++;
55275
 
+               
55276
 
+               /* Verify field body */
55277
 
+               if ( hname_type == _HNAME_BODY ) {
55278
 
+                       // FIXME: verify body ... 
55279
 
+               } else {
55280
 
+                       if ( !rfc2822_header_field_body_verify(str_c(field), str_len(field)) ) {
55281
 
+                               _uri_parse_error
55282
 
+                                       (nlog, "invalid header field body");
55283
 
+                               return FALSE;
55284
 
+                       }
55285
 
+               }
55286
 
+               
55287
 
+               /* Assign field body */
55288
 
+
55289
 
+               switch ( hname_type ) {
55290
 
+               case _HNAME_IGNORED:
55291
 
+                       break;
55292
 
+               case _HNAME_TO:
55293
 
+                       /* Gracefully allow duplicate To fields */
55294
 
+                       if ( !_uri_parse_header_recipients(nlog, field, recipients_r, FALSE) )
55295
 
+                               return FALSE;
55296
 
+                       break;
55297
 
+               case _HNAME_CC:
55298
 
+                       /* Gracefully allow duplicate Cc fields */
55299
 
+                       if ( !_uri_parse_header_recipients(nlog, field, recipients_r, TRUE) )
55300
 
+                               return FALSE;
55301
 
+                       break;
55302
 
+               case _HNAME_SUBJECT:
55303
 
+                       if ( subject != NULL ) {
55304
 
+                               /* Igore duplicate subject field */
55305
 
+                               if ( *subject == NULL )
55306
 
+                                       *subject = p_strdup(pool, str_c(field));
55307
 
+                               else
55308
 
+                                       _uri_parse_warning(nlog, "ignored duplicate subject field");
55309
 
+                       }
55310
 
+                       break;
55311
 
+               case _HNAME_BODY:
55312
 
+                       if ( body != NULL ) {
55313
 
+                               /* Igore duplicate body field */
55314
 
+                               if ( *body == NULL )
55315
 
+                                       *body = p_strdup(pool, str_c(field));
55316
 
+                               else 
55317
 
+                                       _uri_parse_warning(nlog, "ignored duplicate body field");
55318
 
+                       }                               
55319
 
+                       break;
55320
 
+               case _HNAME_GENERIC:
55321
 
+                       if ( hdrf != NULL ) 
55322
 
+                               hdrf->body = p_strdup(pool, str_c(field));
55323
 
+                       break;
55324
 
+               }
55325
 
+                       
55326
 
+               /* Reset for next name */
55327
 
+               str_truncate(field, 0);
55328
 
+       }       
55329
 
+       
55330
 
+       /* Skip '&' */
55331
 
+       if ( *p != '\0' ) p++;
55332
 
+
55333
 
+       *uri_p = p;
55334
 
+       return TRUE;
55335
 
+}
55336
 
+
55337
 
+static bool ntfy_mailto_parse_uri
55338
 
+(const struct sieve_enotify_log *nlog, const char *uri_body, 
55339
 
+       ARRAY_TYPE(recipients) *recipients_r, ARRAY_TYPE(headers) *headers_r,
55340
 
+       const char **body, const char **subject)
55341
 
+{
55342
 
+       const char *p = uri_body;
55343
 
+       
55344
 
+       /* 
55345
 
+        * mailtoURI   = "mailto:" [ to ] [ hfields ]
55346
 
+        * to          = [ addr-spec *("%2C" addr-spec ) ]
55347
 
+        * hfields     = "?" hfield *( "&" hfield )
55348
 
+        * hfield      = hfname "=" hfvalue
55349
 
+        * hfname      = *qchar
55350
 
+        * hfvalue     = *qchar
55351
 
+        * addr-spec   = local-part "@" domain
55352
 
+        * local-part  = dot-atom / quoted-string
55353
 
+        * qchar       = unreserved / pct-encoded / some-delims
55354
 
+        * some-delims = "!" / "$" / "'" / "(" / ")" / "*"
55355
 
+        *               / "+" / "," / ";" / ":" / "@"
55356
 
+        *
55357
 
+        * to         ~= *tqchar
55358
 
+        * tqchar     ~= <qchar> without ";" and ":" 
55359
 
+        * 
55360
 
+        * Scheme 'mailto:' already parsed, starting parse after colon
55361
 
+        */
55362
 
+
55363
 
+       /* First extract to-part by searching for '?' and decoding % items
55364
 
+        */
55365
 
+
55366
 
+       if ( !_uri_parse_recipients(nlog, &p, recipients_r) )
55367
 
+               return FALSE;   
55368
 
+
55369
 
+       /* Extract hfield items */      
55370
 
+       
55371
 
+       while ( *p != '\0' ) {          
55372
 
+               /* Extract hfield item by searching for '&' and decoding '%' items */
55373
 
+               if ( !_uri_parse_headers(nlog, &p, headers_r, recipients_r, body, subject) )
55374
 
+                       return FALSE;           
55375
 
+       }
55376
 
+       
55377
 
+       return TRUE;
55378
 
+}
55379
 
+
55380
 
+/*
55381
 
+ * Validation
55382
 
+ */
55383
 
+
55384
 
+static bool ntfy_mailto_compile_check_uri
55385
 
+(const struct sieve_enotify_log *nlog, const char *uri ATTR_UNUSED,
55386
 
+       const char *uri_body)
55387
 
+{      
55388
 
+       ARRAY_TYPE(recipients) recipients;
55389
 
+       ARRAY_TYPE(headers) headers;
55390
 
+       const char *body = NULL, *subject = NULL;
55391
 
+
55392
 
+       t_array_init(&recipients, NTFY_MAILTO_MAX_RECIPIENTS);
55393
 
+       t_array_init(&headers, NTFY_MAILTO_MAX_HEADERS);
55394
 
+       
55395
 
+       if ( !ntfy_mailto_parse_uri
55396
 
+               (nlog, uri_body, &recipients, &headers, &body, &subject) )
55397
 
+               return FALSE;
55398
 
+               
55399
 
+       if ( array_count(&recipients) == 0 )
55400
 
+               sieve_enotify_warning(nlog, "notification URI specifies no recipients");
55401
 
+       
55402
 
+       return TRUE;
55403
 
+}
55404
 
+
55405
 
+static bool ntfy_mailto_compile_check_from
55406
 
+(const struct sieve_enotify_log *nlog, string_t *from)
55407
 
+{
55408
 
+       const char *error;
55409
 
+       bool result = FALSE;
55410
 
+
55411
 
+       T_BEGIN {
55412
 
+               result = sieve_address_validate(from, &error);
55413
 
+
55414
 
+               if ( !result ) {
55415
 
+                       sieve_enotify_error(nlog,
55416
 
+                               "specified :from address '%s' is invalid for "
55417
 
+                               "the mailto method: %s",
55418
 
+                               str_sanitize(str_c(from), 128), error);
55419
 
+               }
55420
 
+       } T_END;
55421
 
+
55422
 
+       return result;
55423
 
+}
55424
 
+
55425
 
+/*
55426
 
+ * Runtime
55427
 
+ */
55428
 
55429
 
+static const char *ntfy_mailto_runtime_get_notify_capability
55430
 
+(const struct sieve_enotify_log *nlog ATTR_UNUSED, const char *uri ATTR_UNUSED, 
55431
 
+       const char *uri_body, const char *capability)
55432
 
+{
55433
 
+       if ( !ntfy_mailto_parse_uri(NULL, uri_body, NULL, NULL, NULL, NULL) ) {
55434
 
+               return NULL;
55435
 
+       }
55436
 
+       
55437
 
+       if ( strcasecmp(capability, "online") == 0 ) 
55438
 
+               return "maybe";
55439
 
+       
55440
 
+       return NULL;
55441
 
+}
55442
 
+
55443
 
+static bool ntfy_mailto_runtime_check_uri
55444
 
+(const struct sieve_enotify_log *nlog ATTR_UNUSED, const char *uri ATTR_UNUSED,
55445
 
+       const char *uri_body)
55446
 
+{
55447
 
+       return ntfy_mailto_parse_uri(NULL, uri_body, NULL, NULL, NULL, NULL);
55448
 
+}
55449
 
55450
 
+static bool ntfy_mailto_runtime_check_operands
55451
 
+(const struct sieve_enotify_log *nlog, const char *uri ATTR_UNUSED,
55452
 
+       const char *uri_body, string_t *message ATTR_UNUSED, string_t *from, 
55453
 
+       pool_t context_pool, void **method_context)
55454
 
+{
55455
 
+       struct ntfy_mailto_context *mtctx;
55456
 
+       const char *error, *normalized;
55457
 
+
55458
 
+       /* Need to create context before validation to have arrays present */
55459
 
+       mtctx = p_new(context_pool, struct ntfy_mailto_context, 1);
55460
 
+
55461
 
+       /* Validate :from */
55462
 
+       if ( from != NULL ) {
55463
 
+               T_BEGIN {
55464
 
+                       normalized = sieve_address_normalize(from, &error);
55465
 
+
55466
 
+                       if ( normalized == NULL ) {
55467
 
+                               sieve_enotify_error(nlog,
55468
 
+                                       "specified :from address '%s' is invalid for "
55469
 
+                                       "the mailto method: %s",
55470
 
+                                       str_sanitize(str_c(from), 128), error);
55471
 
+                       } else 
55472
 
+                               mtctx->from_normalized = p_strdup(context_pool, normalized);
55473
 
+               } T_END;
55474
 
+
55475
 
+               if ( !normalized ) return FALSE;
55476
 
+       }
55477
 
+
55478
 
+       p_array_init(&mtctx->recipients, context_pool, NTFY_MAILTO_MAX_RECIPIENTS);
55479
 
+       p_array_init(&mtctx->headers, context_pool, NTFY_MAILTO_MAX_HEADERS);
55480
 
+
55481
 
+       if ( !ntfy_mailto_parse_uri
55482
 
+               (nlog, uri_body, &mtctx->recipients, &mtctx->headers, &mtctx->body, 
55483
 
+                       &mtctx->subject) ) {
55484
 
+               return FALSE;
55485
 
+       }
55486
 
+
55487
 
+       *method_context = (void *) mtctx;
55488
 
+       return TRUE;    
55489
 
+}
55490
 
+
55491
 
+/*
55492
 
+ * Action duplicates
55493
 
+ */
55494
 
+
55495
 
+static int ntfy_mailto_action_check_duplicates
55496
 
+(const struct sieve_enotify_log *nlog ATTR_UNUSED, 
55497
 
+       void *method_ctx1, void *method_ctx2,
55498
 
+       const char *dupl_location ATTR_UNUSED)
55499
 
+{
55500
 
+       struct ntfy_mailto_context *mt_new = 
55501
 
+               (struct ntfy_mailto_context *) method_ctx1;
55502
 
+       struct ntfy_mailto_context *mt_old = 
55503
 
+               (struct ntfy_mailto_context *) method_ctx2;
55504
 
+       const struct ntfy_mailto_recipient *new_rcpts, *old_rcpts;
55505
 
+       unsigned int new_count, old_count, i, j;
55506
 
+       unsigned int del_start = 0, del_len = 0;
55507
 
+
55508
 
+       new_rcpts = array_get(&mt_new->recipients, &new_count);
55509
 
+       old_rcpts = array_get(&mt_old->recipients, &old_count);
55510
 
+
55511
 
+       for ( i = 0; i < new_count; i++ ) {
55512
 
+               for ( j = 0; j < old_count; j++ ) {
55513
 
+                       if ( sieve_address_compare
55514
 
+                               (new_rcpts[i].normalized, old_rcpts[j].normalized, TRUE) == 0 )
55515
 
+                               break;                          
55516
 
+               }
55517
 
+
55518
 
+               if ( j == old_count ) {
55519
 
+                       /* Not duplicate */
55520
 
+                       if ( del_len > 0 ) {
55521
 
+                               /* Perform pending deletion */
55522
 
+                               array_delete(&mt_new->recipients, del_start, del_len);
55523
 
+
55524
 
+                               /* Make sure the loop integrity is maintained */
55525
 
+                               i -= del_len;
55526
 
+                               new_rcpts = array_get(&mt_new->recipients, &new_count);
55527
 
+                       }
55528
 
+                       del_len = 0;            
55529
 
+               } else {
55530
 
+                       /* Mark deletion */
55531
 
+                       if ( del_len == 0 )
55532
 
+                               del_start = i;
55533
 
+                       del_len++;
55534
 
+               }
55535
 
+       }
55536
 
+
55537
 
+       /* Perform pending deletion */
55538
 
+       if ( del_len > 0 ) {
55539
 
+               array_delete(&mt_new->recipients, del_start, del_len);                  
55540
 
+       }
55541
 
+
55542
 
+       return ( array_count(&mt_new->recipients) > 0 ? 0 : 1 );
55543
 
+}
55544
 
+
55545
 
+/*
55546
 
+ * Action printing
55547
 
+ */
55548
 
55549
 
+static void ntfy_mailto_action_print
55550
 
+(const struct sieve_enotify_print_env *penv, 
55551
 
+       const struct sieve_enotify_action *act)
55552
 
+{
55553
 
+       unsigned int count, i;
55554
 
+       const struct ntfy_mailto_recipient *recipients;
55555
 
+       const struct ntfy_mailto_header_field *headers;
55556
 
+       struct ntfy_mailto_context *mtctx = 
55557
 
+               (struct ntfy_mailto_context *) act->method_context;
55558
 
+       
55559
 
+       /* Print main method parameters */
55560
 
+
55561
 
+       sieve_enotify_method_printf
55562
 
+               (penv,   "    => importance   : %d\n", act->importance);
55563
 
+
55564
 
+       if ( act->message != NULL )
55565
 
+               sieve_enotify_method_printf
55566
 
+                       (penv, "    => subject      : %s\n", act->message);
55567
 
+       else if ( mtctx->subject != NULL )
55568
 
+               sieve_enotify_method_printf
55569
 
+                       (penv, "    => subject      : %s\n", mtctx->subject);
55570
 
+
55571
 
+       if ( act->from != NULL )
55572
 
+               sieve_enotify_method_printf
55573
 
+                       (penv, "    => from         : %s\n", act->from);
55574
 
+
55575
 
+       /* Print mailto: recipients */
55576
 
+
55577
 
+       sieve_enotify_method_printf(penv,   "    => recipients   :\n" );
55578
 
+
55579
 
+       recipients = array_get(&mtctx->recipients, &count);
55580
 
+       if ( count == 0 ) {
55581
 
+               sieve_enotify_method_printf(penv,   "       NONE, action has no effect\n");
55582
 
+       } else {
55583
 
+               for ( i = 0; i < count; i++ ) {
55584
 
+                       if ( recipients[i].carbon_copy )
55585
 
+                               sieve_enotify_method_printf
55586
 
+                                       (penv,   "       + Cc: %s\n", recipients[i].full);
55587
 
+                       else
55588
 
+                               sieve_enotify_method_printf
55589
 
+                                       (penv,   "       + To: %s\n", recipients[i].full);
55590
 
+               }
55591
 
+       }
55592
 
+
55593
 
+       /* Print accepted headers for notification message */
55594
 
+       
55595
 
+       headers = array_get(&mtctx->headers, &count);
55596
 
+       if ( count > 0 ) {
55597
 
+               sieve_enotify_method_printf(penv,   "    => headers      :\n" );        
55598
 
+               for ( i = 0; i < count; i++ ) {
55599
 
+                       sieve_enotify_method_printf(penv,   "       + %s: %s\n", 
55600
 
+                               headers[i].name, headers[i].body);
55601
 
+               }
55602
 
+       }
55603
 
+
55604
 
+       /* Print body for notification message */
55605
 
+       
55606
 
+       if ( mtctx->body != NULL )
55607
 
+               sieve_enotify_method_printf
55608
 
+                       (penv, "    => body         : \n--\n%s\n--\n", mtctx->body);
55609
 
+
55610
 
+       /* Finish output with an empty line */
55611
 
+
55612
 
+       sieve_enotify_method_printf(penv,   "\n");
55613
 
+}
55614
 
+
55615
 
+/*
55616
 
+ * Action execution
55617
 
+ */
55618
 
+
55619
 
+static bool _contains_8bit(const char *msg)
55620
 
+{
55621
 
+       const unsigned char *s = (const unsigned char *)msg;
55622
 
+
55623
 
+       for (; *s != '\0'; s++) {
55624
 
+               if ((*s & 0x80) != 0)
55625
 
+                       return TRUE;
55626
 
+       }
55627
 
+       
55628
 
+       return FALSE;
55629
 
+}
55630
 
+
55631
 
+static bool ntfy_mailto_send
55632
 
+(const struct sieve_enotify_exec_env *nenv, 
55633
 
+       const struct sieve_enotify_action *act, const char *recipient)
55634
 
+{ 
55635
 
+       const struct sieve_enotify_log *nlog = nenv->notify_log;
55636
 
+       const struct sieve_message_data *msgdata = nenv->msgdata;
55637
 
+       const struct sieve_script_env *senv = nenv->scriptenv;
55638
 
+       struct ntfy_mailto_context *mtctx = 
55639
 
+               (struct ntfy_mailto_context *) act->method_context;     
55640
 
+       const char *from = NULL, *from_smtp = NULL; 
55641
 
+       const char *subject = mtctx->subject;
55642
 
+       const char *body = mtctx->body;
55643
 
+       string_t *to, *cc;
55644
 
+       const struct ntfy_mailto_recipient *recipients;
55645
 
+       void *smtp_handle;
55646
 
+       unsigned int count, i;
55647
 
+       FILE *f;
55648
 
+       const char *outmsgid;
55649
 
+
55650
 
+       /* Get recipients */
55651
 
+       recipients = array_get(&mtctx->recipients, &count);
55652
 
+       if ( count == 0  ) {
55653
 
+               sieve_enotify_warning(nlog, 
55654
 
+                       "notify mailto uri specifies no recipients; action has no effect");
55655
 
+               return TRUE;
55656
 
+       }
55657
 
+
55658
 
+       /* Just to be sure */
55659
 
+       if ( senv->smtp_open == NULL || senv->smtp_close == NULL ) {
55660
 
+               sieve_enotify_warning(nlog, 
55661
 
+                       "notify mailto method has no means to send mail");
55662
 
+               return TRUE;
55663
 
+       }
55664
 
+       
55665
 
+       /* Determine message from address */
55666
 
+       if ( act->from == NULL ) {
55667
 
+               from = t_strdup_printf("Postmaster <%s>", senv->postmaster_address);
55668
 
+       } else {
55669
 
+               from = act->from;
55670
 
+       }
55671
 
+
55672
 
+       /* Determine SMTP from address */
55673
 
+       if ( sieve_message_get_sender(nenv->msgctx) != NULL ) {
55674
 
+               if ( mtctx->from_normalized == NULL ) {
55675
 
+                       from_smtp = senv->postmaster_address;
55676
 
+               } else {
55677
 
+                       from_smtp = mtctx->from_normalized;
55678
 
+               }
55679
 
+       }
55680
 
+       
55681
 
+       /* Determine subject */
55682
 
+       if ( act->message != NULL ) {
55683
 
+               /* FIXME: handle UTF-8 */
55684
 
+               subject = str_sanitize(act->message, NTFY_MAILTO_MAX_SUBJECT);
55685
 
+       } else if ( subject == NULL ) {
55686
 
+               const char *const *hsubject;
55687
 
+               
55688
 
+               /* Fetch subject from original message */
55689
 
+               if ( mail_get_headers_utf8
55690
 
+                       (msgdata->mail, "subject", &hsubject) >= 0 )
55691
 
+                       subject = str_sanitize(t_strdup_printf("Notification: %s", hsubject[0]), 
55692
 
+                               NTFY_MAILTO_MAX_SUBJECT);
55693
 
+               else
55694
 
+                       subject = "Notification: (no subject)";
55695
 
+       }
55696
 
+
55697
 
+       /* Compose To and Cc headers */
55698
 
+       to = NULL;
55699
 
+       cc = NULL;
55700
 
+       for ( i = 0; i < count; i++ ) {
55701
 
+               if ( recipients[i].carbon_copy ) {
55702
 
+                       if ( cc == NULL ) {
55703
 
+                               cc = t_str_new(256);
55704
 
+                               str_append(cc, recipients[i].full);
55705
 
+                       } else {
55706
 
+                               str_append(cc, ", ");
55707
 
+                               str_append(cc, recipients[i].full);
55708
 
+                       }
55709
 
+               } else {
55710
 
+                       if ( to == NULL ) {
55711
 
+                               to = t_str_new(256);
55712
 
+                               str_append(to, recipients[i].full);
55713
 
+                       } else {
55714
 
+                               str_append(to, ", ");
55715
 
+                               str_append(to, recipients[i].full);
55716
 
+                       }
55717
 
+               }
55718
 
+       }
55719
 
+
55720
 
+       /* Send message to all recipients */
55721
 
+       for ( i = 0; i < count; i++ ) {
55722
 
+               const struct ntfy_mailto_header_field *headers;
55723
 
+               unsigned int h, hcount;
55724
 
+
55725
 
+               smtp_handle = senv->smtp_open(recipients[i].normalized, from_smtp, &f);
55726
 
+               outmsgid = sieve_message_get_new_id(senv);
55727
 
+       
55728
 
+               rfc2822_header_field_write(f, "X-Sieve", SIEVE_IMPLEMENTATION);
55729
 
+               rfc2822_header_field_write(f, "Message-ID", outmsgid);
55730
 
+               rfc2822_header_field_write(f, "Date", message_date_create(ioloop_time));
55731
 
+               rfc2822_header_field_write(f, "Subject", subject);
55732
 
+
55733
 
+               rfc2822_header_field_printf(f, "From", "%s", from);
55734
 
+
55735
 
+               if ( to != NULL )
55736
 
+                       rfc2822_header_field_printf(f, "To", "%s", str_c(to));
55737
 
+               
55738
 
+               if ( cc != NULL )
55739
 
+                       rfc2822_header_field_printf(f, "Cc", "%s", str_c(cc));
55740
 
+                       
55741
 
+               rfc2822_header_field_printf(f, "Auto-Submitted", 
55742
 
+                       "auto-notified; owner-email=\"%s\"", recipient);
55743
 
+               rfc2822_header_field_write(f, "Precedence", "bulk");
55744
 
+
55745
 
+               /* Set importance */
55746
 
+               switch ( act->importance ) {
55747
 
+               case 1:
55748
 
+                       rfc2822_header_field_write(f, "X-Priority", "1 (Highest)");
55749
 
+                       rfc2822_header_field_write(f, "Importance", "High");
55750
 
+                       break;
55751
 
+               case 3:
55752
 
+                       rfc2822_header_field_write(f, "X-Priority", "5 (Lowest)");
55753
 
+                       rfc2822_header_field_write(f, "Importance", "Low");
55754
 
+                       break;
55755
 
+               case 2:
55756
 
+               default:
55757
 
+                       rfc2822_header_field_write(f, "X-Priority", "3 (Normal)");
55758
 
+                       rfc2822_header_field_write(f, "Importance", "Normal");
55759
 
+                       break;
55760
 
+               }
55761
 
+               
55762
 
+               /* Add custom headers */
55763
 
+               
55764
 
+               headers = array_get(&mtctx->headers, &hcount);
55765
 
+               for ( h = 0; h < hcount; h++ ) {
55766
 
+                       const char *name = rfc2822_header_field_name_sanitize(headers[h].name);
55767
 
+               
55768
 
+                       rfc2822_header_field_write(f, name, headers[h].body);
55769
 
+               }
55770
 
+                       
55771
 
+               /* Generate message body */
55772
 
+               if ( body != NULL ) {
55773
 
+                       if (_contains_8bit(body)) {
55774
 
+                               rfc2822_header_field_write(f, "MIME-Version", "1.0");
55775
 
+                               rfc2822_header_field_write
55776
 
+                                       (f, "Content-Type", "text/plain; charset=UTF-8");
55777
 
+                               rfc2822_header_field_write(f, "Content-Transfer-Encoding", "8bit");
55778
 
+                       }
55779
 
+                       
55780
 
+                       fprintf(f, "\r\n");
55781
 
+                       fprintf(f, "%s\r\n", body);
55782
 
+                       
55783
 
+               } else {
55784
 
+                       fprintf(f, "\r\n");
55785
 
+                       fprintf(f, "Notification of new message.\r\n");
55786
 
+               }
55787
 
+       
55788
 
+               if ( senv->smtp_close(smtp_handle) ) {
55789
 
+                       sieve_enotify_log(nlog, 
55790
 
+                               "sent mail notification to <%s>", 
55791
 
+                               str_sanitize(recipients[i].normalized, 80));
55792
 
+               } else {
55793
 
+                       sieve_enotify_error(nlog,
55794
 
+                               "failed to send mail notification to <%s> "
55795
 
+                               "(refer to system log for more information)", 
55796
 
+                               str_sanitize(recipients[i].normalized, 80));
55797
 
+               }
55798
 
+       }
55799
 
+
55800
 
+       return TRUE;
55801
 
+}
55802
 
+
55803
 
+static bool ntfy_mailto_action_execute
55804
 
+(const struct sieve_enotify_exec_env *nenv, 
55805
 
+       const struct sieve_enotify_action *act)
55806
 
+{
55807
 
+       const char *const *headers;
55808
 
+       const char *sender = sieve_message_get_sender(nenv->msgctx);
55809
 
+       const char *recipient = sieve_message_get_recipient(nenv->msgctx);
55810
 
+
55811
 
+       /* Is the recipient unset? 
55812
 
+        */
55813
 
+       if ( recipient == NULL ) {
55814
 
+               sieve_enotify_warning(nenv->notify_log, 
55815
 
+                       "notify mailto action aborted: envelope recipient is <>");
55816
 
+               return TRUE;
55817
 
+       }
55818
 
+       
55819
 
+       /* Is the message an automatic reply ? */
55820
 
+       if ( mail_get_headers
55821
 
+               (nenv->msgdata->mail, "auto-submitted", &headers) >= 0 ) {
55822
 
+               const char *const *hdsp = headers;
55823
 
+
55824
 
+               /* Theoretically multiple headers could exist, so lets make sure */
55825
 
+               while ( *hdsp != NULL ) {
55826
 
+                       if ( strcasecmp(*hdsp, "no") != 0 ) {
55827
 
+                               sieve_enotify_log(nenv->notify_log, 
55828
 
+                                       "not sending notification for auto-submitted message from <%s>", 
55829
 
+                                       str_sanitize(sender, 128));     
55830
 
+                                       return TRUE;                             
55831
 
+                       }
55832
 
+                       hdsp++;
55833
 
+               }
55834
 
+       }
55835
 
+
55836
 
+       return ntfy_mailto_send(nenv, act, recipient);
55837
 
+}
55838
 
+
55839
 
+
55840
 
+
55841
 
+
55842
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/enotify/sieve-ext-enotify.h dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/enotify/sieve-ext-enotify.h
55843
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/enotify/sieve-ext-enotify.h    1970-01-01 01:00:00.000000000 +0100
55844
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/enotify/sieve-ext-enotify.h     2009-07-21 02:41:22.000000000 +0200
55845
 
@@ -0,0 +1,139 @@
55846
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
55847
 
+ */
55848
 
+
55849
 
+#ifndef __SIEVE_EXT_ENOTIFY_H
55850
 
+#define __SIEVE_EXT_ENOTIFY_H
55851
 
+
55852
 
+#include "lib.h"
55853
 
+#include "compat.h"
55854
 
+#include <stdarg.h>
55855
 
+
55856
 
+#include "sieve-common.h"
55857
 
+#include "sieve-error.h"
55858
 
+
55859
 
+/*
55860
 
+ * Forward declarations
55861
 
+ */
55862
 
+
55863
 
+struct sieve_enotify_log;
55864
 
+struct sieve_enotify_context; 
55865
 
+struct sieve_enotify_action;
55866
 
+struct sieve_enotify_print_env;
55867
 
+struct sieve_enotify_exec_env;
55868
 
+
55869
 
+/*
55870
 
+ * Notify context
55871
 
+ */
55872
 
+
55873
 
+struct sieve_enotify_context {
55874
 
+       struct sieve_error_handler *ehandler;
55875
 
+       
55876
 
+       /* Script location */
55877
 
+       const struct sieve_script *script;
55878
 
+       unsigned int source_line;
55879
 
+
55880
 
+       const struct sieve_message_data *msgdata;
55881
 
+       pool_t pool;
55882
 
+};
55883
 
+
55884
 
+/*
55885
 
+ * Notify methods
55886
 
+ */ 
55887
 
+
55888
 
+struct sieve_enotify_method {
55889
 
+       const char *identifier;
55890
 
+       
55891
 
+       /* Validation */
55892
 
+       bool (*compile_check_uri)
55893
 
+               (const struct sieve_enotify_log *nlog, const char *uri,
55894
 
+                       const char *uri_body);
55895
 
+       bool (*compile_check_message)
55896
 
+               (const struct sieve_enotify_log *nlog, string_t *message);
55897
 
+       bool (*compile_check_from)
55898
 
+               (const struct sieve_enotify_log *nlog, string_t *from);
55899
 
+       bool (*compile_check_option)
55900
 
+               (const struct sieve_enotify_log *nlog, const char *option, 
55901
 
+                       const char *value);
55902
 
+
55903
 
+       /* Runtime */
55904
 
+       bool (*runtime_check_uri)
55905
 
+               (const struct sieve_enotify_log *nlog, const char *uri,
55906
 
+                       const char *uri_body);
55907
 
+       const char *(*runtime_get_method_capability)
55908
 
+               (const struct sieve_enotify_log *nlog, const char *uri, 
55909
 
+                       const char *uri_body, const char *capability);
55910
 
+       bool (*runtime_check_operands)
55911
 
+               (const struct sieve_enotify_log *nlog, const char *uri, 
55912
 
+                       const char *uri_body, string_t *message, string_t *from, 
55913
 
+                       pool_t context_pool, void **method_context);
55914
 
+       bool (*runtime_set_option)
55915
 
+               (const struct sieve_enotify_log *nlog, void *method_context,
55916
 
+                       const char *option, const char *value);
55917
 
+
55918
 
+       /* Action duplicates */
55919
 
+       int (*action_check_duplicates)
55920
 
+               (const struct sieve_enotify_log *nlog, void *method_ctx1, 
55921
 
+                       void *method_ctx2, const char *dupl_location);
55922
 
+               
55923
 
+       /* Action print */
55924
 
+       void (*action_print)
55925
 
+               (const struct sieve_enotify_print_env *penv, 
55926
 
+                       const struct sieve_enotify_action *act);        
55927
 
+                       
55928
 
+       /* Action execution */
55929
 
+       bool (*action_execute)
55930
 
+               (const struct sieve_enotify_exec_env *nenv, 
55931
 
+                       const struct sieve_enotify_action *act);
55932
 
+};
55933
 
+
55934
 
+void sieve_enotify_method_register(const struct sieve_enotify_method *method);
55935
 
+
55936
 
+/*
55937
 
+ * Notify method printing
55938
 
+ */
55939
 
+
55940
 
+void sieve_enotify_method_printf
55941
 
+       (const struct sieve_enotify_print_env *penv, const char *fmt, ...)
55942
 
+               ATTR_FORMAT(2, 3);
55943
 
+
55944
 
+/*
55945
 
+ * Notify execution environment
55946
 
+ */
55947
 
+
55948
 
+struct sieve_enotify_exec_env {
55949
 
+       const struct sieve_enotify_log *notify_log;
55950
 
+
55951
 
+       const struct sieve_script_env *scriptenv;
55952
 
+       const struct sieve_message_data *msgdata;
55953
 
+       struct sieve_message_context *msgctx;
55954
 
+};
55955
 
+
55956
 
+/*
55957
 
+ * Notify action
55958
 
+ */
55959
 
55960
 
+struct sieve_enotify_action {
55961
 
+       const struct sieve_enotify_method *method;
55962
 
+       void *method_context;
55963
 
+       
55964
 
+       sieve_number_t importance;
55965
 
+       const char *message;
55966
 
+       const char *from;
55967
 
+};
55968
 
+
55969
 
+/*
55970
 
+ * Logging
55971
 
+ */
55972
 
+
55973
 
+void sieve_enotify_error
55974
 
+       (const struct sieve_enotify_log *nlog, const char *fmt, ...) 
55975
 
+               ATTR_FORMAT(2, 3);
55976
 
+void sieve_enotify_warning
55977
 
+       (const struct sieve_enotify_log *nlog, const char *fmt, ...) 
55978
 
+               ATTR_FORMAT(2, 3);
55979
 
+void sieve_enotify_log
55980
 
+       (const struct sieve_enotify_log *nlog, const char *fmt, ...) 
55981
 
+               ATTR_FORMAT(2, 3);
55982
 
+
55983
 
+#endif /* __SIEVE_EXT_ENOTIFY_H */
55984
 
+
55985
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/enotify/tst-notify-method-capability.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/enotify/tst-notify-method-capability.c
55986
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/enotify/tst-notify-method-capability.c 1970-01-01 01:00:00.000000000 +0100
55987
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/enotify/tst-notify-method-capability.c  2009-07-30 00:45:16.000000000 +0200
55988
 
@@ -0,0 +1,253 @@
55989
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
55990
 
+ */
55991
 
+
55992
 
+#include <stdio.h>
55993
 
+
55994
 
+#include "sieve-common.h"
55995
 
+#include "sieve-commands.h"
55996
 
+#include "sieve-code.h"
55997
 
+#include "sieve-comparators.h"
55998
 
+#include "sieve-match-types.h"
55999
 
+#include "sieve-validator.h"
56000
 
+#include "sieve-generator.h"
56001
 
+#include "sieve-interpreter.h"
56002
 
+#include "sieve-dump.h"
56003
 
+#include "sieve-match.h"
56004
 
+
56005
 
+#include "ext-enotify-common.h"
56006
 
+
56007
 
+/* 
56008
 
+ * String test 
56009
 
+ *
56010
 
+ * Syntax:
56011
 
+ *   notify_method_capability [COMPARATOR] [MATCH-TYPE]
56012
 
+ *     <notification-uri: string>
56013
 
+ *     <notification-capability: string>
56014
 
+ *     <key-list: string-list>
56015
 
+ */
56016
 
+
56017
 
+static bool tst_notifymc_registered
56018
 
+       (struct sieve_validator *validator, struct sieve_command_registration *cmd_reg);
56019
 
+static bool tst_notifymc_validate
56020
 
+       (struct sieve_validator *validator, struct sieve_command_context *tst);
56021
 
+static bool tst_notifymc_generate
56022
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx);
56023
 
+
56024
 
+const struct sieve_command notify_method_capability_test = { 
56025
 
+       "notify_method_capability", 
56026
 
+       SCT_TEST, 
56027
 
+       3, 0, FALSE, FALSE,
56028
 
+       tst_notifymc_registered, 
56029
 
+       NULL,
56030
 
+       tst_notifymc_validate, 
56031
 
+       tst_notifymc_generate, 
56032
 
+       NULL 
56033
 
+};
56034
 
+
56035
 
+/* 
56036
 
+ * String operation
56037
 
+ */
56038
 
+
56039
 
+static bool tst_notifymc_operation_dump
56040
 
+       (const struct sieve_operation *op, 
56041
 
+               const struct sieve_dumptime_env *denv, sieve_size_t *address);
56042
 
+static int tst_notifymc_operation_execute
56043
 
+       (const struct sieve_operation *op, 
56044
 
+               const struct sieve_runtime_env *renv, sieve_size_t *address);
56045
 
+
56046
 
+const struct sieve_operation notify_method_capability_operation = { 
56047
 
+       "NOTIFY_METHOD_CAPABILITY",
56048
 
+       &enotify_extension, 
56049
 
+       EXT_ENOTIFY_OPERATION_NOTIFY_METHOD_CAPABILITY, 
56050
 
+       tst_notifymc_operation_dump, 
56051
 
+       tst_notifymc_operation_execute 
56052
 
+};
56053
 
+
56054
 
+/* 
56055
 
+ * Optional arguments 
56056
 
+ */
56057
 
+
56058
 
+enum tst_notifymc_optional {   
56059
 
+       OPT_END,
56060
 
+       OPT_COMPARATOR,
56061
 
+       OPT_MATCH_TYPE
56062
 
+};
56063
 
+
56064
 
+/* 
56065
 
+ * Test registration 
56066
 
+ */
56067
 
+
56068
 
+static bool tst_notifymc_registered
56069
 
+       (struct sieve_validator *validator, struct sieve_command_registration *cmd_reg) 
56070
 
+{
56071
 
+       /* The order of these is not significant */
56072
 
+       sieve_comparators_link_tag(validator, cmd_reg, OPT_COMPARATOR);
56073
 
+       sieve_match_types_link_tags(validator, cmd_reg, OPT_MATCH_TYPE);
56074
 
+
56075
 
+       return TRUE;
56076
 
+}
56077
 
+
56078
 
+/* 
56079
 
+ * Test validation 
56080
 
+ */
56081
 
+
56082
 
+static bool tst_notifymc_validate
56083
 
+       (struct sieve_validator *validator, struct sieve_command_context *tst) 
56084
 
+{              
56085
 
+       struct sieve_ast_argument *arg = tst->first_positional;
56086
 
+       
56087
 
+       if ( !sieve_validate_positional_argument
56088
 
+               (validator, tst, arg, "notification-uri", 1, SAAT_STRING) ) {
56089
 
+               return FALSE;
56090
 
+       }
56091
 
+       
56092
 
+       if ( !sieve_validator_argument_activate(validator, tst, arg, FALSE) )
56093
 
+               return FALSE;
56094
 
+       
56095
 
+       arg = sieve_ast_argument_next(arg);
56096
 
+
56097
 
+       if ( !sieve_validate_positional_argument
56098
 
+               (validator, tst, arg, "notification-capability", 2, SAAT_STRING) ) {
56099
 
+               return FALSE;
56100
 
+       }
56101
 
+       
56102
 
+       if ( !sieve_validator_argument_activate(validator, tst, arg, FALSE) )
56103
 
+               return FALSE;
56104
 
+               
56105
 
+       arg = sieve_ast_argument_next(arg);
56106
 
+
56107
 
+       if ( !sieve_validate_positional_argument
56108
 
+               (validator, tst, arg, "key-list", 3, SAAT_STRING_LIST) ) {
56109
 
+               return FALSE;
56110
 
+       }
56111
 
+       
56112
 
+       if ( !sieve_validator_argument_activate(validator, tst, arg, FALSE) )
56113
 
+               return FALSE;
56114
 
+
56115
 
+       /* Validate the key argument to a specified match type */
56116
 
+       return sieve_match_type_validate
56117
 
+               (validator, tst, arg, &is_match_type, &i_ascii_casemap_comparator);
56118
 
+}
56119
 
+
56120
 
+/* 
56121
 
+ * Test generation 
56122
 
+ */
56123
 
+
56124
 
+static bool tst_notifymc_generate
56125
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx) 
56126
 
+{
56127
 
+       sieve_operation_emit_code(cgenv->sbin, &notify_method_capability_operation);
56128
 
+
56129
 
+       /* Generate arguments */
56130
 
+       return sieve_generate_arguments(cgenv, ctx, NULL);
56131
 
+}
56132
 
+
56133
 
+/* 
56134
 
+ * Code dump 
56135
 
+ */
56136
 
+
56137
 
+static bool tst_notifymc_operation_dump
56138
 
+(const struct sieve_operation *op ATTR_UNUSED,
56139
 
+       const struct sieve_dumptime_env *denv, sieve_size_t *address)
56140
 
+{
56141
 
+       int opt_code = 0;
56142
 
+
56143
 
+       sieve_code_dumpf(denv, "NOTIFY_METHOD_CAPABILITY");
56144
 
+       sieve_code_descend(denv);
56145
 
+
56146
 
+       /* Handle any optional arguments */
56147
 
+       if ( !sieve_match_dump_optional_operands(denv, address, &opt_code) )
56148
 
+               return FALSE;
56149
 
+
56150
 
+       if ( opt_code != SIEVE_MATCH_OPT_END )
56151
 
+               return FALSE;
56152
 
+               
56153
 
+       return
56154
 
+               sieve_opr_string_dump(denv, address, "notify uri") &&
56155
 
+               sieve_opr_string_dump(denv, address, "notify capability") &&
56156
 
+               sieve_opr_stringlist_dump(denv, address, "key list");
56157
 
+}
56158
 
+
56159
 
+/* 
56160
 
+ * Code execution 
56161
 
+ */
56162
 
+
56163
 
+static int tst_notifymc_operation_execute
56164
 
+(const struct sieve_operation *op ATTR_UNUSED, 
56165
 
+       const struct sieve_runtime_env *renv, sieve_size_t *address)
56166
 
+{
56167
 
+       int ret, mret;
56168
 
+       bool result = TRUE;
56169
 
+       int opt_code = 0;
56170
 
+       const struct sieve_comparator *cmp = &i_octet_comparator;
56171
 
+       const struct sieve_match_type *mtch = &is_match_type;
56172
 
+       struct sieve_match_context *mctx;
56173
 
+       string_t *notify_uri, *notify_capability;
56174
 
+       struct sieve_coded_stringlist *key_list;
56175
 
+       const char *cap_value;
56176
 
+       bool matched;
56177
 
+
56178
 
+       /*
56179
 
+        * Read operands 
56180
 
+        */
56181
 
+       
56182
 
+       /* Handle match-type and comparator operands */
56183
 
+       if ( (ret=sieve_match_read_optional_operands
56184
 
+               (renv, address, &opt_code, &cmp, &mtch)) <= 0 )
56185
 
+               return ret;
56186
 
+       
56187
 
+       /* Check whether we neatly finished the list of optional operands */
56188
 
+       if ( opt_code != SIEVE_MATCH_OPT_END) {
56189
 
+               sieve_runtime_trace_error(renv, "invalid optional operand");
56190
 
+               return SIEVE_EXEC_BIN_CORRUPT;
56191
 
+       }
56192
 
+
56193
 
+       /* Read notify uri */
56194
 
+       if ( !sieve_opr_string_read(renv, address, &notify_uri) ) {
56195
 
+               sieve_runtime_trace_error(renv, "invalid notify-uri operand");
56196
 
+               return SIEVE_EXEC_BIN_CORRUPT;
56197
 
+       }
56198
 
+       
56199
 
+       /* Read notify capability */
56200
 
+       if ( !sieve_opr_string_read(renv, address, &notify_capability) ) {
56201
 
+               sieve_runtime_trace_error(renv, "invalid notify-uri operand");
56202
 
+               return SIEVE_EXEC_BIN_CORRUPT;
56203
 
+       }
56204
 
+       
56205
 
+       /* Read key-list */
56206
 
+       if ( (key_list=sieve_opr_stringlist_read(renv, address)) == NULL ) {
56207
 
+               sieve_runtime_trace_error(renv, "invalid key-list operand");
56208
 
+               return SIEVE_EXEC_BIN_CORRUPT;
56209
 
+       }
56210
 
+
56211
 
+       /*
56212
 
+        * Perform operation
56213
 
+        */
56214
 
+
56215
 
+       sieve_runtime_trace(renv, "NOTIFY_METHOD_CAPABILITY test");
56216
 
+
56217
 
+       cap_value = ext_enotify_runtime_get_method_capability
56218
 
+               (renv, 0 /* FIXME */, notify_uri, str_c(notify_capability));
56219
 
+
56220
 
+       if ( cap_value != NULL ) {
56221
 
+               mctx = sieve_match_begin(renv->interp, mtch, cmp, NULL, key_list);      
56222
 
+
56223
 
+               if ( (mret=sieve_match_value(mctx, cap_value, strlen(cap_value))) < 0 )
56224
 
+                       result = FALSE;
56225
 
+               matched = ( mret > 0 );         
56226
 
+
56227
 
+               if ( (mret=sieve_match_end(&mctx)) < 0 ) 
56228
 
+                       result = FALSE;
56229
 
+               matched = ( mret > 0 ) || matched;              
56230
 
+       } else {
56231
 
+               matched = FALSE;
56232
 
+       }
56233
 
+       
56234
 
+       if ( result ) {
56235
 
+               sieve_interpreter_set_test_result(renv->interp, matched);
56236
 
+               return SIEVE_EXEC_OK;
56237
 
+       }
56238
 
+       
56239
 
+       sieve_runtime_trace_error(renv, "invalid string list item");
56240
 
+       return SIEVE_EXEC_BIN_CORRUPT;
56241
 
+}
56242
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/enotify/tst-valid-notify-method.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/enotify/tst-valid-notify-method.c
56243
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/enotify/tst-valid-notify-method.c      1970-01-01 01:00:00.000000000 +0100
56244
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/enotify/tst-valid-notify-method.c       2009-01-06 00:15:52.000000000 +0100
56245
 
@@ -0,0 +1,148 @@
56246
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
56247
 
+ */
56248
 
+
56249
 
+#include "sieve-common.h"
56250
 
+#include "sieve-commands.h"
56251
 
+#include "sieve-code.h"
56252
 
+#include "sieve-comparators.h"
56253
 
+#include "sieve-match-types.h"
56254
 
+#include "sieve-validator.h"
56255
 
+#include "sieve-generator.h"
56256
 
+#include "sieve-interpreter.h"
56257
 
+#include "sieve-dump.h"
56258
 
+#include "sieve-match.h"
56259
 
+
56260
 
+#include "ext-enotify-common.h"
56261
 
+
56262
 
+/* 
56263
 
+ * Valid_notify_method test 
56264
 
+ *
56265
 
+ * Syntax:
56266
 
+ *   valid_notify_method <notification-uris: string-list>
56267
 
+ */
56268
 
+
56269
 
+static bool tst_vnotifym_validate
56270
 
+       (struct sieve_validator *validator, struct sieve_command_context *tst);
56271
 
+static bool tst_vnotifym_generate
56272
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx);
56273
 
+
56274
 
+const struct sieve_command valid_notify_method_test = { 
56275
 
+       "valid_notify_method", 
56276
 
+       SCT_TEST, 
56277
 
+       1, 0, FALSE, FALSE,
56278
 
+       NULL, NULL,
56279
 
+       tst_vnotifym_validate, 
56280
 
+       tst_vnotifym_generate, 
56281
 
+       NULL 
56282
 
+};
56283
 
+
56284
 
+/* 
56285
 
+ * Valid_notify_method operation
56286
 
+ */
56287
 
+
56288
 
+static bool tst_vnotifym_operation_dump
56289
 
+       (const struct sieve_operation *op, 
56290
 
+               const struct sieve_dumptime_env *denv, sieve_size_t *address);
56291
 
+static int tst_vnotifym_operation_execute
56292
 
+       (const struct sieve_operation *op, 
56293
 
+               const struct sieve_runtime_env *renv, sieve_size_t *address);
56294
 
+
56295
 
+const struct sieve_operation valid_notify_method_operation = { 
56296
 
+       "VALID_NOTIFY_METHOD",
56297
 
+       &enotify_extension, 
56298
 
+       EXT_ENOTIFY_OPERATION_VALID_NOTIFY_METHOD, 
56299
 
+       tst_vnotifym_operation_dump, 
56300
 
+       tst_vnotifym_operation_execute 
56301
 
+};
56302
 
+
56303
 
+/* 
56304
 
+ * Test validation 
56305
 
+ */
56306
 
+
56307
 
+static bool tst_vnotifym_validate
56308
 
+       (struct sieve_validator *validator, struct sieve_command_context *tst) 
56309
 
+{              
56310
 
+       struct sieve_ast_argument *arg = tst->first_positional;
56311
 
+       
56312
 
+       if ( !sieve_validate_positional_argument
56313
 
+               (validator, tst, arg, "notification-uris", 1, SAAT_STRING_LIST) ) {
56314
 
+               return FALSE;
56315
 
+       }
56316
 
+       
56317
 
+       return sieve_validator_argument_activate(validator, tst, arg, FALSE);
56318
 
+}
56319
 
+
56320
 
+/* 
56321
 
+ * Test generation 
56322
 
+ */
56323
 
+
56324
 
+static bool tst_vnotifym_generate
56325
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx) 
56326
 
+{
56327
 
+       sieve_operation_emit_code(cgenv->sbin, &valid_notify_method_operation);
56328
 
+
56329
 
+       /* Generate arguments */
56330
 
+       return sieve_generate_arguments(cgenv, ctx, NULL);
56331
 
+}
56332
 
+
56333
 
+/* 
56334
 
+ * Code dump 
56335
 
+ */
56336
 
+
56337
 
+static bool tst_vnotifym_operation_dump
56338
 
+(const struct sieve_operation *op ATTR_UNUSED,
56339
 
+       const struct sieve_dumptime_env *denv, sieve_size_t *address)
56340
 
+{
56341
 
+       sieve_code_dumpf(denv, "VALID_NOTIFY_METHOD");
56342
 
+       sieve_code_descend(denv);
56343
 
+               
56344
 
+       return
56345
 
+               sieve_opr_stringlist_dump(denv, address, "notify-uris");
56346
 
+}
56347
 
+
56348
 
+/* 
56349
 
+ * Code execution 
56350
 
+ */
56351
 
+
56352
 
+static int tst_vnotifym_operation_execute
56353
 
+(const struct sieve_operation *op ATTR_UNUSED, 
56354
 
+       const struct sieve_runtime_env *renv, sieve_size_t *address)
56355
 
+{
56356
 
+       struct sieve_coded_stringlist *notify_uris;
56357
 
+       string_t *uri_item;
56358
 
+       bool result = TRUE, all_valid = TRUE;
56359
 
+
56360
 
+       /*
56361
 
+        * Read operands 
56362
 
+        */
56363
 
+       
56364
 
+       /* Read notify uris */
56365
 
+       if ( (notify_uris=sieve_opr_stringlist_read(renv, address)) == NULL ) {
56366
 
+               sieve_runtime_trace_error(renv, "invalid notify-uris operand");
56367
 
+               return SIEVE_EXEC_BIN_CORRUPT;
56368
 
+       }
56369
 
+       
56370
 
+       /*
56371
 
+        * Perform operation
56372
 
+        */
56373
 
+
56374
 
+       sieve_runtime_trace(renv, "VALID_NOTIFY_METHOD test");
56375
 
+
56376
 
+       uri_item = NULL;
56377
 
+       while ( (result=sieve_coded_stringlist_next_item(notify_uris, &uri_item)) 
56378
 
+               && uri_item != NULL ) {
56379
 
+               
56380
 
+               if ( !ext_enotify_runtime_method_validate(renv, 0 /* FIXME */, uri_item) ) {
56381
 
+                       all_valid = FALSE;
56382
 
+                       break;
56383
 
+               }
56384
 
+       }
56385
 
+       
56386
 
+       if ( !result ) {
56387
 
+               sieve_runtime_trace_error(renv, "invalid method uri item");
56388
 
+               return SIEVE_EXEC_BIN_CORRUPT;
56389
 
+       }
56390
 
+       
56391
 
+       sieve_interpreter_set_test_result(renv->interp, all_valid);
56392
 
+       return SIEVE_EXEC_OK;
56393
 
+}
56394
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/enotify/vmodf-encodeurl.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/enotify/vmodf-encodeurl.c
56395
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/enotify/vmodf-encodeurl.c      1970-01-01 01:00:00.000000000 +0100
56396
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/enotify/vmodf-encodeurl.c       2009-01-06 00:15:52.000000000 +0100
56397
 
@@ -0,0 +1,84 @@
56398
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
56399
 
+ */
56400
 
+
56401
 
+#include "lib.h"
56402
 
+#include "str.h"
56403
 
+
56404
 
+#include "sieve-common.h"
56405
 
+#include "sieve-code.h"
56406
 
+
56407
 
+#include "sieve-ext-variables.h"
56408
 
+
56409
 
+#include "ext-enotify-common.h"
56410
 
+
56411
 
+/*
56412
 
+ * Encodeurl modifier
56413
 
+ */
56414
 
56415
 
+bool mod_encodeurl_modify(string_t *in, string_t **result);
56416
 
56417
 
+const struct sieve_variables_modifier encodeurl_modifier = {
56418
 
+       SIEVE_OBJECT("encodeurl", &encodeurl_operand, 0),
56419
 
+       15,
56420
 
+       mod_encodeurl_modify
56421
 
+};
56422
 
56423
 
+/*
56424
 
+ * Modifier operand
56425
 
+ */
56426
 
+
56427
 
+static const struct sieve_extension_objects ext_enotify_modifiers =
56428
 
+       SIEVE_VARIABLES_DEFINE_MODIFIER(encodeurl_modifier);
56429
 
+
56430
 
+const struct sieve_operand encodeurl_operand = { 
56431
 
+       "modifier", 
56432
 
+       &enotify_extension,
56433
 
+       0, 
56434
 
+       &sieve_variables_modifier_operand_class,
56435
 
+       &ext_enotify_modifiers
56436
 
+};
56437
 
+
56438
 
+/*
56439
 
+ * Modifier implementation
56440
 
+ */
56441
 
+
56442
 
+static const char _uri_reserved_lookup[256] = {
56443
 
+       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 00
56444
 
+       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 10
56445
 
+       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1,  // 20
56446
 
+       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1,  // 30
56447
 
+       1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 40
56448
 
+       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0,  // 50
56449
 
+       1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 60
56450
 
+       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1,  // 70
56451
 
+
56452
 
+       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 80
56453
 
+       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 90
56454
 
+       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // A0
56455
 
+       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // B0
56456
 
+       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // C0
56457
 
+       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // D0
56458
 
+       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // E0
56459
 
+       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // F0
56460
 
+};
56461
 
+
56462
 
+bool mod_encodeurl_modify(string_t *in, string_t **result)
56463
 
+{      
56464
 
+       unsigned int i;
56465
 
+       const unsigned char *c;
56466
 
+
56467
 
+       *result = t_str_new(2*str_len(in));
56468
 
+       c = str_data(in);
56469
 
+       
56470
 
+       for ( i = 0; i < str_len(in); i++, c++ ) {
56471
 
+               if ( _uri_reserved_lookup[*c] ) {
56472
 
+                       str_printfa(*result, "%%%02X", *c);
56473
 
+               } else {
56474
 
+                       str_append_c(*result, *c); 
56475
 
+               }       
56476
 
+       }
56477
 
+
56478
 
+       return TRUE;
56479
 
+}
56480
 
56481
 
+
56482
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/environment/ext-environment.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/environment/ext-environment.c
56483
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/environment/ext-environment.c  1970-01-01 01:00:00.000000000 +0100
56484
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/environment/ext-environment.c   2009-04-13 21:35:39.000000000 +0200
56485
 
@@ -0,0 +1,53 @@
56486
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
56487
 
+ */
56488
 
+
56489
 
+/* Extension variables 
56490
 
+ * -------------------
56491
 
+ *
56492
 
+ * Authors: Stephan Bosch
56493
 
+ * Specification: RFC 5183
56494
 
+ * Implementation: full
56495
 
+ * Status: experimental, not thoroughly tested
56496
 
+ *
56497
 
+ */
56498
 
56499
 
+#include "lib.h"
56500
 
+#include "str.h"
56501
 
+#include "unichar.h"
56502
 
+
56503
 
+#include "sieve-extensions.h"
56504
 
+#include "sieve-commands.h"
56505
 
+#include "sieve-binary.h"
56506
 
+#include "sieve-interpreter.h"
56507
 
+
56508
 
+#include "sieve-validator.h"
56509
 
+
56510
 
+#include "ext-environment-common.h"
56511
 
+
56512
 
+/* 
56513
 
+ * Extension 
56514
 
+ */
56515
 
+
56516
 
+static bool ext_environment_validator_load(struct sieve_validator *validator);
56517
 
+
56518
 
+static int ext_my_id = -1;
56519
 
+       
56520
 
+const struct sieve_extension environment_extension = { 
56521
 
+       "environment", 
56522
 
+       &ext_my_id,
56523
 
+       ext_environment_init, 
56524
 
+       ext_environment_deinit,
56525
 
+       ext_environment_validator_load,
56526
 
+       NULL, NULL, NULL, NULL, NULL,
56527
 
+       SIEVE_EXT_DEFINE_OPERATION(tst_environment_operation), 
56528
 
+       SIEVE_EXT_DEFINE_NO_OPERANDS
56529
 
+};
56530
 
+
56531
 
+static bool ext_environment_validator_load
56532
 
+       (struct sieve_validator *validator)
56533
 
+{
56534
 
+       sieve_validator_register_command(validator, &tst_environment);
56535
 
+       
56536
 
+       return TRUE;
56537
 
+}
56538
 
+
56539
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/environment/ext-environment-common.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/environment/ext-environment-common.c
56540
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/environment/ext-environment-common.c   1970-01-01 01:00:00.000000000 +0100
56541
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/environment/ext-environment-common.c    2009-04-13 23:17:15.000000000 +0200
56542
 
@@ -0,0 +1,168 @@
56543
 
+#include "lib.h"
56544
 
+#include "hash.h"
56545
 
+
56546
 
+#include "ext-environment-common.h"
56547
 
+
56548
 
+static struct hash_table *environment_items;
56549
 
+
56550
 
+/*
56551
 
+ * Core environment items
56552
 
+ */
56553
 
+
56554
 
+static const struct sieve_environment_item *core_env_items[] = {
56555
 
+       &domain_env_item, 
56556
 
+       &host_env_item, 
56557
 
+       &location_env_item, 
56558
 
+       &phase_env_item, 
56559
 
+       &name_env_item, 
56560
 
+       &version_env_item
56561
 
+};
56562
 
+
56563
 
+static unsigned int core_env_items_count = N_ELEMENTS(core_env_items);
56564
 
+
56565
 
+/*
56566
 
+ * Initialization
56567
 
+ */
56568
 
+
56569
 
+bool ext_environment_init(void) 
56570
 
+{
56571
 
+       unsigned int i;
56572
 
+
56573
 
+       environment_items = hash_table_create
56574
 
+               (default_pool, default_pool, 0, str_hash, (hash_cmp_callback_t *)strcmp);
56575
 
+
56576
 
+       for ( i = 0; i < core_env_items_count; i++ ) {
56577
 
+               sieve_ext_environment_item_register(core_env_items[i]);
56578
 
+       }
56579
 
+
56580
 
+       return TRUE;
56581
 
+}
56582
 
+
56583
 
+void ext_environment_deinit(void)
56584
 
+{
56585
 
+       hash_table_destroy(&environment_items);
56586
 
+}
56587
 
+
56588
 
+/*
56589
 
+ * Registration
56590
 
+ */
56591
 
+
56592
 
+void sieve_ext_environment_item_register
56593
 
+(const struct sieve_environment_item *item)
56594
 
+{
56595
 
+       hash_table_insert
56596
 
+               (environment_items, (void *) item->name, (void *) item);
56597
 
+}
56598
 
+
56599
 
+/*
56600
 
+ * Retrieval
56601
 
+ */
56602
 
+
56603
 
+const char *ext_environment_item_get_value
56604
 
+(const char *name, const struct sieve_script_env *senv)
56605
 
+{
56606
 
+       const struct sieve_environment_item *item = 
56607
 
+               (const struct sieve_environment_item *) 
56608
 
+                       hash_table_lookup(environment_items, name);
56609
 
+
56610
 
+       if ( item == NULL )
56611
 
+               return NULL;
56612
 
+
56613
 
+       if ( item->value != NULL )
56614
 
+               return item->value;
56615
 
+
56616
 
+       if ( item->get_value != NULL ) 
56617
 
+               return item->get_value(senv);
56618
 
+
56619
 
+       return NULL; 
56620
 
+}
56621
 
+
56622
 
+/*
56623
 
+ * Default environment items
56624
 
+ */
56625
 
+
56626
 
+/* "domain":
56627
 
+ *
56628
 
+ *   The primary DNS domain associated with the Sieve execution context, usually 
56629
 
+ *   but not always a proper suffix of the host name.
56630
 
+ */
56631
 
+const struct sieve_environment_item domain_env_item = {
56632
 
+       "domain",
56633
 
+       NULL,
56634
 
+       NULL,
56635
 
+};
56636
 
+
56637
 
+/* "host":
56638
 
+ *
56639
 
+ *   The fully-qualified domain name of the host where the Sieve script is 
56640
 
+ *   executing.
56641
 
+ */
56642
 
+
56643
 
+static const char *envit_host_get_value(const struct sieve_script_env *senv)
56644
 
+{
56645
 
+       return senv->hostname != NULL ? senv->hostname : "";
56646
 
+}
56647
 
+
56648
 
+const struct sieve_environment_item host_env_item = {
56649
 
+       "host",
56650
 
+       NULL,
56651
 
+       envit_host_get_value,
56652
 
+};
56653
 
+
56654
 
+/* "location":
56655
 
+ *
56656
 
+ *   Sieve evaluation can be performed at various different points as messages 
56657
 
+ *   are processed. This item provides additional information about the type of
56658
 
+ *   service that is evaluating the script.  Possible values are:
56659
 
+ *    "MTA" - the Sieve script is being evaluated by a Message Transfer Agent 
56660
 
+ *    "MDA" - evaluation is being performed by a Mail Delivery Agent 
56661
 
+ *    "MUA" - evaluation is being performed by a Mail User Agent
56662
 
+ *    "MS"  - evaluation is being performed by a Message Store
56663
 
+ */
56664
 
+const struct sieve_environment_item location_env_item = {
56665
 
+       "location",
56666
 
+       NULL,
56667
 
+       NULL,
56668
 
+};
56669
 
+
56670
 
+/* "phase":
56671
 
+ *
56672
 
+ *   The point relative to final delivery where the Sieve script is being
56673
 
+ *   evaluated.  Possible values are "pre", "during", and "post", referring 
56674
 
+ *   respectively to processing before, during, and after final delivery has 
56675
 
+ *   taken place.
56676
 
+ */
56677
 
+
56678
 
+const struct sieve_environment_item phase_env_item = {
56679
 
+       "phase",
56680
 
+       NULL,
56681
 
+       NULL,
56682
 
+};
56683
 
+
56684
 
+/* "name":
56685
 
+ *
56686
 
+ *  The product name associated with the Sieve interpreter.
56687
 
+ */
56688
 
+const struct sieve_environment_item name_env_item = {
56689
 
+       "name",
56690
 
+       SIEVE_NAME,
56691
 
+       NULL,
56692
 
+};
56693
 
+
56694
 
+/* "version":
56695
 
+ *
56696
 
+ * The product version associated with the Sieve interpreter. The meaning of the 
56697
 
+ * product version string is product-specific and should always be considered
56698
 
+ * in the context of the product name given by the "name" item.
56699
 
+ */
56700
 
+
56701
 
+const struct sieve_environment_item version_env_item = {
56702
 
+       "version",
56703
 
+       SIEVE_VERSION,
56704
 
+       NULL,
56705
 
+};
56706
 
+
56707
 
+
56708
 
+
56709
 
+
56710
 
+
56711
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/environment/ext-environment-common.h dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/environment/ext-environment-common.h
56712
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/environment/ext-environment-common.h   1970-01-01 01:00:00.000000000 +0100
56713
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/environment/ext-environment-common.h    2009-04-13 21:35:39.000000000 +0200
56714
 
@@ -0,0 +1,54 @@
56715
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
56716
 
+ */
56717
 
+
56718
 
+#ifndef __EXT_ENVIRONMENT_COMMON_H
56719
 
+#define __EXT_ENVIRONMENT_COMMON_H
56720
 
+
56721
 
+#include "sieve-common.h"
56722
 
+
56723
 
+#include "sieve-ext-environment.h"
56724
 
+
56725
 
+/*
56726
 
+ * Extension
56727
 
+ */
56728
 
+
56729
 
+extern const struct sieve_extension environment_extension;
56730
 
+
56731
 
+/* 
56732
 
+ * Commands 
56733
 
+ */
56734
 
+
56735
 
+extern const struct sieve_command tst_environment;
56736
 
+
56737
 
+/*
56738
 
+ * Operations
56739
 
+ */
56740
 
+
56741
 
+extern const struct sieve_operation tst_environment_operation;
56742
 
+
56743
 
+/*
56744
 
+ * Environment items
56745
 
+ */
56746
 
+
56747
 
+extern const struct sieve_environment_item domain_env_item;
56748
 
+extern const struct sieve_environment_item host_env_item;
56749
 
+extern const struct sieve_environment_item location_env_item;
56750
 
+extern const struct sieve_environment_item phase_env_item;
56751
 
+extern const struct sieve_environment_item name_env_item;
56752
 
+extern const struct sieve_environment_item version_env_item;
56753
 
+
56754
 
+/*
56755
 
+ * Initialization
56756
 
+ */
56757
 
+
56758
 
+bool ext_environment_init(void);
56759
 
+void ext_environment_deinit(void);
56760
 
+
56761
 
+/*
56762
 
+ * Environment item retrieval
56763
 
+ */
56764
 
+
56765
 
+const char *ext_environment_item_get_value
56766
 
+       (const char *name, const struct sieve_script_env *senv);
56767
 
+
56768
 
+#endif /* __EXT_VARIABLES_COMMON_H */
56769
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/environment/Makefile.am dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/environment/Makefile.am
56770
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/environment/Makefile.am        1970-01-01 01:00:00.000000000 +0100
56771
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/environment/Makefile.am 2009-04-13 21:35:39.000000000 +0200
56772
 
@@ -0,0 +1,20 @@
56773
 
+noinst_LTLIBRARIES = libsieve_ext_environment.la
56774
 
+
56775
 
+AM_CPPFLAGS = \
56776
 
+       -I../../ \
56777
 
+       -I$(dovecot_incdir) \
56778
 
+       -I$(dovecot_incdir)/src/lib \
56779
 
+       -I$(dovecot_incdir)/src/lib-mail \
56780
 
+       -I$(dovecot_incdir)/src/lib-storage 
56781
 
+
56782
 
+tests = \
56783
 
+       tst-environment.c
56784
 
+
56785
 
+libsieve_ext_environment_la_SOURCES = \
56786
 
+       $(tests) \
56787
 
+       ext-environment-common.c \
56788
 
+       ext-environment.c
56789
 
+
56790
 
+noinst_HEADERS = \
56791
 
+       ext-environment-common.h \
56792
 
+       sieve-ext-environment.h
56793
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/environment/Makefile.in dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/environment/Makefile.in
56794
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/environment/Makefile.in        1970-01-01 01:00:00.000000000 +0100
56795
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/environment/Makefile.in 2009-08-21 00:55:43.000000000 +0200
56796
 
@@ -0,0 +1,470 @@
56797
 
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
56798
 
+# @configure_input@
56799
 
+
56800
 
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
56801
 
+# 2003, 2004, 2005, 2006, 2007, 2008  Free Software Foundation, Inc.
56802
 
+# This Makefile.in is free software; the Free Software Foundation
56803
 
+# gives unlimited permission to copy and/or distribute it,
56804
 
+# with or without modifications, as long as this notice is preserved.
56805
 
+
56806
 
+# This program is distributed in the hope that it will be useful,
56807
 
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
56808
 
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
56809
 
+# PARTICULAR PURPOSE.
56810
 
+
56811
 
+@SET_MAKE@
56812
 
+
56813
 
+
56814
 
+VPATH = @srcdir@
56815
 
+pkgdatadir = $(datadir)/@PACKAGE@
56816
 
+pkglibdir = $(libdir)/@PACKAGE@
56817
 
+pkgincludedir = $(includedir)/@PACKAGE@
56818
 
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
56819
 
+install_sh_DATA = $(install_sh) -c -m 644
56820
 
+install_sh_PROGRAM = $(install_sh) -c
56821
 
+install_sh_SCRIPT = $(install_sh) -c
56822
 
+INSTALL_HEADER = $(INSTALL_DATA)
56823
 
+transform = $(program_transform_name)
56824
 
+NORMAL_INSTALL = :
56825
 
+PRE_INSTALL = :
56826
 
+POST_INSTALL = :
56827
 
+NORMAL_UNINSTALL = :
56828
 
+PRE_UNINSTALL = :
56829
 
+POST_UNINSTALL = :
56830
 
+build_triplet = @build@
56831
 
+host_triplet = @host@
56832
 
+subdir = src/lib-sieve/plugins/environment
56833
 
+DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
56834
 
+       $(srcdir)/Makefile.in
56835
 
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
56836
 
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
56837
 
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
56838
 
+       $(ACLOCAL_M4)
56839
 
+mkinstalldirs = $(install_sh) -d
56840
 
+CONFIG_HEADER = $(top_builddir)/dummy-config.h \
56841
 
+       $(top_builddir)/dsieve-config.h
56842
 
+CONFIG_CLEAN_FILES =
56843
 
+LTLIBRARIES = $(noinst_LTLIBRARIES)
56844
 
+libsieve_ext_environment_la_LIBADD =
56845
 
+am__objects_1 = tst-environment.lo
56846
 
+am_libsieve_ext_environment_la_OBJECTS = $(am__objects_1) \
56847
 
+       ext-environment-common.lo ext-environment.lo
56848
 
+libsieve_ext_environment_la_OBJECTS =  \
56849
 
+       $(am_libsieve_ext_environment_la_OBJECTS)
56850
 
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
56851
 
+depcomp = $(SHELL) $(top_srcdir)/depcomp
56852
 
+am__depfiles_maybe = depfiles
56853
 
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
56854
 
+       $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
56855
 
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
56856
 
+       --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
56857
 
+       $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
56858
 
+CCLD = $(CC)
56859
 
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
56860
 
+       --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
56861
 
+       $(LDFLAGS) -o $@
56862
 
+SOURCES = $(libsieve_ext_environment_la_SOURCES)
56863
 
+DIST_SOURCES = $(libsieve_ext_environment_la_SOURCES)
56864
 
+HEADERS = $(noinst_HEADERS)
56865
 
+ETAGS = etags
56866
 
+CTAGS = ctags
56867
 
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
56868
 
+ACLOCAL = @ACLOCAL@
56869
 
+AMTAR = @AMTAR@
56870
 
+AR = @AR@
56871
 
+AUTOCONF = @AUTOCONF@
56872
 
+AUTOHEADER = @AUTOHEADER@
56873
 
+AUTOMAKE = @AUTOMAKE@
56874
 
+AWK = @AWK@
56875
 
+CC = @CC@
56876
 
+CCDEPMODE = @CCDEPMODE@
56877
 
+CFLAGS = @CFLAGS@
56878
 
+CPP = @CPP@
56879
 
+CPPFLAGS = @CPPFLAGS@
56880
 
+CYGPATH_W = @CYGPATH_W@
56881
 
+DEFS = @DEFS@
56882
 
+DEPDIR = @DEPDIR@
56883
 
+DSYMUTIL = @DSYMUTIL@
56884
 
+DUMPBIN = @DUMPBIN@
56885
 
+ECHO_C = @ECHO_C@
56886
 
+ECHO_N = @ECHO_N@
56887
 
+ECHO_T = @ECHO_T@
56888
 
+EGREP = @EGREP@
56889
 
+EXEEXT = @EXEEXT@
56890
 
+FGREP = @FGREP@
56891
 
+GREP = @GREP@
56892
 
+INSTALL = @INSTALL@
56893
 
+INSTALL_DATA = @INSTALL_DATA@
56894
 
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
56895
 
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
56896
 
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
56897
 
+LD = @LD@
56898
 
+LDFLAGS = @LDFLAGS@
56899
 
+LIBICONV = @LIBICONV@
56900
 
+LIBOBJS = @LIBOBJS@
56901
 
+LIBS = @LIBS@
56902
 
+LIBTOOL = @LIBTOOL@
56903
 
+LIPO = @LIPO@
56904
 
+LN_S = @LN_S@
56905
 
+LTLIBOBJS = @LTLIBOBJS@
56906
 
+MAINT = @MAINT@
56907
 
+MAKEINFO = @MAKEINFO@
56908
 
+MKDIR_P = @MKDIR_P@
56909
 
+MODULE_LIBS = @MODULE_LIBS@
56910
 
+NM = @NM@
56911
 
+NMEDIT = @NMEDIT@
56912
 
+OBJDUMP = @OBJDUMP@
56913
 
+OBJEXT = @OBJEXT@
56914
 
+OTOOL = @OTOOL@
56915
 
+OTOOL64 = @OTOOL64@
56916
 
+PACKAGE = @PACKAGE@
56917
 
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
56918
 
+PACKAGE_NAME = @PACKAGE_NAME@
56919
 
+PACKAGE_STRING = @PACKAGE_STRING@
56920
 
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
56921
 
+PACKAGE_URL = @PACKAGE_URL@
56922
 
+PACKAGE_VERSION = @PACKAGE_VERSION@
56923
 
+PATH_SEPARATOR = @PATH_SEPARATOR@
56924
 
+RAND_LIBS = @RAND_LIBS@
56925
 
+RANLIB = @RANLIB@
56926
 
+SED = @SED@
56927
 
+SET_MAKE = @SET_MAKE@
56928
 
+SHELL = @SHELL@
56929
 
+STORAGE_LIBS = @STORAGE_LIBS@
56930
 
+STRIP = @STRIP@
56931
 
+VERSION = @VERSION@
56932
 
+abs_builddir = @abs_builddir@
56933
 
+abs_srcdir = @abs_srcdir@
56934
 
+abs_top_builddir = @abs_top_builddir@
56935
 
+abs_top_srcdir = @abs_top_srcdir@
56936
 
+ac_ct_CC = @ac_ct_CC@
56937
 
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
56938
 
+am__include = @am__include@
56939
 
+am__leading_dot = @am__leading_dot@
56940
 
+am__quote = @am__quote@
56941
 
+am__tar = @am__tar@
56942
 
+am__untar = @am__untar@
56943
 
+bindir = @bindir@
56944
 
+build = @build@
56945
 
+build_alias = @build_alias@
56946
 
+build_cpu = @build_cpu@
56947
 
+build_os = @build_os@
56948
 
+build_vendor = @build_vendor@
56949
 
+builddir = @builddir@
56950
 
+datadir = @datadir@
56951
 
+datarootdir = @datarootdir@
56952
 
+docdir = @docdir@
56953
 
+dovecot_incdir = @dovecot_incdir@
56954
 
+dovecotdir = @dovecotdir@
56955
 
+dvidir = @dvidir@
56956
 
+exec_prefix = @exec_prefix@
56957
 
+host = @host@
56958
 
+host_alias = @host_alias@
56959
 
+host_cpu = @host_cpu@
56960
 
+host_os = @host_os@
56961
 
+host_vendor = @host_vendor@
56962
 
+htmldir = @htmldir@
56963
 
+includedir = @includedir@
56964
 
+infodir = @infodir@
56965
 
+install_sh = @install_sh@
56966
 
+libdir = @libdir@
56967
 
+libexecdir = @libexecdir@
56968
 
+localedir = @localedir@
56969
 
+localstatedir = @localstatedir@
56970
 
+lt_ECHO = @lt_ECHO@
56971
 
+mandir = @mandir@
56972
 
+mkdir_p = @mkdir_p@
56973
 
+moduledir = @moduledir@
56974
 
+oldincludedir = @oldincludedir@
56975
 
+pdfdir = @pdfdir@
56976
 
+prefix = @prefix@
56977
 
+program_transform_name = @program_transform_name@
56978
 
+psdir = @psdir@
56979
 
+sbindir = @sbindir@
56980
 
+sharedstatedir = @sharedstatedir@
56981
 
+srcdir = @srcdir@
56982
 
+sysconfdir = @sysconfdir@
56983
 
+target_alias = @target_alias@
56984
 
+top_build_prefix = @top_build_prefix@
56985
 
+top_builddir = @top_builddir@
56986
 
+top_srcdir = @top_srcdir@
56987
 
+noinst_LTLIBRARIES = libsieve_ext_environment.la
56988
 
+AM_CPPFLAGS = \
56989
 
+       -I../../ \
56990
 
+       -I$(dovecot_incdir) \
56991
 
+       -I$(dovecot_incdir)/src/lib \
56992
 
+       -I$(dovecot_incdir)/src/lib-mail \
56993
 
+       -I$(dovecot_incdir)/src/lib-storage 
56994
 
+
56995
 
+tests = \
56996
 
+       tst-environment.c
56997
 
+
56998
 
+libsieve_ext_environment_la_SOURCES = \
56999
 
+       $(tests) \
57000
 
+       ext-environment-common.c \
57001
 
+       ext-environment.c
57002
 
+
57003
 
+noinst_HEADERS = \
57004
 
+       ext-environment-common.h \
57005
 
+       sieve-ext-environment.h
57006
 
+
57007
 
+all: all-am
57008
 
+
57009
 
+.SUFFIXES:
57010
 
+.SUFFIXES: .c .lo .o .obj
57011
 
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
57012
 
+       @for dep in $?; do \
57013
 
+         case '$(am__configure_deps)' in \
57014
 
+           *$$dep*) \
57015
 
+             ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
57016
 
+               && { if test -f $@; then exit 0; else break; fi; }; \
57017
 
+             exit 1;; \
57018
 
+         esac; \
57019
 
+       done; \
57020
 
+       echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign  src/lib-sieve/plugins/environment/Makefile'; \
57021
 
+       cd $(top_srcdir) && \
57022
 
+         $(AUTOMAKE) --foreign  src/lib-sieve/plugins/environment/Makefile
57023
 
+.PRECIOUS: Makefile
57024
 
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
57025
 
+       @case '$?' in \
57026
 
+         *config.status*) \
57027
 
+           cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
57028
 
+         *) \
57029
 
+           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
57030
 
+           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
57031
 
+       esac;
57032
 
+
57033
 
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
57034
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
57035
 
+
57036
 
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
57037
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
57038
 
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
57039
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
57040
 
+
57041
 
+clean-noinstLTLIBRARIES:
57042
 
+       -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
57043
 
+       @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
57044
 
+         dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
57045
 
+         test "$$dir" != "$$p" || dir=.; \
57046
 
+         echo "rm -f \"$${dir}/so_locations\""; \
57047
 
+         rm -f "$${dir}/so_locations"; \
57048
 
+       done
57049
 
+libsieve_ext_environment.la: $(libsieve_ext_environment_la_OBJECTS) $(libsieve_ext_environment_la_DEPENDENCIES) 
57050
 
+       $(LINK)  $(libsieve_ext_environment_la_OBJECTS) $(libsieve_ext_environment_la_LIBADD) $(LIBS)
57051
 
+
57052
 
+mostlyclean-compile:
57053
 
+       -rm -f *.$(OBJEXT)
57054
 
+
57055
 
+distclean-compile:
57056
 
+       -rm -f *.tab.c
57057
 
+
57058
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-environment-common.Plo@am__quote@
57059
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-environment.Plo@am__quote@
57060
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tst-environment.Plo@am__quote@
57061
 
+
57062
 
+.c.o:
57063
 
+@am__fastdepCC_TRUE@   $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
57064
 
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
57065
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
57066
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
57067
 
+@am__fastdepCC_FALSE@  $(COMPILE) -c $<
57068
 
+
57069
 
+.c.obj:
57070
 
+@am__fastdepCC_TRUE@   $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
57071
 
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
57072
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
57073
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
57074
 
+@am__fastdepCC_FALSE@  $(COMPILE) -c `$(CYGPATH_W) '$<'`
57075
 
+
57076
 
+.c.lo:
57077
 
+@am__fastdepCC_TRUE@   $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
57078
 
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
57079
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
57080
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
57081
 
+@am__fastdepCC_FALSE@  $(LTCOMPILE) -c -o $@ $<
57082
 
+
57083
 
+mostlyclean-libtool:
57084
 
+       -rm -f *.lo
57085
 
+
57086
 
+clean-libtool:
57087
 
+       -rm -rf .libs _libs
57088
 
+
57089
 
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
57090
 
+       list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
57091
 
+       unique=`for i in $$list; do \
57092
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
57093
 
+         done | \
57094
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
57095
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
57096
 
+       mkid -fID $$unique
57097
 
+tags: TAGS
57098
 
+
57099
 
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
57100
 
+               $(TAGS_FILES) $(LISP)
57101
 
+       tags=; \
57102
 
+       here=`pwd`; \
57103
 
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
57104
 
+       unique=`for i in $$list; do \
57105
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
57106
 
+         done | \
57107
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
57108
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
57109
 
+       if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
57110
 
+         test -n "$$unique" || unique=$$empty_fix; \
57111
 
+         $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
57112
 
+           $$tags $$unique; \
57113
 
+       fi
57114
 
+ctags: CTAGS
57115
 
+CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
57116
 
+               $(TAGS_FILES) $(LISP)
57117
 
+       tags=; \
57118
 
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
57119
 
+       unique=`for i in $$list; do \
57120
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
57121
 
+         done | \
57122
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
57123
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
57124
 
+       test -z "$(CTAGS_ARGS)$$tags$$unique" \
57125
 
+         || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
57126
 
+            $$tags $$unique
57127
 
+
57128
 
+GTAGS:
57129
 
+       here=`$(am__cd) $(top_builddir) && pwd` \
57130
 
+         && cd $(top_srcdir) \
57131
 
+         && gtags -i $(GTAGS_ARGS) $$here
57132
 
+
57133
 
+distclean-tags:
57134
 
+       -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
57135
 
+
57136
 
+distdir: $(DISTFILES)
57137
 
+       @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
57138
 
+       topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
57139
 
+       list='$(DISTFILES)'; \
57140
 
+         dist_files=`for file in $$list; do echo $$file; done | \
57141
 
+         sed -e "s|^$$srcdirstrip/||;t" \
57142
 
+             -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
57143
 
+       case $$dist_files in \
57144
 
+         */*) $(MKDIR_P) `echo "$$dist_files" | \
57145
 
+                          sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
57146
 
+                          sort -u` ;; \
57147
 
+       esac; \
57148
 
+       for file in $$dist_files; do \
57149
 
+         if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
57150
 
+         if test -d $$d/$$file; then \
57151
 
+           dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
57152
 
+           if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
57153
 
+             cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
57154
 
+           fi; \
57155
 
+           cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
57156
 
+         else \
57157
 
+           test -f $(distdir)/$$file \
57158
 
+           || cp -p $$d/$$file $(distdir)/$$file \
57159
 
+           || exit 1; \
57160
 
+         fi; \
57161
 
+       done
57162
 
+check-am: all-am
57163
 
+check: check-am
57164
 
+all-am: Makefile $(LTLIBRARIES) $(HEADERS)
57165
 
+installdirs:
57166
 
+install: install-am
57167
 
+install-exec: install-exec-am
57168
 
+install-data: install-data-am
57169
 
+uninstall: uninstall-am
57170
 
+
57171
 
+install-am: all-am
57172
 
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
57173
 
+
57174
 
+installcheck: installcheck-am
57175
 
+install-strip:
57176
 
+       $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
57177
 
+         install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
57178
 
+         `test -z '$(STRIP)' || \
57179
 
+           echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
57180
 
+mostlyclean-generic:
57181
 
+
57182
 
+clean-generic:
57183
 
+
57184
 
+distclean-generic:
57185
 
+       -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
57186
 
+
57187
 
+maintainer-clean-generic:
57188
 
+       @echo "This command is intended for maintainers to use"
57189
 
+       @echo "it deletes files that may require special tools to rebuild."
57190
 
+clean: clean-am
57191
 
+
57192
 
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
57193
 
+       mostlyclean-am
57194
 
+
57195
 
+distclean: distclean-am
57196
 
+       -rm -rf ./$(DEPDIR)
57197
 
+       -rm -f Makefile
57198
 
+distclean-am: clean-am distclean-compile distclean-generic \
57199
 
+       distclean-tags
57200
 
+
57201
 
+dvi: dvi-am
57202
 
+
57203
 
+dvi-am:
57204
 
+
57205
 
+html: html-am
57206
 
+
57207
 
+info: info-am
57208
 
+
57209
 
+info-am:
57210
 
+
57211
 
+install-data-am:
57212
 
+
57213
 
+install-dvi: install-dvi-am
57214
 
+
57215
 
+install-exec-am:
57216
 
+
57217
 
+install-html: install-html-am
57218
 
+
57219
 
+install-info: install-info-am
57220
 
+
57221
 
+install-man:
57222
 
+
57223
 
+install-pdf: install-pdf-am
57224
 
+
57225
 
+install-ps: install-ps-am
57226
 
+
57227
 
+installcheck-am:
57228
 
+
57229
 
+maintainer-clean: maintainer-clean-am
57230
 
+       -rm -rf ./$(DEPDIR)
57231
 
+       -rm -f Makefile
57232
 
+maintainer-clean-am: distclean-am maintainer-clean-generic
57233
 
+
57234
 
+mostlyclean: mostlyclean-am
57235
 
+
57236
 
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
57237
 
+       mostlyclean-libtool
57238
 
+
57239
 
+pdf: pdf-am
57240
 
+
57241
 
+pdf-am:
57242
 
+
57243
 
+ps: ps-am
57244
 
+
57245
 
+ps-am:
57246
 
+
57247
 
+uninstall-am:
57248
 
+
57249
 
+.MAKE: install-am install-strip
57250
 
+
57251
 
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
57252
 
+       clean-libtool clean-noinstLTLIBRARIES ctags distclean \
57253
 
+       distclean-compile distclean-generic distclean-libtool \
57254
 
+       distclean-tags distdir dvi dvi-am html html-am info info-am \
57255
 
+       install install-am install-data install-data-am install-dvi \
57256
 
+       install-dvi-am install-exec install-exec-am install-html \
57257
 
+       install-html-am install-info install-info-am install-man \
57258
 
+       install-pdf install-pdf-am install-ps install-ps-am \
57259
 
+       install-strip installcheck installcheck-am installdirs \
57260
 
+       maintainer-clean maintainer-clean-generic mostlyclean \
57261
 
+       mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
57262
 
+       pdf pdf-am ps ps-am tags uninstall uninstall-am
57263
 
+
57264
 
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
57265
 
+# Otherwise a system limit (for SysV at least) may be exceeded.
57266
 
+.NOEXPORT:
57267
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/environment/sieve-ext-environment.h dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/environment/sieve-ext-environment.h
57268
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/environment/sieve-ext-environment.h    1970-01-01 01:00:00.000000000 +0100
57269
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/environment/sieve-ext-environment.h     2009-04-13 21:35:39.000000000 +0200
57270
 
@@ -0,0 +1,16 @@
57271
 
+#ifndef __SIEVE_EXT_ENVIRONMENT_H
57272
 
+#define __SIEVE_EXT_ENVIRONMENT_H
57273
 
+
57274
 
+#include "sieve-common.h"
57275
 
+
57276
 
+struct sieve_environment_item {
57277
 
+       const char *name;
57278
 
+       
57279
 
+       const char *value;
57280
 
+       const char *(*get_value)(const struct sieve_script_env *senv);
57281
 
+};
57282
 
+
57283
 
+void sieve_ext_environment_item_register
57284
 
+       (const struct sieve_environment_item *item);
57285
 
+
57286
 
+#endif
57287
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/environment/tst-environment.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/environment/tst-environment.c
57288
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/environment/tst-environment.c  1970-01-01 01:00:00.000000000 +0100
57289
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/environment/tst-environment.c   2009-07-30 00:44:32.000000000 +0200
57290
 
@@ -0,0 +1,226 @@
57291
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
57292
 
+ */
57293
 
+
57294
 
+#include "sieve-common.h"
57295
 
+#include "sieve-commands.h"
57296
 
+#include "sieve-code.h"
57297
 
+#include "sieve-comparators.h"
57298
 
+#include "sieve-match-types.h"
57299
 
+#include "sieve-validator.h"
57300
 
+#include "sieve-generator.h"
57301
 
+#include "sieve-interpreter.h"
57302
 
+#include "sieve-dump.h"
57303
 
+#include "sieve-match.h"
57304
 
+
57305
 
+#include "ext-environment-common.h"
57306
 
+
57307
 
+/* 
57308
 
+ * Environment test 
57309
 
+ *
57310
 
+ * Syntax:
57311
 
+ *   environment [COMPARATOR] [MATCH-TYPE]
57312
 
+ *      <name: string> <key-list: string-list>
57313
 
+ */
57314
 
+
57315
 
+static bool tst_environment_registered
57316
 
+       (struct sieve_validator *validator, struct sieve_command_registration *cmd_reg);
57317
 
+static bool tst_environment_validate
57318
 
+       (struct sieve_validator *validator, struct sieve_command_context *tst);
57319
 
+static bool tst_environment_generate
57320
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx);
57321
 
+
57322
 
+const struct sieve_command tst_environment = { 
57323
 
+       "environment", 
57324
 
+       SCT_TEST, 
57325
 
+       2, 0, FALSE, FALSE,
57326
 
+       tst_environment_registered, 
57327
 
+       NULL,
57328
 
+       tst_environment_validate, 
57329
 
+       tst_environment_generate, 
57330
 
+       NULL 
57331
 
+};
57332
 
+
57333
 
+/* 
57334
 
+ * Environment operation
57335
 
+ */
57336
 
+
57337
 
+static bool tst_environment_operation_dump
57338
 
+       (const struct sieve_operation *op, 
57339
 
+               const struct sieve_dumptime_env *denv, sieve_size_t *address);
57340
 
+static int tst_environment_operation_execute
57341
 
+       (const struct sieve_operation *op, 
57342
 
+               const struct sieve_runtime_env *renv, sieve_size_t *address);
57343
 
+
57344
 
+const struct sieve_operation tst_environment_operation = { 
57345
 
+       "ENVIRONMENT",
57346
 
+       &environment_extension, 
57347
 
+       0, 
57348
 
+       tst_environment_operation_dump, 
57349
 
+       tst_environment_operation_execute 
57350
 
+};
57351
 
+
57352
 
+/* 
57353
 
+ * Test registration 
57354
 
+ */
57355
 
+
57356
 
+static bool tst_environment_registered
57357
 
+       (struct sieve_validator *validator, struct sieve_command_registration *cmd_reg) 
57358
 
+{
57359
 
+       /* The order of these is not significant */
57360
 
+       sieve_comparators_link_tag(validator, cmd_reg, SIEVE_MATCH_OPT_COMPARATOR);
57361
 
+       sieve_match_types_link_tags(validator, cmd_reg, SIEVE_MATCH_OPT_MATCH_TYPE);
57362
 
+
57363
 
+       return TRUE;
57364
 
+}
57365
 
+
57366
 
+/* 
57367
 
+ * Test validation 
57368
 
+ */
57369
 
+
57370
 
+static bool tst_environment_validate
57371
 
+       (struct sieve_validator *validator, struct sieve_command_context *tst) 
57372
 
+{              
57373
 
+       struct sieve_ast_argument *arg = tst->first_positional;
57374
 
+       
57375
 
+       if ( !sieve_validate_positional_argument
57376
 
+               (validator, tst, arg, "name", 1, SAAT_STRING) ) {
57377
 
+               return FALSE;
57378
 
+       }
57379
 
+       
57380
 
+       if ( !sieve_validator_argument_activate(validator, tst, arg, FALSE) )
57381
 
+               return FALSE;
57382
 
+       
57383
 
+       arg = sieve_ast_argument_next(arg);
57384
 
+
57385
 
+       if ( !sieve_validate_positional_argument
57386
 
+               (validator, tst, arg, "key list", 2, SAAT_STRING_LIST) ) {
57387
 
+               return FALSE;
57388
 
+       }
57389
 
+       
57390
 
+       if ( !sieve_validator_argument_activate(validator, tst, arg, FALSE) )
57391
 
+               return FALSE;
57392
 
+
57393
 
+       /* Validate the key argument to a specified match type */
57394
 
+       return sieve_match_type_validate
57395
 
+               (validator, tst, arg, &is_match_type, &i_octet_comparator);
57396
 
+}
57397
 
+
57398
 
+/* 
57399
 
+ * Test generation 
57400
 
+ */
57401
 
+
57402
 
+static bool tst_environment_generate
57403
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx) 
57404
 
+{
57405
 
+       sieve_operation_emit_code(cgenv->sbin, &tst_environment_operation);
57406
 
+
57407
 
+       /* Generate arguments */
57408
 
+       if ( !sieve_generate_arguments(cgenv, ctx, NULL) )
57409
 
+               return FALSE;
57410
 
+       
57411
 
+       return TRUE;
57412
 
+}
57413
 
+
57414
 
+/* 
57415
 
+ * Code dump 
57416
 
+ */
57417
 
+
57418
 
+static bool tst_environment_operation_dump
57419
 
+(const struct sieve_operation *op ATTR_UNUSED,
57420
 
+       const struct sieve_dumptime_env *denv, sieve_size_t *address)
57421
 
+{
57422
 
+       int opt_code = 0;
57423
 
+
57424
 
+       sieve_code_dumpf(denv, "ENVIRONMENT");
57425
 
+       sieve_code_descend(denv);
57426
 
+
57427
 
+       /* Handle any optional arguments */
57428
 
+       if ( !sieve_match_dump_optional_operands(denv, address, &opt_code) )
57429
 
+               return FALSE;
57430
 
+
57431
 
+       if ( opt_code != SIEVE_MATCH_OPT_END )
57432
 
+               return FALSE;
57433
 
+               
57434
 
+       return
57435
 
+               sieve_opr_string_dump(denv, address, "name") &&
57436
 
+               sieve_opr_stringlist_dump(denv, address, "key list");
57437
 
+}
57438
 
+
57439
 
+/* 
57440
 
+ * Code execution 
57441
 
+ */
57442
 
+
57443
 
+static int tst_environment_operation_execute
57444
 
+(const struct sieve_operation *op ATTR_UNUSED, 
57445
 
+       const struct sieve_runtime_env *renv, sieve_size_t *address)
57446
 
+{
57447
 
+       int ret, mret;
57448
 
+       bool result = TRUE;
57449
 
+       int opt_code = 0;
57450
 
+       const struct sieve_comparator *cmp = &i_ascii_casemap_comparator;
57451
 
+       const struct sieve_match_type *mtch = &is_match_type;
57452
 
+       struct sieve_match_context *mctx;
57453
 
+       string_t *name;
57454
 
+       struct sieve_coded_stringlist *key_list;
57455
 
+       const char *env_item;
57456
 
+       bool matched = FALSE;
57457
 
+
57458
 
+       /*
57459
 
+        * Read operands 
57460
 
+        */
57461
 
+       
57462
 
+       /* Handle match-type and comparator operands */
57463
 
+       if ( (ret=sieve_match_read_optional_operands
57464
 
+               (renv, address, &opt_code, &cmp, &mtch)) <= 0 )
57465
 
+               return ret;
57466
 
+       
57467
 
+       /* Check whether we neatly finished the list of optional operands*/
57468
 
+       if ( opt_code != SIEVE_MATCH_OPT_END) {
57469
 
+               sieve_runtime_trace_error(renv, "invalid optional operand");
57470
 
+               return SIEVE_EXEC_BIN_CORRUPT;
57471
 
+       }
57472
 
+
57473
 
+       /* Read source */
57474
 
+       if ( !sieve_opr_string_read(renv, address, &name) ) {
57475
 
+               sieve_runtime_trace_error(renv, "invalid name operand");
57476
 
+               return SIEVE_EXEC_BIN_CORRUPT;
57477
 
+       }
57478
 
+       
57479
 
+       /* Read key-list */
57480
 
+       if ( (key_list=sieve_opr_stringlist_read(renv, address)) == NULL ) {
57481
 
+               sieve_runtime_trace_error(renv, "invalid key-list operand");
57482
 
+               return SIEVE_EXEC_BIN_CORRUPT;
57483
 
+       }
57484
 
+
57485
 
+       /*
57486
 
+        * Perform operation
57487
 
+        */
57488
 
+
57489
 
+       sieve_runtime_trace(renv, "ENVIRONMENT test");
57490
 
+
57491
 
+       env_item = ext_environment_item_get_value(str_c(name), renv->scriptenv);
57492
 
+
57493
 
+       if ( env_item != NULL ) {
57494
 
+               mctx = sieve_match_begin(renv->interp, mtch, cmp, NULL, key_list);      
57495
 
+
57496
 
+               if ( (mret=sieve_match_value(mctx, strlen(env_item) == 0 ? NULL : env_item, 
57497
 
+                       strlen(env_item))) < 0 ) {
57498
 
+                       result = FALSE;
57499
 
+               } else {
57500
 
+                       matched = ( mret > 0 );                         
57501
 
+               }
57502
 
+
57503
 
+               if ( (mret=sieve_match_end(&mctx)) < 0 )
57504
 
+                       result = FALSE;
57505
 
+               else
57506
 
+                       matched = ( mret > 0 || matched );
57507
 
+       }
57508
 
+       
57509
 
+       if ( result ) {
57510
 
+               sieve_interpreter_set_test_result(renv->interp, matched);
57511
 
+               return SIEVE_EXEC_OK;
57512
 
+       }
57513
 
+       
57514
 
+       sieve_runtime_trace_error(renv, "invalid key list item");
57515
 
+       return SIEVE_EXEC_BIN_CORRUPT;
57516
 
+}
57517
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/imap4flags/cmd-flag.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/imap4flags/cmd-flag.c
57518
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/imap4flags/cmd-flag.c  1970-01-01 01:00:00.000000000 +0100
57519
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/imap4flags/cmd-flag.c   2009-08-05 11:49:11.000000000 +0200
57520
 
@@ -0,0 +1,268 @@
57521
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
57522
 
+ */
57523
 
+
57524
 
+#include "lib.h"
57525
 
+
57526
 
+#include "sieve-code.h"
57527
 
+#include "sieve-commands.h"
57528
 
+#include "sieve-validator.h" 
57529
 
+#include "sieve-generator.h"
57530
 
+#include "sieve-interpreter.h"
57531
 
+#include "sieve-dump.h"
57532
 
+
57533
 
+#include "ext-imap4flags-common.h"
57534
 
+
57535
 
+/*
57536
 
+ * Commands
57537
 
+ */
57538
 
+
57539
 
+/* Forward declarations */
57540
 
+
57541
 
+static bool cmd_flag_generate
57542
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx);
57543
 
+
57544
 
+/* Setflag command 
57545
 
+ *
57546
 
+ * Syntax: 
57547
 
+ *   setflag [<variablename: string>] <list-of-flags: string-list>
57548
 
+ */
57549
 
57550
 
+const struct sieve_command cmd_setflag = { 
57551
 
+       "setflag", 
57552
 
+       SCT_COMMAND,
57553
 
+       -1, /* We check positional arguments ourselves */
57554
 
+       0, FALSE, FALSE, 
57555
 
+       NULL, NULL,
57556
 
+       ext_imap4flags_command_validate, 
57557
 
+       cmd_flag_generate, 
57558
 
+       NULL 
57559
 
+};
57560
 
+
57561
 
+/* Addflag command 
57562
 
+ *
57563
 
+ * Syntax:
57564
 
+ *   addflag [<variablename: string>] <list-of-flags: string-list>
57565
 
+ */
57566
 
+
57567
 
+const struct sieve_command cmd_addflag = { 
57568
 
+       "addflag", 
57569
 
+       SCT_COMMAND,
57570
 
+       -1, /* We check positional arguments ourselves */
57571
 
+       0, FALSE, FALSE, 
57572
 
+       NULL, NULL,
57573
 
+       ext_imap4flags_command_validate, 
57574
 
+       cmd_flag_generate, 
57575
 
+       NULL 
57576
 
+};
57577
 
+
57578
 
+
57579
 
+/* Removeflag command 
57580
 
+ *
57581
 
+ * Syntax:
57582
 
+ *   removeflag [<variablename: string>] <list-of-flags: string-list>
57583
 
+ */
57584
 
+
57585
 
+const struct sieve_command cmd_removeflag = { 
57586
 
+       "removeflag", 
57587
 
+       SCT_COMMAND,
57588
 
+       -1, /* We check positional arguments ourselves */
57589
 
+       0, FALSE, FALSE, 
57590
 
+       NULL, NULL,
57591
 
+       ext_imap4flags_command_validate, 
57592
 
+       cmd_flag_generate, 
57593
 
+       NULL 
57594
 
+};
57595
 
+
57596
 
+/*
57597
 
+ * Operations
57598
 
+ */
57599
 
+
57600
 
+/* Forward declarations */
57601
 
+
57602
 
+bool cmd_flag_operation_dump
57603
 
+       (const struct sieve_operation *op,
57604
 
+               const struct sieve_dumptime_env *denv, sieve_size_t *address);
57605
 
+static int cmd_flag_operation_execute
57606
 
+       (const struct sieve_operation *op,      
57607
 
+               const struct sieve_runtime_env *renv, sieve_size_t *address);
57608
 
+
57609
 
+/* Setflag operation */
57610
 
+
57611
 
+const struct sieve_operation setflag_operation = { 
57612
 
+       "SETFLAG",
57613
 
+       &imap4flags_extension,
57614
 
+       ext_imap4flags_OPERATION_SETFLAG,
57615
 
+       cmd_flag_operation_dump,
57616
 
+       cmd_flag_operation_execute
57617
 
+};
57618
 
+
57619
 
+/* Addflag operation */
57620
 
+
57621
 
+const struct sieve_operation addflag_operation = { 
57622
 
+       "ADDFLAG",
57623
 
+       &imap4flags_extension,
57624
 
+       ext_imap4flags_OPERATION_ADDFLAG,
57625
 
+       cmd_flag_operation_dump,        
57626
 
+       cmd_flag_operation_execute
57627
 
+};
57628
 
+
57629
 
+/* Removeflag operation */
57630
 
+
57631
 
+const struct sieve_operation removeflag_operation = { 
57632
 
+       "REMOVEFLAG",
57633
 
+       &imap4flags_extension,
57634
 
+       ext_imap4flags_OPERATION_REMOVEFLAG,
57635
 
+       cmd_flag_operation_dump, 
57636
 
+       cmd_flag_operation_execute 
57637
 
+};
57638
 
+
57639
 
+/* 
57640
 
+ * Code generation 
57641
 
+ */
57642
 
+
57643
 
+static bool cmd_flag_generate
57644
 
+(const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx)
57645
 
+{
57646
 
+       const struct sieve_command *command = ctx->command;
57647
 
+
57648
 
+       /* Emit operation */
57649
 
+       if ( command == &cmd_setflag ) 
57650
 
+               sieve_operation_emit_code(cgenv->sbin, &setflag_operation);
57651
 
+       else if ( command == &cmd_addflag ) 
57652
 
+               sieve_operation_emit_code(cgenv->sbin, &addflag_operation);
57653
 
+       else if ( command == &cmd_removeflag ) 
57654
 
+               sieve_operation_emit_code(cgenv->sbin, &removeflag_operation);
57655
 
+
57656
 
+       /* Generate arguments */
57657
 
+       if ( !sieve_generate_arguments(cgenv, ctx, NULL) )
57658
 
+               return FALSE;   
57659
 
+
57660
 
+       return TRUE;
57661
 
+}
57662
 
+
57663
 
+/*
57664
 
+ * Code dump
57665
 
+ */
57666
 
+
57667
 
+bool cmd_flag_operation_dump
57668
 
+(const struct sieve_operation *op,
57669
 
+       const struct sieve_dumptime_env *denv, sieve_size_t *address)
57670
 
+{
57671
 
+       const struct sieve_operand *operand;
57672
 
+
57673
 
+       sieve_code_dumpf(denv, "%s", op->mnemonic);
57674
 
+       sieve_code_descend(denv);
57675
 
+       
57676
 
+       sieve_code_mark(denv);
57677
 
+       operand = sieve_operand_read(denv->sbin, address);
57678
 
+       if ( operand == NULL ) {
57679
 
+               sieve_code_dumpf(denv, "ERROR: INVALID OPERAND");
57680
 
+               return FALSE;
57681
 
+       }
57682
 
+
57683
 
+       if ( sieve_operand_is_variable(operand) ) {     
57684
 
+               return 
57685
 
+                       sieve_opr_string_dump_data(denv, operand, address, 
57686
 
+                               "variable name") &&
57687
 
+                       sieve_opr_stringlist_dump(denv, address, 
57688
 
+                               "list of flags");
57689
 
+       }
57690
 
+       
57691
 
+       return 
57692
 
+               sieve_opr_stringlist_dump_data(denv, operand, address,
57693
 
+                       "list of flags");
57694
 
+}
57695
 
57696
 
+/*
57697
 
+ * Code execution
57698
 
+ */
57699
 
+
57700
 
+static int cmd_flag_operation_execute
57701
 
+(const struct sieve_operation *op,
57702
 
+       const struct sieve_runtime_env *renv, sieve_size_t *address)
57703
 
+{
57704
 
+       const struct sieve_operand *operand;
57705
 
+       sieve_size_t op_address = *address;
57706
 
+       bool result = TRUE;
57707
 
+       string_t *flag_item;
57708
 
+       struct sieve_coded_stringlist *flag_list;
57709
 
+       struct sieve_variable_storage *storage;
57710
 
+       unsigned int var_index;
57711
 
+       ext_imapflag_flag_operation_t flag_op;
57712
 
+       int ret;
57713
 
+               
57714
 
+       /* 
57715
 
+        * Read operands 
57716
 
+        */
57717
 
+
57718
 
+       operand = sieve_operand_read(renv->sbin, address);
57719
 
+       if ( operand == NULL ) {
57720
 
+               sieve_runtime_trace_error(renv, "invalid operand");
57721
 
+               return SIEVE_EXEC_BIN_CORRUPT;
57722
 
+       }
57723
 
+               
57724
 
+       if ( sieve_operand_is_variable(operand) ) {             
57725
 
+
57726
 
+               /* Read the variable operand */
57727
 
+               if ( !sieve_variable_operand_read_data
57728
 
+                       (renv, operand, address, &storage, &var_index) ) {
57729
 
+                       sieve_runtime_trace_error(renv, "invalid variable operand");
57730
 
+                       return SIEVE_EXEC_BIN_CORRUPT;
57731
 
+               }
57732
 
+               
57733
 
+               /* Read flag list */
57734
 
+               if ( (flag_list=sieve_opr_stringlist_read(renv, address)) == NULL ) {
57735
 
+                       sieve_runtime_trace_error(renv, "invalid flag-list operand");
57736
 
+                       return SIEVE_EXEC_BIN_CORRUPT;
57737
 
+               }
57738
 
+
57739
 
+       } else if ( sieve_operand_is_stringlist(operand) ) {    
57740
 
+               storage = NULL;
57741
 
+               var_index = 0;
57742
 
+               
57743
 
+               /* Read flag list */
57744
 
+               if ( (flag_list=sieve_opr_stringlist_read_data
57745
 
+                       (renv, operand, op_address, address)) == NULL ) {
57746
 
+                       sieve_runtime_trace_error(renv, "invalid flag-list operand");
57747
 
+                       return SIEVE_EXEC_BIN_CORRUPT;
57748
 
+               }
57749
 
+
57750
 
+       } else {
57751
 
+               sieve_runtime_trace_error(renv, "unexpected operand '%s'", 
57752
 
+                       operand->name);
57753
 
+               return SIEVE_EXEC_BIN_CORRUPT;
57754
 
+       }
57755
 
+       
57756
 
+       /*
57757
 
+        * Perform operation
57758
 
+        */     
57759
 
+       
57760
 
+       sieve_runtime_trace(renv, "%s command", op->mnemonic);
57761
 
+
57762
 
+       /* Determine what to do */
57763
 
+
57764
 
+       if ( op == &setflag_operation )
57765
 
+               flag_op = ext_imap4flags_set_flags;
57766
 
+       else if ( op == &addflag_operation )
57767
 
+               flag_op = ext_imap4flags_add_flags;
57768
 
+       else if ( op == &removeflag_operation )
57769
 
+               flag_op = ext_imap4flags_remove_flags;
57770
 
+       else
57771
 
+               i_unreached();
57772
 
+
57773
 
+       /* Iterate through all flags and perform requested operation */
57774
 
+       
57775
 
+       while ( (result=sieve_coded_stringlist_next_item(flag_list, &flag_item)) && 
57776
 
+               flag_item != NULL ) {
57777
 
+
57778
 
+               if ( (ret=flag_op(renv, storage, var_index, flag_item)) <= 0)
57779
 
+                       return ret;
57780
 
+       }
57781
 
+
57782
 
+       if ( !result ) {        
57783
 
+               sieve_runtime_trace_error(renv, "invalid flag-list item");
57784
 
+               return SIEVE_EXEC_BIN_CORRUPT;
57785
 
+       }
57786
 
+
57787
 
+       return SIEVE_EXEC_OK;
57788
 
+}
57789
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/imap4flags/ext-imap4flags.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/imap4flags/ext-imap4flags.c
57790
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/imap4flags/ext-imap4flags.c    1970-01-01 01:00:00.000000000 +0100
57791
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/imap4flags/ext-imap4flags.c     2009-02-04 20:23:16.000000000 +0100
57792
 
@@ -0,0 +1,88 @@
57793
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
57794
 
+ */
57795
 
+
57796
 
+/* Extension imap4flags
57797
 
+ * --------------------
57798
 
+ *
57799
 
+ * Authors: Stephan Bosch
57800
 
+ * Specification: RFC 5232
57801
 
+ * Implementation: full 
57802
 
+ * Status: experimental, roughly tested
57803
 
+ *
57804
 
+ */
57805
 
57806
 
+#include "lib.h"
57807
 
+#include "mempool.h"
57808
 
+#include "str.h"
57809
 
+
57810
 
+#include "sieve-common.h"
57811
 
+
57812
 
+#include "sieve-code.h"
57813
 
+#include "sieve-extensions.h"
57814
 
+#include "sieve-actions.h"
57815
 
+#include "sieve-commands.h"
57816
 
+#include "sieve-validator.h"
57817
 
+#include "sieve-generator.h"
57818
 
+#include "sieve-interpreter.h"
57819
 
+
57820
 
+#include "ext-imap4flags-common.h"
57821
 
+
57822
 
+/* 
57823
 
+ * Operations 
57824
 
+ */
57825
 
+
57826
 
+const struct sieve_operation *imap4flags_operations[] = { 
57827
 
+       &setflag_operation, 
57828
 
+       &addflag_operation, 
57829
 
+       &removeflag_operation,
57830
 
+       &hasflag_operation 
57831
 
+};
57832
 
+
57833
 
+/* 
57834
 
+ * Extension
57835
 
+ */
57836
 
+
57837
 
+static bool ext_imap4flags_validator_load(struct sieve_validator *valdtr);
57838
 
+static bool ext_imap4flags_interpreter_load
57839
 
+       (const struct sieve_runtime_env *renv, sieve_size_t *address);
57840
 
+
57841
 
+int ext_imap4flags_my_id = -1;
57842
 
+
57843
 
+const struct sieve_extension imap4flags_extension = { 
57844
 
+       "imap4flags", 
57845
 
+       &ext_imap4flags_my_id,
57846
 
+       NULL, NULL,
57847
 
+       ext_imap4flags_validator_load, 
57848
 
+       NULL, 
57849
 
+       ext_imap4flags_interpreter_load, 
57850
 
+       NULL, NULL, NULL,
57851
 
+       SIEVE_EXT_DEFINE_OPERATIONS(imap4flags_operations), 
57852
 
+       SIEVE_EXT_DEFINE_OPERAND(flags_side_effect_operand)
57853
 
+};
57854
 
+
57855
 
+static bool ext_imap4flags_validator_load
57856
 
+(struct sieve_validator *valdtr)
57857
 
+{
57858
 
+       /* Register commands */
57859
 
+       sieve_validator_register_command(valdtr, &cmd_setflag);
57860
 
+       sieve_validator_register_command(valdtr, &cmd_addflag);
57861
 
+       sieve_validator_register_command(valdtr, &cmd_removeflag);
57862
 
+       sieve_validator_register_command(valdtr, &tst_hasflag);
57863
 
+       
57864
 
+       ext_imap4flags_attach_flags_tag(valdtr, "keep");
57865
 
+       ext_imap4flags_attach_flags_tag(valdtr, "fileinto");
57866
 
+
57867
 
+       return TRUE;
57868
 
+}
57869
 
+
57870
 
+static bool ext_imap4flags_interpreter_load
57871
 
+(const struct sieve_runtime_env *renv, sieve_size_t *address ATTR_UNUSED)
57872
 
+{
57873
 
+       sieve_interpreter_extension_register
57874
 
+        (renv->interp, &imap4flags_interpreter_extension, NULL);
57875
 
+
57876
 
+       return TRUE;
57877
 
+}
57878
 
+
57879
 
+
57880
 
+
57881
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/imap4flags/ext-imap4flags-common.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/imap4flags/ext-imap4flags-common.c
57882
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/imap4flags/ext-imap4flags-common.c     1970-01-01 01:00:00.000000000 +0100
57883
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/imap4flags/ext-imap4flags-common.c      2009-08-05 12:41:48.000000000 +0200
57884
 
@@ -0,0 +1,521 @@
57885
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
57886
 
+ */
57887
 
+
57888
 
+#include "lib.h"
57889
 
+#include "str.h"
57890
 
+#include "str-sanitize.h"
57891
 
+
57892
 
+#include "sieve-common.h"
57893
 
+#include "sieve-commands.h"
57894
 
+#include "sieve-code.h"
57895
 
+#include "sieve-actions.h"
57896
 
+#include "sieve-validator.h" 
57897
 
+#include "sieve-generator.h"
57898
 
+#include "sieve-interpreter.h"
57899
 
+#include "sieve-result.h"
57900
 
+#include "sieve-dump.h"
57901
 
+
57902
 
+#include "sieve-ext-variables.h"
57903
 
+
57904
 
+#include "ext-imap4flags-common.h"
57905
 
+
57906
 
+/*
57907
 
+ * Forward declarations
57908
 
+ */
57909
 
+
57910
 
+static bool flag_is_valid(const char *flag);
57911
 
+
57912
 
+/* 
57913
 
+ * Tagged arguments 
57914
 
+ */
57915
 
+
57916
 
+extern const struct sieve_argument tag_flags;
57917
 
+extern const struct sieve_argument tag_flags_implicit;
57918
 
+
57919
 
+/* 
57920
 
+ * Common command functions 
57921
 
+ */
57922
 
+
57923
 
+bool ext_imap4flags_command_validate
57924
 
+(struct sieve_validator *validator, struct sieve_command_context *cmd)
57925
 
+{
57926
 
+       struct sieve_ast_argument *arg = cmd->first_positional;
57927
 
+       struct sieve_ast_argument *arg2;
57928
 
+       
57929
 
+       /* Check arguments */
57930
 
+       
57931
 
+       if ( arg == NULL ) {
57932
 
+               sieve_command_validate_error(validator, cmd, 
57933
 
+                       "the %s %s expects at least one argument, but none was found", 
57934
 
+                       cmd->command->identifier, sieve_command_type_name(cmd->command));
57935
 
+               return FALSE;
57936
 
+       }
57937
 
+       
57938
 
+       if ( sieve_ast_argument_type(arg) != SAAT_STRING && 
57939
 
+               sieve_ast_argument_type(arg) != SAAT_STRING_LIST ) 
57940
 
+       {
57941
 
+               sieve_argument_validate_error(validator, arg, 
57942
 
+                       "the %s %s expects either a string (variable name) or "
57943
 
+                       "a string-list (list of flags) as first argument, but %s was found", 
57944
 
+                       cmd->command->identifier, sieve_command_type_name(cmd->command),
57945
 
+                       sieve_ast_argument_name(arg));
57946
 
+               return FALSE; 
57947
 
+       }
57948
 
+
57949
 
+       arg2 = sieve_ast_argument_next(arg);
57950
 
+       if ( arg2 != NULL ) {           
57951
 
+               /* First, check syntax sanity */
57952
 
+                               
57953
 
+               if ( sieve_ast_argument_type(arg) != SAAT_STRING ) 
57954
 
+               {
57955
 
+                       if ( cmd->command == &tst_hasflag ) {
57956
 
+                               if ( sieve_ast_argument_type(arg) != SAAT_STRING_LIST ) {
57957
 
+                                       sieve_argument_validate_error(validator, arg, 
57958
 
+                                               "if a second argument is specified for the hasflag, the first "
57959
 
+                                               "must be a string-list (variable-list), but %s was found",
57960
 
+                                               sieve_ast_argument_name(arg));
57961
 
+                                       return FALSE;
57962
 
+                               }
57963
 
+                       } else {
57964
 
+                               sieve_argument_validate_error(validator, arg, 
57965
 
+                                       "if a second argument is specified for the %s %s, the first "
57966
 
+                                       "must be a string (variable name), but %s was found",
57967
 
+                                       cmd->command->identifier, sieve_command_type_name(cmd->command), 
57968
 
+                                       sieve_ast_argument_name(arg));
57969
 
+                               return FALSE; 
57970
 
+                       }
57971
 
+               }
57972
 
+               
57973
 
+               /* Then, check whether the second argument is permitted */
57974
 
+               
57975
 
+               if ( !sieve_ext_variables_is_active(validator) )        {
57976
 
+                       sieve_argument_validate_error(validator,arg, 
57977
 
+                               "the %s %s only allows for the specification of a "
57978
 
+                               "variable name when the variables extension is active",
57979
 
+                               cmd->command->identifier, sieve_command_type_name(cmd->command));
57980
 
+                       return FALSE;
57981
 
+               }               
57982
 
+               
57983
 
+               if ( !sieve_variable_argument_activate(validator, cmd, arg, 
57984
 
+                       cmd->command != &tst_hasflag ) )
57985
 
+                       return FALSE;
57986
 
+               
57987
 
+               if ( sieve_ast_argument_type(arg2) != SAAT_STRING && 
57988
 
+                       sieve_ast_argument_type(arg2) != SAAT_STRING_LIST ) 
57989
 
+               {
57990
 
+                       sieve_argument_validate_error(validator, arg2, 
57991
 
+                               "the %s %s expects a string list (list of flags) as "
57992
 
+                               "second argument when two arguments are specified, "
57993
 
+                               "but %s was found",
57994
 
+                               cmd->command->identifier, sieve_command_type_name(cmd->command),
57995
 
+                               sieve_ast_argument_name(arg2));
57996
 
+                       return FALSE; 
57997
 
+               }
57998
 
+       } else
57999
 
+               arg2 = arg;
58000
 
+
58001
 
+       if ( !sieve_validator_argument_activate(validator, cmd, arg2, FALSE) )
58002
 
+               return FALSE;
58003
 
+
58004
 
+       if ( cmd->command != &tst_hasflag && sieve_argument_is_string_literal(arg2) ) {
58005
 
+               struct ext_imap4flags_iter fiter;
58006
 
+               const char *flag;
58007
 
+               
58008
 
+               /* Warn the user about validity of verifiable flags */
58009
 
+               ext_imap4flags_iter_init(&fiter, sieve_ast_argument_str(arg));
58010
 
+
58011
 
+               while ( (flag=ext_imap4flags_iter_get_flag(&fiter)) != NULL ) {
58012
 
+                       if ( !flag_is_valid(flag) ) {
58013
 
+                               sieve_argument_validate_warning(validator, arg,
58014
 
+                       "IMAP flag '%s' specified for the %s command is invalid "
58015
 
+                                       "and will be ignored (only first invalid is reported)",                                 
58016
 
+                                       str_sanitize(flag, 64), cmd->command->identifier);
58017
 
+                               break;
58018
 
+                       }
58019
 
+               }
58020
 
+       }
58021
 
+
58022
 
+       return TRUE;
58023
 
+}
58024
 
+
58025
 
+/* 
58026
 
+ * Flags tag registration 
58027
 
+ */
58028
 
+
58029
 
+void ext_imap4flags_attach_flags_tag
58030
 
+(struct sieve_validator *valdtr, const char *command)
58031
 
+{
58032
 
+       /* Register :flags tag with the command and we don't care whether it is 
58033
 
+        * registered or even whether it will be registered at all. The validator 
58034
 
+        * handles either situation gracefully 
58035
 
+        */
58036
 
+        
58037
 
+       /* Tag specified by user */
58038
 
+       sieve_validator_register_external_tag
58039
 
+               (valdtr, &tag_flags, command, SIEVE_OPT_SIDE_EFFECT);
58040
 
+
58041
 
+    /* Implicit tag if none is specified */
58042
 
+       sieve_validator_register_persistent_tag
58043
 
+               (valdtr, &tag_flags_implicit, command);
58044
 
+}
58045
 
+
58046
 
+/* 
58047
 
+ * Result context 
58048
 
+ */
58049
 
+
58050
 
+struct ext_imap4flags_result_context {
58051
 
+    string_t *internal_flags;
58052
 
+};
58053
 
+
58054
 
+static void _get_initial_flags
58055
 
+(struct sieve_result *result, string_t *flags)
58056
 
+{
58057
 
+       const struct sieve_message_data *msgdata = 
58058
 
+               sieve_result_get_message_data(result);
58059
 
+       enum mail_flags mail_flags;
58060
 
+       const char *const *mail_keywords;
58061
 
+
58062
 
+       mail_flags = mail_get_flags(msgdata->mail);
58063
 
+       mail_keywords = mail_get_keywords(msgdata->mail);       
58064
 
+
58065
 
+       if ( (mail_flags & MAIL_FLAGGED) > 0 )
58066
 
+               str_printfa(flags, " \\flagged");
58067
 
+
58068
 
+       if ( (mail_flags & MAIL_ANSWERED) > 0 )
58069
 
+               str_printfa(flags, " \\answered");
58070
 
+
58071
 
+       if ( (mail_flags & MAIL_DELETED) > 0 )
58072
 
+               str_printfa(flags, " \\deleted");
58073
 
+
58074
 
+       if ( (mail_flags & MAIL_SEEN) > 0 )
58075
 
+               str_printfa(flags, " \\seen");
58076
 
+
58077
 
+       if ( (mail_flags & MAIL_DRAFT) > 0 )
58078
 
+               str_printfa(flags, " \\draft");
58079
 
+
58080
 
+       while ( *mail_keywords != NULL ) {
58081
 
+               str_printfa(flags, " %s", *mail_keywords);
58082
 
+               mail_keywords++;
58083
 
+       }       
58084
 
+}
58085
 
+
58086
 
+static inline struct ext_imap4flags_result_context *_get_result_context
58087
 
+(struct sieve_result *result)
58088
 
+{
58089
 
+       struct ext_imap4flags_result_context *rctx =
58090
 
+               (struct ext_imap4flags_result_context *) 
58091
 
+               sieve_result_extension_get_context(result, &imap4flags_extension);
58092
 
+
58093
 
+       if ( rctx == NULL ) {
58094
 
+               pool_t pool = sieve_result_pool(result);
58095
 
+
58096
 
+               rctx =p_new(pool, struct ext_imap4flags_result_context, 1);
58097
 
+               rctx->internal_flags = str_new(pool, 32);
58098
 
+               _get_initial_flags(result, rctx->internal_flags);
58099
 
+
58100
 
+               sieve_result_extension_set_context
58101
 
+                       (result, &imap4flags_extension, rctx);
58102
 
+       }
58103
 
+
58104
 
+       return rctx;
58105
 
+}
58106
 
+
58107
 
+static string_t *_get_flags_string
58108
 
+(struct sieve_result *result)
58109
 
+{
58110
 
+       struct ext_imap4flags_result_context *ctx = 
58111
 
+               _get_result_context(result);
58112
 
+               
58113
 
+       return ctx->internal_flags;
58114
 
+}
58115
 
+
58116
 
+/* 
58117
 
+ * Runtime initialization 
58118
 
+ */
58119
 
+
58120
 
+static void ext_imap4flags_runtime_init
58121
 
+(const struct sieve_runtime_env *renv, void *context ATTR_UNUSED)
58122
 
+{      
58123
 
+       sieve_result_add_implicit_side_effect
58124
 
+               (renv->result, &act_store, &flags_side_effect, NULL);
58125
 
+}
58126
 
+
58127
 
+const struct sieve_interpreter_extension imap4flags_interpreter_extension = {
58128
 
+       &imap4flags_extension,
58129
 
+       ext_imap4flags_runtime_init,
58130
 
+       NULL,
58131
 
+};
58132
 
+
58133
 
+/* 
58134
 
+ * Flag operations 
58135
 
+ */
58136
 
+
58137
 
+/* FIXME: This currently accepts a potentially unlimited number of 
58138
 
+ * flags, making the internal or variable flag list indefinitely long
58139
 
+ */
58140
 
+static bool flag_is_valid(const char *flag)
58141
 
+{      
58142
 
+       if (*flag == '\\') {
58143
 
+               /* System flag */
58144
 
+               const char *atom = t_str_ucase(flag); 
58145
 
+        
58146
 
+               if (
58147
 
+                       (strcmp(atom, "\\ANSWERED") != 0) &&
58148
 
+                       (strcmp(atom, "\\FLAGGED") != 0) &&
58149
 
+                       (strcmp(atom, "\\DELETED") != 0) &&
58150
 
+                       (strcmp(atom, "\\SEEN") != 0) &&
58151
 
+                       (strcmp(atom, "\\DRAFT") != 0) )  
58152
 
+               {           
58153
 
+                       return FALSE;
58154
 
+               }
58155
 
+       } else {
58156
 
+               /* Custom keyword:
58157
 
+                *
58158
 
+                * The validity of the keyword cannot be validated until the 
58159
 
+                * target mailbox for the message is known. Meaning that the 
58160
 
+                * verfication of keyword can only be performed when the
58161
 
+                * action side effect is about to be executed.
58162
 
+                *
58163
 
+                * FIXME: technically this is nonsense, since we can simply parse
58164
 
+                * using the flag-keyword grammar provided by imap.
58165
 
+                */                                     
58166
 
+       }
58167
 
+
58168
 
+       return TRUE;  
58169
 
+}
58170
 
+
58171
 
+void ext_imap4flags_iter_init
58172
 
+(struct ext_imap4flags_iter *iter, string_t *flags_list) 
58173
 
+{
58174
 
+       iter->flags_list = flags_list;
58175
 
+       iter->offset = 0;
58176
 
+       iter->last = 0;
58177
 
+}
58178
 
+
58179
 
+const char *ext_imap4flags_iter_get_flag
58180
 
+(struct ext_imap4flags_iter *iter) 
58181
 
+{
58182
 
+       unsigned int len = str_len(iter->flags_list);
58183
 
+       const unsigned char *fp;
58184
 
+       const unsigned char *fbegin;
58185
 
+       const unsigned char *fstart;
58186
 
+       const unsigned char *fend;
58187
 
+       
58188
 
+       if ( iter->offset >= len ) return NULL;
58189
 
+       
58190
 
+       fbegin = str_data(iter->flags_list);
58191
 
+       fp = fbegin + iter->offset;
58192
 
+       fstart = fp;
58193
 
+       fend = fbegin + len;
58194
 
+       for (;;) {
58195
 
+               if ( fp >= fend || *fp == ' ' ) { 
58196
 
+                       if ( fp > fstart ) {
58197
 
+                               const char *flag = t_strdup_until(fstart, fp);
58198
 
+                               
58199
 
+                               iter->last = fstart - fbegin;
58200
 
+                               iter->offset = fp - fbegin;
58201
 
+                               return flag;
58202
 
+                       }       
58203
 
+                       
58204
 
+                       fstart = fp+1;
58205
 
+               }
58206
 
+               
58207
 
+               if ( fp >= fend ) break;
58208
 
+                               
58209
 
+               fp++;
58210
 
+       }
58211
 
+       
58212
 
+       iter->last = fstart - fbegin;
58213
 
+       iter->offset = fp - fbegin;
58214
 
+       return NULL;
58215
 
+}
58216
 
+
58217
 
+static void ext_imap4flags_iter_delete_last
58218
 
+(struct ext_imap4flags_iter *iter) 
58219
 
+{
58220
 
+       iter->offset++;
58221
 
+       if ( iter->offset > str_len(iter->flags_list) )
58222
 
+               iter->offset = str_len(iter->flags_list);
58223
 
+       if ( iter->offset == str_len(iter->flags_list) )
58224
 
+               iter->last--;
58225
 
+
58226
 
+       str_delete(iter->flags_list, iter->last, iter->offset - iter->last);    
58227
 
+       
58228
 
+       iter->offset = iter->last;
58229
 
+}
58230
 
+
58231
 
+static bool flags_list_flag_exists
58232
 
+(string_t *flags_list, const char *flag)
58233
 
+{
58234
 
+       const char *flg;
58235
 
+       struct ext_imap4flags_iter flit;
58236
 
+               
58237
 
+       ext_imap4flags_iter_init(&flit, flags_list);
58238
 
+       
58239
 
+       while ( (flg=ext_imap4flags_iter_get_flag(&flit)) != NULL ) {
58240
 
+               if ( strcasecmp(flg, flag) == 0 ) 
58241
 
+                       return TRUE;    
58242
 
+       }
58243
 
+       
58244
 
+       return FALSE;
58245
 
+}
58246
 
+
58247
 
+static void flags_list_flag_delete
58248
 
+(string_t *flags_list, const char *flag)
58249
 
+{
58250
 
+       const char *flg;
58251
 
+       struct ext_imap4flags_iter flit;
58252
 
+               
58253
 
+       ext_imap4flags_iter_init(&flit, flags_list);
58254
 
+       
58255
 
+       while ( (flg=ext_imap4flags_iter_get_flag(&flit)) != NULL ) {
58256
 
+               if ( strcasecmp(flg, flag) == 0 ) {
58257
 
+                       ext_imap4flags_iter_delete_last(&flit);
58258
 
+               }       
58259
 
+       }
58260
 
+}
58261
 
+                       
58262
 
+static void flags_list_add_flags
58263
 
+(string_t *flags_list, string_t *flags)
58264
 
+{      
58265
 
+       const char *flg;
58266
 
+       struct ext_imap4flags_iter flit;
58267
 
+               
58268
 
+       ext_imap4flags_iter_init(&flit, flags);
58269
 
+       
58270
 
+       while ( (flg=ext_imap4flags_iter_get_flag(&flit)) != NULL ) {
58271
 
+               if ( flag_is_valid(flg) && !flags_list_flag_exists(flags_list, flg) ) {
58272
 
+                       if ( str_len(flags_list) != 0 ) 
58273
 
+                               str_append_c(flags_list, ' '); 
58274
 
+                       str_append(flags_list, flg);
58275
 
+               }       
58276
 
+       }
58277
 
+}
58278
 
+
58279
 
+static void flags_list_remove_flags
58280
 
+(string_t *flags_list, string_t *flags)
58281
 
+{      
58282
 
+       const char *flg;
58283
 
+       struct ext_imap4flags_iter flit;
58284
 
+               
58285
 
+       ext_imap4flags_iter_init(&flit, flags);
58286
 
+       
58287
 
+       while ( (flg=ext_imap4flags_iter_get_flag(&flit)) != NULL ) {
58288
 
+               flags_list_flag_delete(flags_list, flg);        
58289
 
+       }
58290
 
+}
58291
 
+
58292
 
+static void flags_list_set_flags
58293
 
+(string_t *flags_list, string_t *flags)
58294
 
+{
58295
 
+       str_truncate(flags_list, 0);
58296
 
+       flags_list_add_flags(flags_list, flags);
58297
 
+}
58298
 
+
58299
 
+/* 
58300
 
+ * Flag registration 
58301
 
+ */
58302
 
+
58303
 
+int ext_imap4flags_set_flags
58304
 
+(const struct sieve_runtime_env *renv, struct sieve_variable_storage *storage,
58305
 
+       unsigned int var_index, string_t *flags)
58306
 
+{
58307
 
+       string_t *cur_flags;
58308
 
+       
58309
 
+       if ( storage != NULL ) {
58310
 
+               if ( !sieve_variable_get_modifiable(storage, var_index, &cur_flags) )
58311
 
+                       return SIEVE_EXEC_BIN_CORRUPT;
58312
 
+       } else
58313
 
+               cur_flags = _get_flags_string(renv->result);
58314
 
+
58315
 
+       if ( cur_flags != NULL )
58316
 
+               flags_list_set_flags(cur_flags, flags);         
58317
 
+
58318
 
+       return SIEVE_EXEC_OK;
58319
 
+}
58320
 
+
58321
 
+int ext_imap4flags_add_flags
58322
 
+(const struct sieve_runtime_env *renv, struct sieve_variable_storage *storage,
58323
 
+       unsigned int var_index, string_t *flags)
58324
 
+{
58325
 
+       string_t *cur_flags;
58326
 
+       
58327
 
+       if ( storage != NULL ) {
58328
 
+               if ( !sieve_variable_get_modifiable(storage, var_index, &cur_flags) )
58329
 
+                       return SIEVE_EXEC_BIN_CORRUPT;
58330
 
+       } else
58331
 
+               cur_flags = _get_flags_string(renv->result);
58332
 
+       
58333
 
+       if ( cur_flags != NULL )
58334
 
+               flags_list_add_flags(cur_flags, flags);
58335
 
+       
58336
 
+       return SIEVE_EXEC_OK;   
58337
 
+}
58338
 
+
58339
 
+int ext_imap4flags_remove_flags
58340
 
+(const struct sieve_runtime_env *renv, struct sieve_variable_storage *storage,
58341
 
+       unsigned int var_index, string_t *flags)
58342
 
+{
58343
 
+       string_t *cur_flags;
58344
 
+       
58345
 
+       if ( storage != NULL ) {
58346
 
+               if ( !sieve_variable_get_modifiable(storage, var_index, &cur_flags) )
58347
 
+                       return SIEVE_EXEC_BIN_CORRUPT;
58348
 
+       } else
58349
 
+               cur_flags = _get_flags_string(renv->result);
58350
 
+       
58351
 
+       if ( cur_flags != NULL )
58352
 
+               flags_list_remove_flags(cur_flags, flags);              
58353
 
+
58354
 
+       return SIEVE_EXEC_OK;
58355
 
+}
58356
 
+
58357
 
+int ext_imap4flags_get_flags_string
58358
 
+(const struct sieve_runtime_env *renv, struct sieve_variable_storage *storage, 
58359
 
+       unsigned int var_index, const char **flags)
58360
 
+{
58361
 
+       string_t *cur_flags;
58362
 
+       
58363
 
+       if ( storage != NULL ) {
58364
 
+               if ( !sieve_variable_get_modifiable(storage, var_index, &cur_flags) )
58365
 
+                       return SIEVE_EXEC_BIN_CORRUPT;
58366
 
+       } else
58367
 
+               cur_flags = _get_flags_string(renv->result);
58368
 
+       
58369
 
+       if ( cur_flags == NULL )
58370
 
+               *flags = "";
58371
 
+       else 
58372
 
+               *flags = str_c(cur_flags);
58373
 
+
58374
 
+       return SIEVE_EXEC_OK;
58375
 
+}
58376
 
+
58377
 
+void ext_imap4flags_get_flags_init
58378
 
+(struct ext_imap4flags_iter *iter, const struct sieve_runtime_env *renv,
58379
 
+       string_t *flags_list)
58380
 
+{
58381
 
+       string_t *cur_flags;
58382
 
+       
58383
 
+       if ( flags_list != NULL ) {
58384
 
+               cur_flags = t_str_new(256);
58385
 
+               
58386
 
+               flags_list_set_flags(cur_flags, flags_list);
58387
 
+       }
58388
 
+       else
58389
 
+               cur_flags = _get_flags_string(renv->result);
58390
 
+       
58391
 
+       ext_imap4flags_iter_init(iter, cur_flags);              
58392
 
+}
58393
 
+
58394
 
+void ext_imap4flags_get_implicit_flags_init
58395
 
+(struct ext_imap4flags_iter *iter, struct sieve_result *result)
58396
 
+{
58397
 
+       string_t *cur_flags = _get_flags_string(result);
58398
 
+       
58399
 
+       ext_imap4flags_iter_init(iter, cur_flags);              
58400
 
+}
58401
 
+
58402
 
+
58403
 
+       
58404
 
+       
58405
 
+
58406
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/imap4flags/ext-imap4flags-common.h dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/imap4flags/ext-imap4flags-common.h
58407
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/imap4flags/ext-imap4flags-common.h     1970-01-01 01:00:00.000000000 +0100
58408
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/imap4flags/ext-imap4flags-common.h      2009-02-04 20:23:33.000000000 +0100
58409
 
@@ -0,0 +1,118 @@
58410
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
58411
 
+ */
58412
 
+
58413
 
+#ifndef __EXT_IMAP4FLAGS_COMMON_H
58414
 
+#define __EXT_IMAP4FLAGS_COMMON_H
58415
 
+
58416
 
+#include "lib.h"
58417
 
+
58418
 
+#include "sieve-common.h"
58419
 
+#include "sieve-ext-variables.h"
58420
 
+
58421
 
+/*
58422
 
+ * Extension
58423
 
+ */
58424
 
58425
 
+extern const struct sieve_extension imap4flags_extension;
58426
 
+extern const struct sieve_interpreter_extension 
58427
 
+       imap4flags_interpreter_extension;
58428
 
+
58429
 
+/*
58430
 
+ * Side effect
58431
 
+ */
58432
 
+
58433
 
+extern const struct sieve_side_effect flags_side_effect;
58434
 
+
58435
 
+/*
58436
 
+ * Operands
58437
 
+ */
58438
 
+
58439
 
+extern const struct sieve_operand flags_side_effect_operand;
58440
 
+
58441
 
+/*
58442
 
+ * Operations
58443
 
+ */
58444
 
58445
 
+enum ext_imap4flags_opcode {
58446
 
+       ext_imap4flags_OPERATION_SETFLAG,
58447
 
+       ext_imap4flags_OPERATION_ADDFLAG,
58448
 
+       ext_imap4flags_OPERATION_REMOVEFLAG,
58449
 
+       ext_imap4flags_OPERATION_HASFLAG
58450
 
+};
58451
 
+
58452
 
+extern const struct sieve_operation setflag_operation;
58453
 
+extern const struct sieve_operation addflag_operation;
58454
 
+extern const struct sieve_operation removeflag_operation;
58455
 
+extern const struct sieve_operation hasflag_operation;
58456
 
+
58457
 
+/* 
58458
 
+ * Commands 
58459
 
+ */
58460
 
+
58461
 
+extern const struct sieve_command cmd_setflag;
58462
 
+extern const struct sieve_command cmd_addflag;
58463
 
+extern const struct sieve_command cmd_removeflag;
58464
 
+
58465
 
+extern const struct sieve_command tst_hasflag;
58466
 
+
58467
 
+/*
58468
 
+ * Common command functions
58469
 
+ */
58470
 
+
58471
 
+bool ext_imap4flags_command_validate
58472
 
+       (struct sieve_validator *validator, struct sieve_command_context *cmd);
58473
 
+
58474
 
+/*
58475
 
+ * Flags tagged argument
58476
 
+ */    
58477
 
+       
58478
 
+void ext_imap4flags_attach_flags_tag
58479
 
+       (struct sieve_validator *valdtr, const char *command);
58480
 
+
58481
 
+/* 
58482
 
+ * Flag management 
58483
 
+ */
58484
 
+
58485
 
+struct ext_imap4flags_iter {
58486
 
+       string_t *flags_list;
58487
 
+       unsigned int offset;
58488
 
+       unsigned int last;
58489
 
+};
58490
 
+
58491
 
+void ext_imap4flags_iter_init
58492
 
+       (struct ext_imap4flags_iter *iter, string_t *flags_list);
58493
 
+       
58494
 
+const char *ext_imap4flags_iter_get_flag
58495
 
+       (struct ext_imap4flags_iter *iter);
58496
 
+
58497
 
+typedef int (*ext_imapflag_flag_operation_t)
58498
 
+       (const struct sieve_runtime_env *renv, struct sieve_variable_storage *storage,
58499
 
+               unsigned int var_index, string_t *flags);
58500
 
+
58501
 
+int ext_imap4flags_set_flags
58502
 
+       (const struct sieve_runtime_env *renv, struct sieve_variable_storage *storage,
58503
 
+               unsigned int var_index, string_t *flags);
58504
 
+int ext_imap4flags_add_flags
58505
 
+       (const struct sieve_runtime_env *renv, struct sieve_variable_storage *storage,
58506
 
+               unsigned int var_index, string_t *flags);
58507
 
+int ext_imap4flags_remove_flags
58508
 
+       (const struct sieve_runtime_env *renv, struct sieve_variable_storage *storage,
58509
 
+               unsigned int var_index, string_t *flags);
58510
 
+
58511
 
+/*
58512
 
+ * Flags access
58513
 
+ */
58514
 
+
58515
 
+int ext_imap4flags_get_flags_string
58516
 
+(const struct sieve_runtime_env *renv, struct sieve_variable_storage *storage, 
58517
 
+       unsigned int var_index, const char **flags);
58518
 
+
58519
 
+void ext_imap4flags_get_flags_init
58520
 
+       (struct ext_imap4flags_iter *iter, const struct sieve_runtime_env *renv,
58521
 
+               string_t *flags_list);
58522
 
+void ext_imap4flags_get_implicit_flags_init
58523
 
+       (struct ext_imap4flags_iter *iter, struct sieve_result *result);
58524
 
+
58525
 
+
58526
 
+#endif /* __EXT_IMAP4FLAGS_COMMON_H */
58527
 
+
58528
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/imap4flags/ext-imapflags.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/imap4flags/ext-imapflags.c
58529
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/imap4flags/ext-imapflags.c     1970-01-01 01:00:00.000000000 +0100
58530
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/imap4flags/ext-imapflags.c      2009-07-08 17:06:04.000000000 +0200
58531
 
@@ -0,0 +1,175 @@
58532
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
58533
 
+ */
58534
 
+
58535
 
+/* Extension imapflags
58536
 
+ * --------------------
58537
 
+ *
58538
 
+ * Authors: Stephan Bosch
58539
 
+ * Specification: draft-melnikov-sieve-imapflags-03.txt
58540
 
+ * Implementation: deprecated; provided for backwards compatibility
58541
 
+ * Status: deprecated
58542
 
+ *
58543
 
+ */
58544
 
58545
 
+#include "lib.h"
58546
 
+#include "mempool.h"
58547
 
+#include "str.h"
58548
 
+
58549
 
+#include "sieve-common.h"
58550
 
+
58551
 
+#include "sieve-ast.h"
58552
 
+#include "sieve-code.h"
58553
 
+#include "sieve-extensions.h"
58554
 
+#include "sieve-actions.h"
58555
 
+#include "sieve-commands.h"
58556
 
+#include "sieve-validator.h"
58557
 
+#include "sieve-generator.h"
58558
 
+#include "sieve-interpreter.h"
58559
 
+
58560
 
+#include "ext-imap4flags-common.h"
58561
 
+
58562
 
+/*
58563
 
+ * Commands
58564
 
+ */
58565
 
+
58566
 
+static bool cmd_mark_validate
58567
 
+       (struct sieve_validator *valdtr, struct sieve_command_context *cmd);
58568
 
+
58569
 
+/* Mark command
58570
 
+ *
58571
 
+ * Syntax:
58572
 
+ *   mark
58573
 
+ */
58574
 
+
58575
 
+static const struct sieve_command cmd_mark = {
58576
 
+    "mark",
58577
 
+    SCT_COMMAND,
58578
 
+    0, 0, FALSE, FALSE,
58579
 
+    NULL, NULL,
58580
 
+    cmd_mark_validate,
58581
 
+    NULL, NULL,
58582
 
+};
58583
 
+
58584
 
+/* Unmark command
58585
 
+ *
58586
 
+ * Syntax:
58587
 
+ *   unmark
58588
 
+ */
58589
 
+static const struct sieve_command cmd_unmark = {
58590
 
+    "unmark",
58591
 
+    SCT_COMMAND,
58592
 
+    0, 0, FALSE, FALSE,
58593
 
+    NULL, NULL,
58594
 
+    cmd_mark_validate,
58595
 
+    NULL, NULL,
58596
 
+};
58597
 
+
58598
 
+/* 
58599
 
+ * Extension
58600
 
+ */
58601
 
+
58602
 
+static bool ext_imapflags_load(void);
58603
 
+static bool ext_imapflags_validator_load(struct sieve_validator *valdtr);
58604
 
+static bool ext_imapflags_interpreter_load
58605
 
+       (const struct sieve_runtime_env *renv, sieve_size_t *address);
58606
 
+
58607
 
+int ext_imapflags_my_id = -1;
58608
 
+
58609
 
+const struct sieve_extension imapflags_extension = { 
58610
 
+       "imapflags", 
58611
 
+       &ext_imapflags_my_id,
58612
 
+       ext_imapflags_load, 
58613
 
+       NULL,
58614
 
+       ext_imapflags_validator_load, 
58615
 
+       NULL,
58616
 
+       ext_imapflags_interpreter_load, 
58617
 
+       NULL, NULL, NULL,
58618
 
+       SIEVE_EXT_DEFINE_NO_OPERATIONS, 
58619
 
+       SIEVE_EXT_DEFINE_NO_OPERANDS
58620
 
+};
58621
 
+
58622
 
+static bool ext_imapflags_load(void)
58623
 
+{
58624
 
+       /* Make sure real extension is registered, it is needed by the binary */
58625
 
+       (void)sieve_extension_require(&imap4flags_extension);
58626
 
+
58627
 
+       return TRUE;
58628
 
+}
58629
 
+
58630
 
+/*
58631
 
+ * Validator
58632
 
+ */
58633
 
+
58634
 
+static bool ext_imapflags_validator_extension_validate
58635
 
+       (struct sieve_validator *valdtr, void *context, struct sieve_ast_argument *require_arg);
58636
 
+
58637
 
+const struct sieve_validator_extension imapflags_validator_extension = {
58638
 
+       &imapflags_extension,
58639
 
+       ext_imapflags_validator_extension_validate,
58640
 
+       NULL
58641
 
+};
58642
 
+
58643
 
+static bool ext_imapflags_validator_load
58644
 
+(struct sieve_validator *valdtr)
58645
 
+{
58646
 
+       sieve_validator_extension_register
58647
 
+           (valdtr, &imapflags_validator_extension, NULL);
58648
 
+
58649
 
+       /* Register commands */
58650
 
+       sieve_validator_register_command(valdtr, &cmd_setflag);
58651
 
+       sieve_validator_register_command(valdtr, &cmd_addflag);
58652
 
+       sieve_validator_register_command(valdtr, &cmd_removeflag);
58653
 
+
58654
 
+       sieve_validator_register_command(valdtr, &cmd_mark);
58655
 
+       sieve_validator_register_command(valdtr, &cmd_unmark);  
58656
 
+       
58657
 
+       return TRUE;
58658
 
+}
58659
 
+
58660
 
+static bool ext_imapflags_validator_extension_validate
58661
 
+(struct sieve_validator *valdtr, void *context ATTR_UNUSED, 
58662
 
+       struct sieve_ast_argument *require_arg)
58663
 
+{
58664
 
+       if ( sieve_validator_extension_loaded(valdtr, &imap4flags_extension) ) {
58665
 
+               sieve_argument_validate_error(valdtr, require_arg,
58666
 
+                       "the (deprecated) imapflags extension cannot be used "
58667
 
+                       "together with the imap4flags extension");
58668
 
+               return FALSE;
58669
 
+       }
58670
 
+
58671
 
+       return TRUE;
58672
 
+}
58673
 
+
58674
 
+/*
58675
 
+ * Interpreter
58676
 
+ */
58677
 
+
58678
 
+static bool ext_imapflags_interpreter_load
58679
 
+(const struct sieve_runtime_env *renv, sieve_size_t *address ATTR_UNUSED)
58680
 
+{
58681
 
+    sieve_interpreter_extension_register
58682
 
+        (renv->interp, &imap4flags_interpreter_extension, NULL);
58683
 
+
58684
 
+    return TRUE;
58685
 
+}
58686
 
+
58687
 
+/*
58688
 
+ * Command validation
58689
 
+ */ 
58690
 
+
58691
 
+static bool cmd_mark_validate
58692
 
+(struct sieve_validator *valdtr, struct sieve_command_context *cmd)
58693
 
+{
58694
 
+       if ( cmd->command == &cmd_mark )
58695
 
+               cmd->command = &cmd_addflag;
58696
 
+       else
58697
 
+               cmd->command = &cmd_removeflag;
58698
 
+
58699
 
+       cmd->first_positional = sieve_ast_argument_cstring_create
58700
 
+               (cmd->ast_node, "\\flagged", cmd->ast_node->source_line);
58701
 
+
58702
 
+       if ( !sieve_validator_argument_activate(valdtr, cmd, cmd->first_positional, FALSE) )
58703
 
+        return FALSE;  
58704
 
+               
58705
 
+       return TRUE;
58706
 
+}
58707
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/imap4flags/Makefile.am dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/imap4flags/Makefile.am
58708
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/imap4flags/Makefile.am 1970-01-01 01:00:00.000000000 +0100
58709
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/imap4flags/Makefile.am  2009-02-04 20:43:56.000000000 +0100
58710
 
@@ -0,0 +1,30 @@
58711
 
+noinst_LTLIBRARIES = libsieve_ext_imap4flags.la
58712
 
+
58713
 
+AM_CPPFLAGS = \
58714
 
+       -I../../ \
58715
 
+    -I../variables \
58716
 
+       -I$(dovecot_incdir) \
58717
 
+       -I$(dovecot_incdir)/src/lib \
58718
 
+       -I$(dovecot_incdir)/src/lib-mail \
58719
 
+       -I$(dovecot_incdir)/src/lib-storage 
58720
 
+
58721
 
+commands = \
58722
 
+       cmd-flag.c
58723
 
+
58724
 
+tests = \
58725
 
+       tst-hasflag.c
58726
 
+
58727
 
+tags = \
58728
 
+       tag-flags.c
58729
 
+
58730
 
+libsieve_ext_imap4flags_la_SOURCES = \
58731
 
+       ext-imap4flags-common.c \
58732
 
+       $(commands) \
58733
 
+       $(tests) \
58734
 
+       $(tags) \
58735
 
+       ext-imap4flags.c \
58736
 
+       ext-imapflags.c
58737
 
+       
58738
 
+
58739
 
+noinst_HEADERS = \
58740
 
+       ext-imap4flags-common.h
58741
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/imap4flags/Makefile.in dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/imap4flags/Makefile.in
58742
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/imap4flags/Makefile.in 1970-01-01 01:00:00.000000000 +0100
58743
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/imap4flags/Makefile.in  2009-08-21 00:55:43.000000000 +0200
58744
 
@@ -0,0 +1,485 @@
58745
 
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
58746
 
+# @configure_input@
58747
 
+
58748
 
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
58749
 
+# 2003, 2004, 2005, 2006, 2007, 2008  Free Software Foundation, Inc.
58750
 
+# This Makefile.in is free software; the Free Software Foundation
58751
 
+# gives unlimited permission to copy and/or distribute it,
58752
 
+# with or without modifications, as long as this notice is preserved.
58753
 
+
58754
 
+# This program is distributed in the hope that it will be useful,
58755
 
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
58756
 
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
58757
 
+# PARTICULAR PURPOSE.
58758
 
+
58759
 
+@SET_MAKE@
58760
 
+
58761
 
+
58762
 
+VPATH = @srcdir@
58763
 
+pkgdatadir = $(datadir)/@PACKAGE@
58764
 
+pkglibdir = $(libdir)/@PACKAGE@
58765
 
+pkgincludedir = $(includedir)/@PACKAGE@
58766
 
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
58767
 
+install_sh_DATA = $(install_sh) -c -m 644
58768
 
+install_sh_PROGRAM = $(install_sh) -c
58769
 
+install_sh_SCRIPT = $(install_sh) -c
58770
 
+INSTALL_HEADER = $(INSTALL_DATA)
58771
 
+transform = $(program_transform_name)
58772
 
+NORMAL_INSTALL = :
58773
 
+PRE_INSTALL = :
58774
 
+POST_INSTALL = :
58775
 
+NORMAL_UNINSTALL = :
58776
 
+PRE_UNINSTALL = :
58777
 
+POST_UNINSTALL = :
58778
 
+build_triplet = @build@
58779
 
+host_triplet = @host@
58780
 
+subdir = src/lib-sieve/plugins/imap4flags
58781
 
+DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
58782
 
+       $(srcdir)/Makefile.in
58783
 
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
58784
 
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
58785
 
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
58786
 
+       $(ACLOCAL_M4)
58787
 
+mkinstalldirs = $(install_sh) -d
58788
 
+CONFIG_HEADER = $(top_builddir)/dummy-config.h \
58789
 
+       $(top_builddir)/dsieve-config.h
58790
 
+CONFIG_CLEAN_FILES =
58791
 
+LTLIBRARIES = $(noinst_LTLIBRARIES)
58792
 
+libsieve_ext_imap4flags_la_LIBADD =
58793
 
+am__objects_1 = cmd-flag.lo
58794
 
+am__objects_2 = tst-hasflag.lo
58795
 
+am__objects_3 = tag-flags.lo
58796
 
+am_libsieve_ext_imap4flags_la_OBJECTS = ext-imap4flags-common.lo \
58797
 
+       $(am__objects_1) $(am__objects_2) $(am__objects_3) \
58798
 
+       ext-imap4flags.lo ext-imapflags.lo
58799
 
+libsieve_ext_imap4flags_la_OBJECTS =  \
58800
 
+       $(am_libsieve_ext_imap4flags_la_OBJECTS)
58801
 
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
58802
 
+depcomp = $(SHELL) $(top_srcdir)/depcomp
58803
 
+am__depfiles_maybe = depfiles
58804
 
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
58805
 
+       $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
58806
 
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
58807
 
+       --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
58808
 
+       $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
58809
 
+CCLD = $(CC)
58810
 
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
58811
 
+       --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
58812
 
+       $(LDFLAGS) -o $@
58813
 
+SOURCES = $(libsieve_ext_imap4flags_la_SOURCES)
58814
 
+DIST_SOURCES = $(libsieve_ext_imap4flags_la_SOURCES)
58815
 
+HEADERS = $(noinst_HEADERS)
58816
 
+ETAGS = etags
58817
 
+CTAGS = ctags
58818
 
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
58819
 
+ACLOCAL = @ACLOCAL@
58820
 
+AMTAR = @AMTAR@
58821
 
+AR = @AR@
58822
 
+AUTOCONF = @AUTOCONF@
58823
 
+AUTOHEADER = @AUTOHEADER@
58824
 
+AUTOMAKE = @AUTOMAKE@
58825
 
+AWK = @AWK@
58826
 
+CC = @CC@
58827
 
+CCDEPMODE = @CCDEPMODE@
58828
 
+CFLAGS = @CFLAGS@
58829
 
+CPP = @CPP@
58830
 
+CPPFLAGS = @CPPFLAGS@
58831
 
+CYGPATH_W = @CYGPATH_W@
58832
 
+DEFS = @DEFS@
58833
 
+DEPDIR = @DEPDIR@
58834
 
+DSYMUTIL = @DSYMUTIL@
58835
 
+DUMPBIN = @DUMPBIN@
58836
 
+ECHO_C = @ECHO_C@
58837
 
+ECHO_N = @ECHO_N@
58838
 
+ECHO_T = @ECHO_T@
58839
 
+EGREP = @EGREP@
58840
 
+EXEEXT = @EXEEXT@
58841
 
+FGREP = @FGREP@
58842
 
+GREP = @GREP@
58843
 
+INSTALL = @INSTALL@
58844
 
+INSTALL_DATA = @INSTALL_DATA@
58845
 
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
58846
 
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
58847
 
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
58848
 
+LD = @LD@
58849
 
+LDFLAGS = @LDFLAGS@
58850
 
+LIBICONV = @LIBICONV@
58851
 
+LIBOBJS = @LIBOBJS@
58852
 
+LIBS = @LIBS@
58853
 
+LIBTOOL = @LIBTOOL@
58854
 
+LIPO = @LIPO@
58855
 
+LN_S = @LN_S@
58856
 
+LTLIBOBJS = @LTLIBOBJS@
58857
 
+MAINT = @MAINT@
58858
 
+MAKEINFO = @MAKEINFO@
58859
 
+MKDIR_P = @MKDIR_P@
58860
 
+MODULE_LIBS = @MODULE_LIBS@
58861
 
+NM = @NM@
58862
 
+NMEDIT = @NMEDIT@
58863
 
+OBJDUMP = @OBJDUMP@
58864
 
+OBJEXT = @OBJEXT@
58865
 
+OTOOL = @OTOOL@
58866
 
+OTOOL64 = @OTOOL64@
58867
 
+PACKAGE = @PACKAGE@
58868
 
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
58869
 
+PACKAGE_NAME = @PACKAGE_NAME@
58870
 
+PACKAGE_STRING = @PACKAGE_STRING@
58871
 
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
58872
 
+PACKAGE_URL = @PACKAGE_URL@
58873
 
+PACKAGE_VERSION = @PACKAGE_VERSION@
58874
 
+PATH_SEPARATOR = @PATH_SEPARATOR@
58875
 
+RAND_LIBS = @RAND_LIBS@
58876
 
+RANLIB = @RANLIB@
58877
 
+SED = @SED@
58878
 
+SET_MAKE = @SET_MAKE@
58879
 
+SHELL = @SHELL@
58880
 
+STORAGE_LIBS = @STORAGE_LIBS@
58881
 
+STRIP = @STRIP@
58882
 
+VERSION = @VERSION@
58883
 
+abs_builddir = @abs_builddir@
58884
 
+abs_srcdir = @abs_srcdir@
58885
 
+abs_top_builddir = @abs_top_builddir@
58886
 
+abs_top_srcdir = @abs_top_srcdir@
58887
 
+ac_ct_CC = @ac_ct_CC@
58888
 
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
58889
 
+am__include = @am__include@
58890
 
+am__leading_dot = @am__leading_dot@
58891
 
+am__quote = @am__quote@
58892
 
+am__tar = @am__tar@
58893
 
+am__untar = @am__untar@
58894
 
+bindir = @bindir@
58895
 
+build = @build@
58896
 
+build_alias = @build_alias@
58897
 
+build_cpu = @build_cpu@
58898
 
+build_os = @build_os@
58899
 
+build_vendor = @build_vendor@
58900
 
+builddir = @builddir@
58901
 
+datadir = @datadir@
58902
 
+datarootdir = @datarootdir@
58903
 
+docdir = @docdir@
58904
 
+dovecot_incdir = @dovecot_incdir@
58905
 
+dovecotdir = @dovecotdir@
58906
 
+dvidir = @dvidir@
58907
 
+exec_prefix = @exec_prefix@
58908
 
+host = @host@
58909
 
+host_alias = @host_alias@
58910
 
+host_cpu = @host_cpu@
58911
 
+host_os = @host_os@
58912
 
+host_vendor = @host_vendor@
58913
 
+htmldir = @htmldir@
58914
 
+includedir = @includedir@
58915
 
+infodir = @infodir@
58916
 
+install_sh = @install_sh@
58917
 
+libdir = @libdir@
58918
 
+libexecdir = @libexecdir@
58919
 
+localedir = @localedir@
58920
 
+localstatedir = @localstatedir@
58921
 
+lt_ECHO = @lt_ECHO@
58922
 
+mandir = @mandir@
58923
 
+mkdir_p = @mkdir_p@
58924
 
+moduledir = @moduledir@
58925
 
+oldincludedir = @oldincludedir@
58926
 
+pdfdir = @pdfdir@
58927
 
+prefix = @prefix@
58928
 
+program_transform_name = @program_transform_name@
58929
 
+psdir = @psdir@
58930
 
+sbindir = @sbindir@
58931
 
+sharedstatedir = @sharedstatedir@
58932
 
+srcdir = @srcdir@
58933
 
+sysconfdir = @sysconfdir@
58934
 
+target_alias = @target_alias@
58935
 
+top_build_prefix = @top_build_prefix@
58936
 
+top_builddir = @top_builddir@
58937
 
+top_srcdir = @top_srcdir@
58938
 
+noinst_LTLIBRARIES = libsieve_ext_imap4flags.la
58939
 
+AM_CPPFLAGS = \
58940
 
+       -I../../ \
58941
 
+    -I../variables \
58942
 
+       -I$(dovecot_incdir) \
58943
 
+       -I$(dovecot_incdir)/src/lib \
58944
 
+       -I$(dovecot_incdir)/src/lib-mail \
58945
 
+       -I$(dovecot_incdir)/src/lib-storage 
58946
 
+
58947
 
+commands = \
58948
 
+       cmd-flag.c
58949
 
+
58950
 
+tests = \
58951
 
+       tst-hasflag.c
58952
 
+
58953
 
+tags = \
58954
 
+       tag-flags.c
58955
 
+
58956
 
+libsieve_ext_imap4flags_la_SOURCES = \
58957
 
+       ext-imap4flags-common.c \
58958
 
+       $(commands) \
58959
 
+       $(tests) \
58960
 
+       $(tags) \
58961
 
+       ext-imap4flags.c \
58962
 
+       ext-imapflags.c
58963
 
+
58964
 
+noinst_HEADERS = \
58965
 
+       ext-imap4flags-common.h
58966
 
+
58967
 
+all: all-am
58968
 
+
58969
 
+.SUFFIXES:
58970
 
+.SUFFIXES: .c .lo .o .obj
58971
 
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
58972
 
+       @for dep in $?; do \
58973
 
+         case '$(am__configure_deps)' in \
58974
 
+           *$$dep*) \
58975
 
+             ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
58976
 
+               && { if test -f $@; then exit 0; else break; fi; }; \
58977
 
+             exit 1;; \
58978
 
+         esac; \
58979
 
+       done; \
58980
 
+       echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign  src/lib-sieve/plugins/imap4flags/Makefile'; \
58981
 
+       cd $(top_srcdir) && \
58982
 
+         $(AUTOMAKE) --foreign  src/lib-sieve/plugins/imap4flags/Makefile
58983
 
+.PRECIOUS: Makefile
58984
 
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
58985
 
+       @case '$?' in \
58986
 
+         *config.status*) \
58987
 
+           cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
58988
 
+         *) \
58989
 
+           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
58990
 
+           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
58991
 
+       esac;
58992
 
+
58993
 
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
58994
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
58995
 
+
58996
 
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
58997
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
58998
 
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
58999
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
59000
 
+
59001
 
+clean-noinstLTLIBRARIES:
59002
 
+       -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
59003
 
+       @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
59004
 
+         dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
59005
 
+         test "$$dir" != "$$p" || dir=.; \
59006
 
+         echo "rm -f \"$${dir}/so_locations\""; \
59007
 
+         rm -f "$${dir}/so_locations"; \
59008
 
+       done
59009
 
+libsieve_ext_imap4flags.la: $(libsieve_ext_imap4flags_la_OBJECTS) $(libsieve_ext_imap4flags_la_DEPENDENCIES) 
59010
 
+       $(LINK)  $(libsieve_ext_imap4flags_la_OBJECTS) $(libsieve_ext_imap4flags_la_LIBADD) $(LIBS)
59011
 
+
59012
 
+mostlyclean-compile:
59013
 
+       -rm -f *.$(OBJEXT)
59014
 
+
59015
 
+distclean-compile:
59016
 
+       -rm -f *.tab.c
59017
 
+
59018
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd-flag.Plo@am__quote@
59019
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-imap4flags-common.Plo@am__quote@
59020
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-imap4flags.Plo@am__quote@
59021
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-imapflags.Plo@am__quote@
59022
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tag-flags.Plo@am__quote@
59023
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tst-hasflag.Plo@am__quote@
59024
 
+
59025
 
+.c.o:
59026
 
+@am__fastdepCC_TRUE@   $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
59027
 
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
59028
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
59029
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
59030
 
+@am__fastdepCC_FALSE@  $(COMPILE) -c $<
59031
 
+
59032
 
+.c.obj:
59033
 
+@am__fastdepCC_TRUE@   $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
59034
 
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
59035
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
59036
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
59037
 
+@am__fastdepCC_FALSE@  $(COMPILE) -c `$(CYGPATH_W) '$<'`
59038
 
+
59039
 
+.c.lo:
59040
 
+@am__fastdepCC_TRUE@   $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
59041
 
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
59042
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
59043
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
59044
 
+@am__fastdepCC_FALSE@  $(LTCOMPILE) -c -o $@ $<
59045
 
+
59046
 
+mostlyclean-libtool:
59047
 
+       -rm -f *.lo
59048
 
+
59049
 
+clean-libtool:
59050
 
+       -rm -rf .libs _libs
59051
 
+
59052
 
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
59053
 
+       list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
59054
 
+       unique=`for i in $$list; do \
59055
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
59056
 
+         done | \
59057
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
59058
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
59059
 
+       mkid -fID $$unique
59060
 
+tags: TAGS
59061
 
+
59062
 
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
59063
 
+               $(TAGS_FILES) $(LISP)
59064
 
+       tags=; \
59065
 
+       here=`pwd`; \
59066
 
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
59067
 
+       unique=`for i in $$list; do \
59068
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
59069
 
+         done | \
59070
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
59071
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
59072
 
+       if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
59073
 
+         test -n "$$unique" || unique=$$empty_fix; \
59074
 
+         $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
59075
 
+           $$tags $$unique; \
59076
 
+       fi
59077
 
+ctags: CTAGS
59078
 
+CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
59079
 
+               $(TAGS_FILES) $(LISP)
59080
 
+       tags=; \
59081
 
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
59082
 
+       unique=`for i in $$list; do \
59083
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
59084
 
+         done | \
59085
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
59086
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
59087
 
+       test -z "$(CTAGS_ARGS)$$tags$$unique" \
59088
 
+         || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
59089
 
+            $$tags $$unique
59090
 
+
59091
 
+GTAGS:
59092
 
+       here=`$(am__cd) $(top_builddir) && pwd` \
59093
 
+         && cd $(top_srcdir) \
59094
 
+         && gtags -i $(GTAGS_ARGS) $$here
59095
 
+
59096
 
+distclean-tags:
59097
 
+       -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
59098
 
+
59099
 
+distdir: $(DISTFILES)
59100
 
+       @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
59101
 
+       topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
59102
 
+       list='$(DISTFILES)'; \
59103
 
+         dist_files=`for file in $$list; do echo $$file; done | \
59104
 
+         sed -e "s|^$$srcdirstrip/||;t" \
59105
 
+             -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
59106
 
+       case $$dist_files in \
59107
 
+         */*) $(MKDIR_P) `echo "$$dist_files" | \
59108
 
+                          sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
59109
 
+                          sort -u` ;; \
59110
 
+       esac; \
59111
 
+       for file in $$dist_files; do \
59112
 
+         if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
59113
 
+         if test -d $$d/$$file; then \
59114
 
+           dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
59115
 
+           if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
59116
 
+             cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
59117
 
+           fi; \
59118
 
+           cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
59119
 
+         else \
59120
 
+           test -f $(distdir)/$$file \
59121
 
+           || cp -p $$d/$$file $(distdir)/$$file \
59122
 
+           || exit 1; \
59123
 
+         fi; \
59124
 
+       done
59125
 
+check-am: all-am
59126
 
+check: check-am
59127
 
+all-am: Makefile $(LTLIBRARIES) $(HEADERS)
59128
 
+installdirs:
59129
 
+install: install-am
59130
 
+install-exec: install-exec-am
59131
 
+install-data: install-data-am
59132
 
+uninstall: uninstall-am
59133
 
+
59134
 
+install-am: all-am
59135
 
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
59136
 
+
59137
 
+installcheck: installcheck-am
59138
 
+install-strip:
59139
 
+       $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
59140
 
+         install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
59141
 
+         `test -z '$(STRIP)' || \
59142
 
+           echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
59143
 
+mostlyclean-generic:
59144
 
+
59145
 
+clean-generic:
59146
 
+
59147
 
+distclean-generic:
59148
 
+       -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
59149
 
+
59150
 
+maintainer-clean-generic:
59151
 
+       @echo "This command is intended for maintainers to use"
59152
 
+       @echo "it deletes files that may require special tools to rebuild."
59153
 
+clean: clean-am
59154
 
+
59155
 
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
59156
 
+       mostlyclean-am
59157
 
+
59158
 
+distclean: distclean-am
59159
 
+       -rm -rf ./$(DEPDIR)
59160
 
+       -rm -f Makefile
59161
 
+distclean-am: clean-am distclean-compile distclean-generic \
59162
 
+       distclean-tags
59163
 
+
59164
 
+dvi: dvi-am
59165
 
+
59166
 
+dvi-am:
59167
 
+
59168
 
+html: html-am
59169
 
+
59170
 
+info: info-am
59171
 
+
59172
 
+info-am:
59173
 
+
59174
 
+install-data-am:
59175
 
+
59176
 
+install-dvi: install-dvi-am
59177
 
+
59178
 
+install-exec-am:
59179
 
+
59180
 
+install-html: install-html-am
59181
 
+
59182
 
+install-info: install-info-am
59183
 
+
59184
 
+install-man:
59185
 
+
59186
 
+install-pdf: install-pdf-am
59187
 
+
59188
 
+install-ps: install-ps-am
59189
 
+
59190
 
+installcheck-am:
59191
 
+
59192
 
+maintainer-clean: maintainer-clean-am
59193
 
+       -rm -rf ./$(DEPDIR)
59194
 
+       -rm -f Makefile
59195
 
+maintainer-clean-am: distclean-am maintainer-clean-generic
59196
 
+
59197
 
+mostlyclean: mostlyclean-am
59198
 
+
59199
 
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
59200
 
+       mostlyclean-libtool
59201
 
+
59202
 
+pdf: pdf-am
59203
 
+
59204
 
+pdf-am:
59205
 
+
59206
 
+ps: ps-am
59207
 
+
59208
 
+ps-am:
59209
 
+
59210
 
+uninstall-am:
59211
 
+
59212
 
+.MAKE: install-am install-strip
59213
 
+
59214
 
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
59215
 
+       clean-libtool clean-noinstLTLIBRARIES ctags distclean \
59216
 
+       distclean-compile distclean-generic distclean-libtool \
59217
 
+       distclean-tags distdir dvi dvi-am html html-am info info-am \
59218
 
+       install install-am install-data install-data-am install-dvi \
59219
 
+       install-dvi-am install-exec install-exec-am install-html \
59220
 
+       install-html-am install-info install-info-am install-man \
59221
 
+       install-pdf install-pdf-am install-ps install-ps-am \
59222
 
+       install-strip installcheck installcheck-am installdirs \
59223
 
+       maintainer-clean maintainer-clean-generic mostlyclean \
59224
 
+       mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
59225
 
+       pdf pdf-am ps ps-am tags uninstall uninstall-am
59226
 
+
59227
 
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
59228
 
+# Otherwise a system limit (for SysV at least) may be exceeded.
59229
 
+.NOEXPORT:
59230
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/imap4flags/tag-flags.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/imap4flags/tag-flags.c
59231
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/imap4flags/tag-flags.c 1970-01-01 01:00:00.000000000 +0100
59232
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/imap4flags/tag-flags.c  2009-08-05 11:50:22.000000000 +0200
59233
 
@@ -0,0 +1,426 @@
59234
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
59235
 
+ */
59236
 
+
59237
 
+#include "lib.h"
59238
 
+#include "str-sanitize.h"
59239
 
+#include "array.h"
59240
 
+#include "mail-storage.h"
59241
 
+
59242
 
+#include "sieve-code.h"
59243
 
+#include "sieve-extensions.h"
59244
 
+#include "sieve-commands.h"
59245
 
+#include "sieve-result.h"
59246
 
+#include "sieve-validator.h" 
59247
 
+#include "sieve-generator.h"
59248
 
+#include "sieve-interpreter.h"
59249
 
+#include "sieve-actions.h"
59250
 
+#include "sieve-dump.h"
59251
 
+
59252
 
+#include "ext-imap4flags-common.h"
59253
 
+
59254
 
+#include <ctype.h>
59255
 
+
59256
 
+/* 
59257
 
+ * Flags tagged argument
59258
 
+ */
59259
 
+
59260
 
+static bool tag_flags_validate
59261
 
+       (struct sieve_validator *validator,     struct sieve_ast_argument **arg, 
59262
 
+               struct sieve_command_context *cmd);
59263
 
+static bool tag_flags_validate_persistent
59264
 
+       (struct sieve_validator *validator, struct sieve_command_context *cmd);
59265
 
+static bool tag_flags_generate
59266
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg,
59267
 
+               struct sieve_command_context *cmd);
59268
 
+
59269
 
+const struct sieve_argument tag_flags = { 
59270
 
+       "flags", 
59271
 
+       NULL, NULL,
59272
 
+       tag_flags_validate, 
59273
 
+       NULL, 
59274
 
+       tag_flags_generate 
59275
 
+};
59276
 
+
59277
 
+const struct sieve_argument tag_flags_implicit = { 
59278
 
+       "flags-implicit", 
59279
 
+       NULL,
59280
 
+       tag_flags_validate_persistent, 
59281
 
+       NULL, NULL,
59282
 
+       tag_flags_generate
59283
 
+};
59284
 
+
59285
 
+/* 
59286
 
+ * Side effect 
59287
 
+ */
59288
 
+
59289
 
+static bool seff_flags_dump_context
59290
 
+       (const struct sieve_side_effect *seffect,
59291
 
+       const struct sieve_dumptime_env *denv, sieve_size_t *address);
59292
 
+static bool seff_flags_read_context
59293
 
+       (const struct sieve_side_effect *seffect, 
59294
 
+               const struct sieve_runtime_env *renv, sieve_size_t *address,
59295
 
+               void **se_context);
59296
 
+
59297
 
+static int seff_flags_merge
59298
 
+       (const struct sieve_runtime_env *renv, const struct sieve_action *action, 
59299
 
+               const struct sieve_side_effect *seffect, 
59300
 
+               void **old_context, void *new_context);
59301
 
+static void seff_flags_print
59302
 
+       (const struct sieve_side_effect *seffect, const struct sieve_action *action,
59303
 
+               const struct sieve_result_print_env *rpenv, void *se_context, bool *keep);
59304
 
+static bool seff_flags_pre_execute
59305
 
+       (const struct sieve_side_effect *seffect, const struct sieve_action *action, 
59306
 
+               const struct sieve_action_exec_env *aenv, 
59307
 
+               void **se_context, void *tr_context);
59308
 
+
59309
 
+const struct sieve_side_effect flags_side_effect = {
59310
 
+       SIEVE_OBJECT("flags", &flags_side_effect_operand, 0),
59311
 
+       &act_store,
59312
 
+
59313
 
+       seff_flags_dump_context,
59314
 
+       seff_flags_read_context,
59315
 
+       seff_flags_merge,
59316
 
+       seff_flags_print,
59317
 
+       seff_flags_pre_execute, 
59318
 
+       NULL, NULL, NULL
59319
 
+};
59320
 
+
59321
 
+/*
59322
 
+ * Operand
59323
 
+ */
59324
 
+
59325
 
+static const struct sieve_extension_objects ext_side_effects =
59326
 
+       SIEVE_EXT_DEFINE_SIDE_EFFECT(flags_side_effect);
59327
 
+
59328
 
+const struct sieve_operand flags_side_effect_operand = { 
59329
 
+       "flags operand", 
59330
 
+       &imap4flags_extension,
59331
 
+       0, 
59332
 
+       &sieve_side_effect_operand_class,
59333
 
+       &ext_side_effects
59334
 
+};
59335
 
+
59336
 
+/* 
59337
 
+ * Tag validation 
59338
 
+ */
59339
 
+
59340
 
+static bool tag_flags_validate_persistent
59341
 
+(struct sieve_validator *validator ATTR_UNUSED, struct sieve_command_context *cmd)
59342
 
+{
59343
 
+       if ( sieve_command_find_argument(cmd, &tag_flags) == NULL ) {
59344
 
+               sieve_command_add_dynamic_tag(cmd, &tag_flags_implicit, -1);
59345
 
+       }
59346
 
+       
59347
 
+       return TRUE;
59348
 
+}
59349
 
+
59350
 
+static bool tag_flags_validate
59351
 
+(struct sieve_validator *validator,    struct sieve_ast_argument **arg, 
59352
 
+       struct sieve_command_context *cmd)
59353
 
+{
59354
 
+       struct sieve_ast_argument *tag = *arg;
59355
 
+
59356
 
+       /* Detach the tag itself */
59357
 
+       *arg = sieve_ast_argument_next(*arg);
59358
 
+       
59359
 
+       /* Check syntax:
59360
 
+        *   :flags <list-of-flags: string-list>
59361
 
+        */
59362
 
+       if ( !sieve_validate_tag_parameter
59363
 
+               (validator, cmd, tag, *arg, SAAT_STRING_LIST) ) {
59364
 
+               return FALSE;
59365
 
+       }
59366
 
+       
59367
 
+       tag->parameters = *arg;
59368
 
+       
59369
 
+       /* Detach parameter */
59370
 
+       *arg = sieve_ast_arguments_detach(*arg,1);
59371
 
+
59372
 
+       return TRUE;
59373
 
+}
59374
 
+
59375
 
+/* 
59376
 
+ * Code generation 
59377
 
+ */
59378
 
+
59379
 
+static bool tag_flags_generate
59380
 
+(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg,
59381
 
+       struct sieve_command_context *cmd)
59382
 
+{
59383
 
+       struct sieve_ast_argument *param;
59384
 
+
59385
 
+       if ( sieve_ast_argument_type(arg) != SAAT_TAG ) {
59386
 
+               return FALSE;
59387
 
+       }
59388
 
+
59389
 
+       sieve_opr_side_effect_emit(cgenv->sbin, &flags_side_effect);
59390
 
+
59391
 
+       if ( arg->argument == &tag_flags ) {
59392
 
+               /* Explicit :flags tag */
59393
 
+               param = arg->parameters;
59394
 
+
59395
 
+               /* Call the generation function for the argument */ 
59396
 
+               if ( param->argument != NULL && param->argument->generate != NULL && 
59397
 
+                       !param->argument->generate(cgenv, param, cmd) ) 
59398
 
+                       return FALSE;
59399
 
+
59400
 
+       } else if ( arg->argument == &tag_flags_implicit ) {
59401
 
+               /* Implicit flags */
59402
 
+               sieve_opr_omitted_emit(cgenv->sbin);
59403
 
+       
59404
 
+       } else {
59405
 
+               /* Something else?! */
59406
 
+               i_unreached();
59407
 
+       }
59408
 
+       
59409
 
+       return TRUE;
59410
 
+}
59411
 
+
59412
 
+/* 
59413
 
+ * Side effect implementation
59414
 
+ */
59415
 
59416
 
+/* Context data */
59417
 
+
59418
 
+struct seff_flags_context {
59419
 
+       ARRAY_DEFINE(keywords, const char *);
59420
 
+       enum mail_flags flags;
59421
 
+};
59422
 
+
59423
 
+/* Context coding */
59424
 
+
59425
 
+static bool seff_flags_dump_context
59426
 
+(const struct sieve_side_effect *seffect ATTR_UNUSED, 
59427
 
+       const struct sieve_dumptime_env *denv, sieve_size_t *address)
59428
 
+{
59429
 
+    const struct sieve_operand *operand;
59430
 
+
59431
 
+    operand = sieve_operand_read(denv->sbin, address);
59432
 
+       if ( operand == NULL ) {
59433
 
+               sieve_code_dumpf(denv, "ERROR: INVALID OPERAND");
59434
 
+               return FALSE;
59435
 
+       }
59436
 
+
59437
 
+
59438
 
+    if ( sieve_operand_is_omitted(operand) ) {
59439
 
+               sieve_code_dumpf(denv, "flags: INTERNAL");
59440
 
+               return TRUE;
59441
 
+    }
59442
 
+
59443
 
+    return sieve_opr_stringlist_dump_data(denv, operand, address,
59444
 
+            "flags");
59445
 
+}
59446
 
+
59447
 
+static struct seff_flags_context *seff_flags_get_implicit_context
59448
 
+(struct sieve_result *result)
59449
 
+{
59450
 
+       pool_t pool = sieve_result_pool(result);
59451
 
+       struct seff_flags_context *ctx;
59452
 
+       const char *flag;
59453
 
+       struct ext_imap4flags_iter flit;
59454
 
+       
59455
 
+       ctx = p_new(pool, struct seff_flags_context, 1);
59456
 
+       p_array_init(&ctx->keywords, pool, 2);
59457
 
+       
59458
 
+       T_BEGIN {
59459
 
+               
59460
 
+               /* Unpack */
59461
 
+               ext_imap4flags_get_implicit_flags_init(&flit, result);
59462
 
+               while ( (flag=ext_imap4flags_iter_get_flag(&flit)) != NULL ) {          
59463
 
+                       if (flag != NULL && *flag != '\\') {
59464
 
+                               /* keyword */
59465
 
+                               const char *keyword = p_strdup(pool, flag);
59466
 
+                               array_append(&ctx->keywords, &keyword, 1);
59467
 
+                       } else {
59468
 
+                               /* system flag */
59469
 
+                               if (flag == NULL || strcasecmp(flag, "\\flagged") == 0)
59470
 
+                                       ctx->flags |= MAIL_FLAGGED;
59471
 
+                               else if (strcasecmp(flag, "\\answered") == 0)
59472
 
+                                       ctx->flags |= MAIL_ANSWERED;
59473
 
+                               else if (strcasecmp(flag, "\\deleted") == 0)
59474
 
+                                       ctx->flags |= MAIL_DELETED;
59475
 
+                               else if (strcasecmp(flag, "\\seen") == 0)
59476
 
+                                       ctx->flags |= MAIL_SEEN;
59477
 
+                               else if (strcasecmp(flag, "\\draft") == 0)
59478
 
+                                       ctx->flags |= MAIL_DRAFT;
59479
 
+                       }
59480
 
+               }
59481
 
+
59482
 
+       } T_END;
59483
 
+       
59484
 
+       return ctx;
59485
 
+}
59486
 
+
59487
 
+static bool _seff_flags_read_context
59488
 
+(const struct sieve_side_effect *seffect ATTR_UNUSED, 
59489
 
+       const struct sieve_runtime_env *renv, sieve_size_t *address,
59490
 
+       void **se_context)
59491
 
+{
59492
 
+       bool result = TRUE;
59493
 
+       sieve_size_t op_address = *address;
59494
 
+       const struct sieve_operand *operand;
59495
 
+       pool_t pool = sieve_result_pool(renv->result);
59496
 
+       struct seff_flags_context *ctx;
59497
 
+       string_t *flags_item;
59498
 
+       struct sieve_coded_stringlist *flag_list;
59499
 
+       
59500
 
+       ctx = p_new(pool, struct seff_flags_context, 1);
59501
 
+       p_array_init(&ctx->keywords, pool, 2);  
59502
 
+
59503
 
+       /* Check whether explicit flag list operand is present */
59504
 
+       operand = sieve_operand_read(renv->sbin, address);
59505
 
+
59506
 
+    if ( operand == NULL ) {
59507
 
+        sieve_runtime_trace_error(renv, "invalid operand");
59508
 
+        return FALSE;
59509
 
+    }
59510
 
+
59511
 
+    if ( sieve_operand_is_omitted(operand) ) {
59512
 
+               /* Flag list is omitted, use current value of internal 
59513
 
+                * variable to construct side effect context.
59514
 
+                */
59515
 
+               *se_context = seff_flags_get_implicit_context(renv->result);
59516
 
+               return TRUE;
59517
 
+       }
59518
 
+       
59519
 
+       /* Read flag-list */
59520
 
+       if ( (flag_list=sieve_opr_stringlist_read_data
59521
 
+               (renv, operand, op_address, address)) == NULL ) {
59522
 
+               return FALSE;
59523
 
+       }
59524
 
+       
59525
 
+       /* Unpack */
59526
 
+       flags_item = NULL;
59527
 
+       while ( (result=sieve_coded_stringlist_next_item(flag_list, &flags_item)) && 
59528
 
+               flags_item != NULL ) {
59529
 
+               const char *flag;
59530
 
+               struct ext_imap4flags_iter flit;
59531
 
+
59532
 
+               ext_imap4flags_iter_init(&flit, flags_item);
59533
 
+       
59534
 
+               while ( (flag=ext_imap4flags_iter_get_flag(&flit)) != NULL ) {          
59535
 
+                       if (flag != NULL && *flag != '\\') {
59536
 
+                               /* keyword */
59537
 
+                               const char *keyword = p_strdup(pool, flag);
59538
 
+
59539
 
+                               /* FIXME: should check for duplicates (cannot trust variables) */
59540
 
+                               array_append(&ctx->keywords, &keyword, 1);
59541
 
+
59542
 
+                       } else {
59543
 
+                               /* system flag */
59544
 
+                               if (flag == NULL || strcasecmp(flag, "\\flagged") == 0)
59545
 
+                                       ctx->flags |= MAIL_FLAGGED;
59546
 
+                               else if (strcasecmp(flag, "\\answered") == 0)
59547
 
+                                       ctx->flags |= MAIL_ANSWERED;
59548
 
+                               else if (strcasecmp(flag, "\\deleted") == 0)
59549
 
+                                       ctx->flags |= MAIL_DELETED;
59550
 
+                               else if (strcasecmp(flag, "\\seen") == 0)
59551
 
+                                       ctx->flags |= MAIL_SEEN;
59552
 
+                               else if (strcasecmp(flag, "\\draft") == 0)
59553
 
+                                       ctx->flags |= MAIL_DRAFT;
59554
 
+                       }
59555
 
+               }
59556
 
+       }
59557
 
+       
59558
 
+       *se_context = (void *) ctx;
59559
 
+       
59560
 
+       return result;
59561
 
+}
59562
 
+
59563
 
+static bool seff_flags_read_context
59564
 
+(const struct sieve_side_effect *seffect, 
59565
 
+       const struct sieve_runtime_env *renv, sieve_size_t *address,
59566
 
+       void **se_context)
59567
 
+{
59568
 
+       bool result;
59569
 
+       
59570
 
+       T_BEGIN {
59571
 
+               result = _seff_flags_read_context(seffect, renv, address, se_context);
59572
 
+       } T_END;
59573
 
+
59574
 
+       return result;
59575
 
+}
59576
 
+
59577
 
+
59578
 
+/* Result verification */
59579
 
+
59580
 
+static int seff_flags_merge
59581
 
+(const struct sieve_runtime_env *renv ATTR_UNUSED, 
59582
 
+       const struct sieve_action *action ATTR_UNUSED, 
59583
 
+       const struct sieve_side_effect *seffect ATTR_UNUSED, 
59584
 
+       void **old_context, void *new_context)
59585
 
+{
59586
 
+       *old_context = new_context;
59587
 
+       
59588
 
+       return 1;
59589
 
+}
59590
 
+
59591
 
+/* Result printing */
59592
 
+
59593
 
+static void seff_flags_print
59594
 
+(const struct sieve_side_effect *seffect ATTR_UNUSED, 
59595
 
+       const struct sieve_action *action ATTR_UNUSED, 
59596
 
+       const struct sieve_result_print_env *rpenv,
59597
 
+       void *se_context, bool *keep ATTR_UNUSED)
59598
 
+{
59599
 
+       struct sieve_result *result = rpenv->result;
59600
 
+       struct seff_flags_context *ctx = (struct seff_flags_context *) se_context;
59601
 
+       unsigned int i;
59602
 
+       
59603
 
+       if ( ctx == NULL )
59604
 
+               ctx = seff_flags_get_implicit_context(result);
59605
 
+       
59606
 
+       if ( ctx->flags != 0 || array_count(&ctx->keywords) > 0 ) {
59607
 
+               T_BEGIN {
59608
 
+                       string_t *flags = t_str_new(128);
59609
 
59610
 
+                       if ( (ctx->flags & MAIL_FLAGGED) > 0 )
59611
 
+                               str_printfa(flags, " \\flagged");
59612
 
+
59613
 
+                       if ( (ctx->flags & MAIL_ANSWERED) > 0 )
59614
 
+                               str_printfa(flags, " \\answered");
59615
 
+               
59616
 
+                       if ( (ctx->flags & MAIL_DELETED) > 0 )
59617
 
+                               str_printfa(flags, " \\deleted");
59618
 
+                                       
59619
 
+                       if ( (ctx->flags & MAIL_SEEN) > 0 )
59620
 
+                               str_printfa(flags, " \\seen");
59621
 
+                       
59622
 
+                       if ( (ctx->flags & MAIL_DRAFT) > 0 )
59623
 
+                               str_printfa(flags, " \\draft");
59624
 
+
59625
 
+                       for ( i = 0; i < array_count(&ctx->keywords); i++ ) {
59626
 
+                               const char *const *keyword = array_idx(&ctx->keywords, i);
59627
 
+                               str_printfa(flags, " %s", str_sanitize(*keyword, 64));
59628
 
+                       }
59629
 
+
59630
 
+                       sieve_result_seffect_printf(rpenv, "add IMAP flags:%s", str_c(flags));
59631
 
+               } T_END;
59632
 
+       }
59633
 
+}
59634
 
+
59635
 
+/* Result execution */
59636
 
+
59637
 
+static bool seff_flags_pre_execute
59638
 
+(const struct sieve_side_effect *seffect ATTR_UNUSED, 
59639
 
+       const struct sieve_action *action ATTR_UNUSED, 
59640
 
+       const struct sieve_action_exec_env *aenv, 
59641
 
+       void **se_context, void *tr_context)
59642
 
+{      
59643
 
+       struct seff_flags_context *ctx = (struct seff_flags_context *) *se_context;
59644
 
+       const char *const *keywords;
59645
 
+               
59646
 
+       if ( ctx == NULL ) {
59647
 
+               ctx = seff_flags_get_implicit_context(aenv->result);
59648
 
+               *se_context = (void *) ctx;
59649
 
+       }
59650
 
+               
59651
 
+       (void)array_append_space(&ctx->keywords);
59652
 
+       keywords = array_idx(&ctx->keywords, 0);
59653
 
+
59654
 
+       sieve_act_store_add_flags(aenv, tr_context, keywords, ctx->flags);
59655
 
+       
59656
 
+       return TRUE;
59657
 
+}
59658
 
+
59659
 
+
59660
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/imap4flags/tst-hasflag.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/imap4flags/tst-hasflag.c
59661
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/imap4flags/tst-hasflag.c       1970-01-01 01:00:00.000000000 +0100
59662
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/imap4flags/tst-hasflag.c        2009-07-30 00:44:14.000000000 +0200
59663
 
@@ -0,0 +1,300 @@
59664
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
59665
 
+ */
59666
 
59667
 
+#include "lib.h"
59668
 
+
59669
 
+#include "sieve-commands.h"
59670
 
+#include "sieve-code.h"
59671
 
+#include "sieve-comparators.h"
59672
 
+#include "sieve-match-types.h"
59673
 
+#include "sieve-validator.h" 
59674
 
+#include "sieve-generator.h"
59675
 
+#include "sieve-interpreter.h"
59676
 
+#include "sieve-dump.h"
59677
 
+#include "sieve-match.h"
59678
 
+
59679
 
+#include "ext-imap4flags-common.h"
59680
 
+
59681
 
+/*
59682
 
+ * Hasflag test
59683
 
+ *
59684
 
+ * Syntax: 
59685
 
+ *   hasflag [MATCH-TYPE] [COMPARATOR] [<variable-list: string-list>]
59686
 
+ *       <list-of-flags: string-list>
59687
 
+ */
59688
 
+
59689
 
+static bool tst_hasflag_registered
59690
 
+       (struct sieve_validator *validator,
59691
 
+               struct sieve_command_registration *cmd_reg);
59692
 
+static bool tst_hasflag_validate
59693
 
+       (struct sieve_validator *validator,     struct sieve_command_context *ctx);
59694
 
+static bool tst_hasflag_generate
59695
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx);
59696
 
59697
 
+const struct sieve_command tst_hasflag = { 
59698
 
+       "hasflag", 
59699
 
+       SCT_TEST,
59700
 
+       -1, /* We check positional arguments ourselves */
59701
 
+       0, FALSE, FALSE, 
59702
 
+       tst_hasflag_registered, 
59703
 
+       NULL,
59704
 
+       tst_hasflag_validate, 
59705
 
+       tst_hasflag_generate, 
59706
 
+       NULL 
59707
 
+};
59708
 
+
59709
 
+/* 
59710
 
+ * Hasflag operation 
59711
 
+ */
59712
 
+
59713
 
+static bool tst_hasflag_operation_dump
59714
 
+       (const struct sieve_operation *op,      
59715
 
+               const struct sieve_dumptime_env *denv, sieve_size_t *address);
59716
 
+static int tst_hasflag_operation_execute
59717
 
+       (const struct sieve_operation *op,      
59718
 
+               const struct sieve_runtime_env *renv, sieve_size_t *address);
59719
 
+
59720
 
+const struct sieve_operation hasflag_operation = { 
59721
 
+       "HASFLAG",
59722
 
+       &imap4flags_extension,
59723
 
+       ext_imap4flags_OPERATION_HASFLAG,
59724
 
+       tst_hasflag_operation_dump,
59725
 
+       tst_hasflag_operation_execute
59726
 
+};
59727
 
+
59728
 
+/* 
59729
 
+ * Optional arguments 
59730
 
+ */
59731
 
+
59732
 
+enum tst_hasflag_optional {    
59733
 
+       OPT_VARIABLES = SIEVE_MATCH_OPT_LAST,
59734
 
+};
59735
 
+
59736
 
+/* 
59737
 
+ * Tag registration 
59738
 
+ */
59739
 
+
59740
 
+static bool tst_hasflag_registered
59741
 
+(struct sieve_validator *validator, 
59742
 
+       struct sieve_command_registration *cmd_reg) 
59743
 
+{
59744
 
+       /* The order of these is not significant */
59745
 
+       sieve_comparators_link_tag(validator, cmd_reg, SIEVE_MATCH_OPT_COMPARATOR);
59746
 
+       sieve_match_types_link_tags(validator, cmd_reg, SIEVE_MATCH_OPT_MATCH_TYPE);
59747
 
+
59748
 
+       return TRUE;
59749
 
+}
59750
 
+
59751
 
+/* 
59752
 
+ * Validation 
59753
 
+ */
59754
 
+
59755
 
+static bool tst_hasflag_validate
59756
 
+(struct sieve_validator *validator,    struct sieve_command_context *tst)
59757
 
+{
59758
 
+       struct sieve_ast_argument *vars = tst->first_positional;
59759
 
+       struct sieve_ast_argument *keys = sieve_ast_argument_next(vars);
59760
 
+               
59761
 
+       if ( !ext_imap4flags_command_validate(validator, tst) )
59762
 
+               return FALSE;
59763
 
+       
59764
 
+       if ( keys == NULL ) {
59765
 
+               keys = vars;
59766
 
+               vars = NULL;
59767
 
+       } else {
59768
 
+               vars->arg_id_code = OPT_VARIABLES;
59769
 
+       }
59770
 
+       
59771
 
+       /* Validate the key argument to a specified match type */
59772
 
+       return sieve_match_type_validate
59773
 
+               (validator, tst, keys, &is_match_type, &i_ascii_casemap_comparator);
59774
 
+}
59775
 
+
59776
 
+/*
59777
 
+ * Code generation 
59778
 
+ */
59779
 
+
59780
 
+static bool tst_hasflag_generate
59781
 
+(const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx)
59782
 
+{
59783
 
+       sieve_operation_emit_code(cgenv->sbin, &hasflag_operation);
59784
 
+
59785
 
+       /* Generate arguments */
59786
 
+       if ( !sieve_generate_arguments(cgenv, ctx, NULL) )
59787
 
+               return FALSE;   
59788
 
+
59789
 
+       return TRUE;
59790
 
+}
59791
 
+
59792
 
+/* 
59793
 
+ * Code dump 
59794
 
+ */
59795
 
59796
 
+static bool tst_hasflag_operation_dump
59797
 
+(const struct sieve_operation *op ATTR_UNUSED, 
59798
 
+       const struct sieve_dumptime_env *denv, sieve_size_t *address)
59799
 
+{
59800
 
+       int opt_code = 0;
59801
 
+
59802
 
+       sieve_code_dumpf(denv, "HASFLAG");
59803
 
+       sieve_code_descend(denv);
59804
 
+
59805
 
+       /* Handle any optional arguments */
59806
 
+       do {
59807
 
+               if ( !sieve_match_dump_optional_operands(denv, address, &opt_code) )
59808
 
+                       return FALSE;
59809
 
+
59810
 
+               switch ( opt_code ) {
59811
 
+               case SIEVE_MATCH_OPT_END:
59812
 
+                       break;
59813
 
+               case OPT_VARIABLES:
59814
 
+                       sieve_opr_stringlist_dump(denv, address, "variables");
59815
 
+                       break;
59816
 
+               default:
59817
 
+                       return FALSE;
59818
 
+               }
59819
 
+       } while ( opt_code != SIEVE_MATCH_OPT_END );
59820
 
+                       
59821
 
+       return 
59822
 
+               sieve_opr_stringlist_dump(denv, address, "list of flags");
59823
 
+}
59824
 
+
59825
 
+/*
59826
 
+ * Interpretation
59827
 
+ */
59828
 
59829
 
+static int _flag_key_extract_init
59830
 
+(void **context, string_t *raw_key)
59831
 
+{
59832
 
+       struct ext_imap4flags_iter *iter = t_new(struct ext_imap4flags_iter, 1);
59833
 
+       
59834
 
+       ext_imap4flags_iter_init(iter, raw_key);
59835
 
+       
59836
 
+       *context = iter; 
59837
 
+       
59838
 
+       return TRUE;
59839
 
+}
59840
 
+
59841
 
+static int _flag_key_extract
59842
 
+(void *context, const char **key, size_t *size)
59843
 
+{
59844
 
+       struct ext_imap4flags_iter *iter = (struct ext_imap4flags_iter *) context;
59845
 
+       
59846
 
+       if ( (*key = ext_imap4flags_iter_get_flag(iter)) != NULL ) {
59847
 
+               *size = strlen(*key); 
59848
 
+               return TRUE;
59849
 
+       }
59850
 
+       
59851
 
+       return FALSE;
59852
 
+}
59853
 
+
59854
 
+static const struct sieve_match_key_extractor _flag_extractor = {
59855
 
+       _flag_key_extract_init,
59856
 
+       _flag_key_extract
59857
 
+};
59858
 
+
59859
 
+static int tst_hasflag_operation_execute
59860
 
+(const struct sieve_operation *op ATTR_UNUSED,
59861
 
+       const struct sieve_runtime_env *renv, sieve_size_t *address)
59862
 
+{
59863
 
+       int ret, mret;
59864
 
+       bool result = TRUE;
59865
 
+       int opt_code = 0;
59866
 
+       const struct sieve_comparator *cmp = &i_ascii_casemap_comparator;
59867
 
+       const struct sieve_match_type *mtch = &is_match_type;
59868
 
+       struct sieve_match_context *mctx;
59869
 
+       struct sieve_coded_stringlist *flag_list, *variables_list = NULL;
59870
 
+       struct ext_imap4flags_iter iter;
59871
 
+       const char *flag;
59872
 
+       bool matched;
59873
 
+       
59874
 
+       /*
59875
 
+        * Read operands
59876
 
+        */
59877
 
+
59878
 
+       /* Handle match-type and comparator operands */
59879
 
+       do {
59880
 
+               if ( (ret=sieve_match_read_optional_operands
59881
 
+                       (renv, address, &opt_code, &cmp, &mtch)) <= 0 )
59882
 
+                       return ret;
59883
 
+       
59884
 
+               /* Check whether we neatly finished the list of optional operands*/
59885
 
+               switch ( opt_code ) { 
59886
 
+               case SIEVE_MATCH_OPT_END:
59887
 
+                       break;
59888
 
+               case OPT_VARIABLES:
59889
 
+                       if ( (variables_list=sieve_opr_stringlist_read(renv, address)) == NULL ) {
59890
 
+                                       sieve_runtime_trace_error(renv, "invalid variables-list operand");
59891
 
+                               return SIEVE_EXEC_BIN_CORRUPT;
59892
 
+                       }
59893
 
+                       break;
59894
 
+               default:
59895
 
+                       sieve_runtime_trace_error(renv, "invalid optional operand");
59896
 
+                       return SIEVE_EXEC_BIN_CORRUPT;
59897
 
+               }
59898
 
+       } while ( opt_code != SIEVE_MATCH_OPT_END );
59899
 
+               
59900
 
+       /* Read flag list */
59901
 
+       if ( (flag_list=sieve_opr_stringlist_read(renv, address)) == NULL ) {
59902
 
+               sieve_runtime_trace_error(renv, "invalid flag-list operand");
59903
 
+               return SIEVE_EXEC_BIN_CORRUPT;
59904
 
+       }
59905
 
+
59906
 
+       /*
59907
 
+        * Perform operation
59908
 
+        */
59909
 
+
59910
 
+       sieve_runtime_trace(renv, "HASFLAG test");
59911
 
+
59912
 
+       matched = FALSE;
59913
 
+       mctx = sieve_match_begin
59914
 
+               (renv->interp, mtch, cmp, &_flag_extractor, flag_list);         
59915
 
+
59916
 
+       matched = FALSE;
59917
 
+
59918
 
+       if ( variables_list != NULL ) {
59919
 
+               string_t *var_item = NULL;
59920
 
+               
59921
 
+               /* Iterate through all requested variables to match */
59922
 
+               while ( result && !matched && 
59923
 
+                       (result=sieve_coded_stringlist_next_item(variables_list, &var_item)) 
59924
 
+                       && var_item != NULL ) {
59925
 
+               
59926
 
+                       ext_imap4flags_get_flags_init(&iter, renv, var_item);   
59927
 
+                       while ( !matched && (flag=ext_imap4flags_iter_get_flag(&iter)) != NULL ) {
59928
 
+                               if ( (mret=sieve_match_value(mctx, flag, strlen(flag))) < 0 ) {
59929
 
+                                       result = FALSE;
59930
 
+                                       break;
59931
 
+                               }
59932
 
+
59933
 
+                               matched = ( mret > 0 );         
59934
 
+                       }
59935
 
+               }
59936
 
+       } else {
59937
 
+               ext_imap4flags_get_flags_init(&iter, renv, NULL);       
59938
 
+               while ( !matched && (flag=ext_imap4flags_iter_get_flag(&iter)) != NULL ) {
59939
 
+                       if ( (mret=sieve_match_value(mctx, flag, strlen(flag))) < 0 ) {
59940
 
+                               result = FALSE;
59941
 
+                               break;
59942
 
+                       }
59943
 
+
59944
 
+                       matched = ( mret > 0 );         
59945
 
+               }
59946
 
+       }
59947
 
+
59948
 
+       if ( (mret=sieve_match_end(&mctx)) < 0 ) {
59949
 
+               result = FALSE;
59950
 
+       } else
59951
 
+               matched = ( mret > 0 || matched );      
59952
 
+       
59953
 
+       /* Assign test result */
59954
 
+       if ( result ) {
59955
 
+               sieve_interpreter_set_test_result(renv->interp, matched);
59956
 
+               return SIEVE_EXEC_OK;
59957
 
+       }
59958
 
+       
59959
 
+       sieve_runtime_trace_error(renv, "invalid string list item");
59960
 
+       return SIEVE_EXEC_BIN_CORRUPT;
59961
 
+}
59962
 
+
59963
 
+
59964
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/include/cmd-global.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/include/cmd-global.c
59965
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/include/cmd-global.c   1970-01-01 01:00:00.000000000 +0100
59966
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/include/cmd-global.c    2009-04-10 15:11:38.000000000 +0200
59967
 
@@ -0,0 +1,310 @@
59968
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
59969
 
+ */
59970
 
+
59971
 
+#include "lib.h"
59972
 
+
59973
 
+#include "sieve-common.h"
59974
 
+#include "sieve-code.h"
59975
 
+#include "sieve-commands.h"
59976
 
+#include "sieve-validator.h" 
59977
 
+#include "sieve-generator.h"
59978
 
+#include "sieve-binary.h"
59979
 
+#include "sieve-interpreter.h"
59980
 
+#include "sieve-dump.h"
59981
 
+
59982
 
+#include "sieve-ext-variables.h"
59983
 
+
59984
 
+#include "ext-include-common.h"
59985
 
+#include "ext-include-binary.h"
59986
 
+#include "ext-include-variables.h"
59987
 
+
59988
 
+/* 
59989
 
+ * Commands 
59990
 
+ */
59991
 
+
59992
 
+static bool cmd_global_validate
59993
 
+  (struct sieve_validator *validator, struct sieve_command_context *cmd);
59994
 
+static bool cmd_global_generate
59995
 
+(const struct sieve_codegen_env *cgenv, struct sieve_command_context *cmd);
59996
 
+
59997
 
+const struct sieve_command cmd_global = {
59998
 
+    "global",
59999
 
+    SCT_COMMAND,
60000
 
+    1, 0, FALSE, FALSE,
60001
 
+    NULL, NULL,
60002
 
+    cmd_global_validate,
60003
 
+    cmd_global_generate,
60004
 
+    NULL
60005
 
+};
60006
 
+
60007
 
+/* DEPRICATED:
60008
 
+ */
60009
 
+               
60010
 
+/* Import command 
60011
 
+ * 
60012
 
+ * Syntax
60013
 
+ *   import
60014
 
+ */    
60015
 
+const struct sieve_command cmd_import = { 
60016
 
+       "import", 
60017
 
+       SCT_COMMAND, 
60018
 
+       1, 0, FALSE, FALSE,
60019
 
+       NULL, NULL,
60020
 
+       cmd_global_validate, 
60021
 
+       cmd_global_generate, 
60022
 
+       NULL
60023
 
+};
60024
 
+
60025
 
+/* Export command 
60026
 
+ * 
60027
 
+ * Syntax
60028
 
+ *   export
60029
 
+ */    
60030
 
+const struct sieve_command cmd_export = { 
60031
 
+       "export", 
60032
 
+       SCT_COMMAND, 
60033
 
+       1, 0, FALSE, FALSE,
60034
 
+       NULL, NULL, 
60035
 
+       cmd_global_validate, 
60036
 
+       cmd_global_generate, 
60037
 
+       NULL
60038
 
+};
60039
 
+
60040
 
+/*
60041
 
+ * Operations
60042
 
+ */
60043
 
+
60044
 
+static bool opc_global_dump
60045
 
+       (const struct sieve_operation *op,      
60046
 
+               const struct sieve_dumptime_env *denv, sieve_size_t *address);
60047
 
+static int opc_global_execute
60048
 
+       (const struct sieve_operation *op, 
60049
 
+               const struct sieve_runtime_env *renv, sieve_size_t *address);
60050
 
+
60051
 
+/* Global operation */
60052
 
+
60053
 
+const struct sieve_operation global_operation = { 
60054
 
+       "global",
60055
 
+       &include_extension,
60056
 
+       EXT_INCLUDE_OPERATION_GLOBAL,
60057
 
+       opc_global_dump, 
60058
 
+       opc_global_execute
60059
 
+};
60060
 
+
60061
 
+/*
60062
 
+ * Validation
60063
 
+ */
60064
 
+
60065
 
+static bool cmd_global_validate
60066
 
+  (struct sieve_validator *validator, struct sieve_command_context *cmd) 
60067
 
+{
60068
 
+       struct sieve_ast_argument *arg = cmd->first_positional;
60069
 
+       struct sieve_command_context *prev_context = 
60070
 
+               sieve_command_prev_context(cmd);
60071
 
+
60072
 
+       /* Check valid command placement */
60073
 
+       if ( !sieve_command_is_toplevel(cmd) ||
60074
 
+               ( !sieve_command_is_first(cmd) && prev_context != NULL &&
60075
 
+                       prev_context->command != &cmd_require ) ) {
60076
 
+
60077
 
+               if ( cmd->command == &cmd_global ) {
60078
 
+                       if ( prev_context->command != &cmd_global ) {
60079
 
+                               sieve_command_validate_error(validator, cmd, 
60080
 
+                                       "a global command can only be placed at top level "
60081
 
+                                       "at the beginning of the file after any require or other global commands");
60082
 
+                               return FALSE;
60083
 
+                       }
60084
 
+               } else {
60085
 
+                       if ( prev_context->command != &cmd_import && prev_context->command != &cmd_export ) {
60086
 
+                sieve_command_validate_error(validator, cmd,
60087
 
+                    "the DEPRICATED %s command can only be placed at top level "
60088
 
+                    "at the beginning of the file after any require or import/export commands",
60089
 
+                                       cmd->command->identifier);
60090
 
+                return FALSE;
60091
 
+            }
60092
 
+               }
60093
 
+       }
60094
 
+
60095
 
+       /* Check for use of variables extension */      
60096
 
+       if ( !sieve_ext_variables_is_active(validator) ) {
60097
 
+               sieve_command_validate_error(validator, cmd, 
60098
 
+                       "%s command requires that variables extension is active",
60099
 
+                       cmd->command->identifier);
60100
 
+               return FALSE;
60101
 
+       }
60102
 
+               
60103
 
+       /* Register global variable */
60104
 
+       if ( sieve_ast_argument_type(arg) == SAAT_STRING ) {
60105
 
+               /* Single string */
60106
 
+               const char *identifier = sieve_ast_argument_strc(arg);
60107
 
+               struct sieve_variable *var;
60108
 
+               
60109
 
+               if ( (var=ext_include_variable_import_global
60110
 
+                       (validator, cmd, identifier)) == NULL )
60111
 
+                       return FALSE;
60112
 
+                       
60113
 
+               arg->context = (void *) var;
60114
 
+
60115
 
+       } else if ( sieve_ast_argument_type(arg) == SAAT_STRING_LIST ) {
60116
 
+               /* String list */
60117
 
+               struct sieve_ast_argument *stritem = sieve_ast_strlist_first(arg);
60118
 
+               
60119
 
+               while ( stritem != NULL ) {
60120
 
+                       const char *identifier = sieve_ast_argument_strc(stritem);
60121
 
+                       struct sieve_variable *var;
60122
 
+                       
60123
 
+                       if ( (var=ext_include_variable_import_global
60124
 
+                               (validator, cmd, identifier)) == NULL )
60125
 
+                               return FALSE;
60126
 
+
60127
 
+                       stritem->context = (void *) var;
60128
 
+       
60129
 
+                       stritem = sieve_ast_strlist_next(stritem);
60130
 
+               }
60131
 
+       } else {
60132
 
+               /* Something else */
60133
 
+               sieve_argument_validate_error(validator, arg, 
60134
 
+                       "the %s command accepts a single string or string list argument, "
60135
 
+                       "but %s was found", cmd->command->identifier,
60136
 
+                       sieve_ast_argument_name(arg));
60137
 
+               return FALSE;
60138
 
+       }
60139
 
+       
60140
 
+       /* Join global commands with predecessors if possible */
60141
 
+       if ( prev_context->command == cmd->command ) {
60142
 
+               /* Join this command's string list with the previous one */
60143
 
+               prev_context->first_positional = sieve_ast_stringlist_join
60144
 
+                       (prev_context->first_positional, cmd->first_positional);
60145
 
+               
60146
 
+               if ( prev_context->first_positional == NULL ) {
60147
 
+                       /* Not going to happen unless MAXINT stringlist items are specified */
60148
 
+                       sieve_command_validate_error(validator, cmd, 
60149
 
+                               "compiler reached AST limit (script too complex)");
60150
 
+                       return FALSE;
60151
 
+               }
60152
 
+
60153
 
+               /* Detach this command node */
60154
 
+               sieve_ast_node_detach(cmd->ast_node);
60155
 
+       }
60156
 
+               
60157
 
+       return TRUE;
60158
 
+}
60159
 
+
60160
 
+/*
60161
 
+ * Code generation
60162
 
+ */
60163
 
60164
 
+static bool cmd_global_generate
60165
 
+(const struct sieve_codegen_env *cgenv, struct sieve_command_context *cmd) 
60166
 
+{
60167
 
+       struct sieve_ast_argument *arg = cmd->first_positional;
60168
 
+
60169
 
+       sieve_operation_emit_code(cgenv->sbin, &global_operation);
60170
 
+                               
60171
 
+       if ( sieve_ast_argument_type(arg) == SAAT_STRING ) {
60172
 
+               /* Single string */
60173
 
+               struct sieve_variable *var = (struct sieve_variable *) arg->context;
60174
 
+               
60175
 
+               (void)sieve_binary_emit_unsigned(cgenv->sbin, 1);
60176
 
+               (void)sieve_binary_emit_unsigned(cgenv->sbin, var->index);
60177
 
+               
60178
 
+       } else if ( sieve_ast_argument_type(arg) == SAAT_STRING_LIST ) {
60179
 
+               /* String list */
60180
 
+               struct sieve_ast_argument *stritem = sieve_ast_strlist_first(arg);
60181
 
+               
60182
 
+               (void)sieve_binary_emit_unsigned(cgenv->sbin, sieve_ast_strlist_count(arg));
60183
 
+                                               
60184
 
+               while ( stritem != NULL ) {
60185
 
+                       struct sieve_variable *var = (struct sieve_variable *) stritem->context;
60186
 
+                       
60187
 
+                       (void)sieve_binary_emit_unsigned(cgenv->sbin, var->index);
60188
 
+                       
60189
 
+                       stritem = sieve_ast_strlist_next(stritem);
60190
 
+               }
60191
 
+       } else {
60192
 
+               i_unreached();
60193
 
+       }
60194
 
+                       
60195
 
+       return TRUE;
60196
 
+}
60197
 
+
60198
 
+/* 
60199
 
+ * Code dump
60200
 
+ */
60201
 
60202
 
+static bool opc_global_dump
60203
 
+(const struct sieve_operation *op ATTR_UNUSED,
60204
 
+       const struct sieve_dumptime_env *denv, sieve_size_t *address)
60205
 
+{
60206
 
+       unsigned int count, i, var_count;
60207
 
+       struct sieve_variable_scope *scope;
60208
 
+       struct sieve_variable * const *vars;
60209
 
+       
60210
 
+       if ( !sieve_binary_read_unsigned(denv->sbin, address, &count) )
60211
 
+               return FALSE;
60212
 
+
60213
 
+       sieve_code_dumpf(denv, "GLOBAL (count: %u):", count);
60214
 
+
60215
 
+       scope = ext_include_binary_get_global_scope(denv->sbin);
60216
 
+       vars = sieve_variable_scope_get_variables(scope, &var_count);
60217
 
+
60218
 
+       sieve_code_descend(denv);
60219
 
+
60220
 
+       for ( i = 0; i < count; i++ ) {
60221
 
+               unsigned int index;
60222
 
+               
60223
 
+               sieve_code_mark(denv);
60224
 
+               if ( !sieve_binary_read_unsigned(denv->sbin, address, &index) ||
60225
 
+                       index >= var_count )
60226
 
+                       return FALSE;
60227
 
+                       
60228
 
+               sieve_code_dumpf(denv, "VAR[%d]: '%s'", index, vars[index]->identifier); 
60229
 
+       }
60230
 
+        
60231
 
+       return TRUE;
60232
 
+}
60233
 
+
60234
 
+/* 
60235
 
+ * Execution
60236
 
+ */
60237
 
60238
 
+static int opc_global_execute
60239
 
+(const struct sieve_operation *op ATTR_UNUSED,
60240
 
+       const struct sieve_runtime_env *renv, sieve_size_t *address)
60241
 
+{
60242
 
+       struct sieve_variable_scope *scope;     
60243
 
+       struct sieve_variable_storage *storage;
60244
 
+       struct sieve_variable * const *vars;
60245
 
+       unsigned int var_count, count, i;
60246
 
+               
60247
 
+       if ( !sieve_binary_read_unsigned(renv->sbin, address, &count) ) {
60248
 
+               sieve_runtime_trace_error(renv, "invalid count operand");
60249
 
+               return SIEVE_EXEC_BIN_CORRUPT;
60250
 
+       }
60251
 
+       
60252
 
+       scope = ext_include_binary_get_global_scope(renv->sbin);
60253
 
+       vars = sieve_variable_scope_get_variables(scope, &var_count);
60254
 
+       storage = ext_include_interpreter_get_global_variables(renv->interp);
60255
 
+
60256
 
+       for ( i = 0; i < count; i++ ) {
60257
 
+               unsigned int index;
60258
 
+               
60259
 
+               if ( !sieve_binary_read_unsigned(renv->sbin, address, &index) ) {
60260
 
+                       sieve_runtime_trace_error(renv, "invalid global variable operand");
60261
 
+                       return SIEVE_EXEC_BIN_CORRUPT;
60262
 
+               }
60263
 
+               
60264
 
+               if ( index >= var_count ) {
60265
 
+                       sieve_runtime_trace_error(renv, "invalid global variable index (%u > %u)",
60266
 
+                               index, var_count);
60267
 
+                       return SIEVE_EXEC_BIN_CORRUPT;
60268
 
+               }
60269
 
+               
60270
 
+               /* Make sure variable is initialized (export) */
60271
 
+               (void)sieve_variable_get_modifiable(storage, index, NULL); 
60272
 
+       }
60273
 
+
60274
 
+       return SIEVE_EXEC_OK;
60275
 
+}
60276
 
+
60277
 
+
60278
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/include/cmd-include.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/include/cmd-include.c
60279
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/include/cmd-include.c  1970-01-01 01:00:00.000000000 +0100
60280
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/include/cmd-include.c   2009-08-04 19:14:52.000000000 +0200
60281
 
@@ -0,0 +1,360 @@
60282
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
60283
 
+ */
60284
 
+
60285
 
+#include "lib.h"
60286
 
+#include "str-sanitize.h"
60287
 
+
60288
 
+#include "sieve-common.h"
60289
 
+#include "sieve-script.h"
60290
 
+#include "sieve-ast.h"
60291
 
+#include "sieve-code.h"
60292
 
+#include "sieve-extensions.h"
60293
 
+#include "sieve-commands.h"
60294
 
+#include "sieve-validator.h"
60295
 
+#include "sieve-binary.h"
60296
 
+#include "sieve-generator.h"
60297
 
+#include "sieve-interpreter.h"
60298
 
+#include "sieve-dump.h"
60299
 
+
60300
 
+#include "ext-include-common.h"
60301
 
+#include "ext-include-binary.h"
60302
 
+
60303
 
+/* 
60304
 
+ * Include command 
60305
 
+ *     
60306
 
+ * Syntax: 
60307
 
+ *   include [LOCATION] <value: string>
60308
 
+ *
60309
 
+ * [LOCATION]:      
60310
 
+ *   ":personal" / ":global"
60311
 
+ */
60312
 
+
60313
 
+static bool cmd_include_registered
60314
 
+       (struct sieve_validator *validator, 
60315
 
+               struct sieve_command_registration *cmd_reg);
60316
 
+static bool cmd_include_pre_validate
60317
 
+       (struct sieve_validator *validator ATTR_UNUSED, 
60318
 
+               struct sieve_command_context *cmd);
60319
 
+static bool cmd_include_validate
60320
 
+       (struct sieve_validator *validator, struct sieve_command_context *cmd);
60321
 
+static bool cmd_include_generate
60322
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx);
60323
 
+
60324
 
+const struct sieve_command cmd_include = { 
60325
 
+       "include",
60326
 
+       SCT_COMMAND, 
60327
 
+       1, 0, FALSE, FALSE, 
60328
 
+       cmd_include_registered,
60329
 
+       cmd_include_pre_validate,  
60330
 
+       cmd_include_validate, 
60331
 
+       cmd_include_generate, 
60332
 
+       NULL 
60333
 
+};
60334
 
+
60335
 
+/* 
60336
 
+ * Include operation 
60337
 
+ */
60338
 
+
60339
 
+static bool opc_include_dump
60340
 
+       (const struct sieve_operation *op,      
60341
 
+               const struct sieve_dumptime_env *denv, sieve_size_t *address);
60342
 
+static int opc_include_execute
60343
 
+       (const struct sieve_operation *op, 
60344
 
+               const struct sieve_runtime_env *renv, sieve_size_t *address);
60345
 
+
60346
 
+const struct sieve_operation include_operation = { 
60347
 
+       "include",
60348
 
+       &include_extension,
60349
 
+       EXT_INCLUDE_OPERATION_INCLUDE,
60350
 
+       opc_include_dump, 
60351
 
+       opc_include_execute
60352
 
+};
60353
 
+
60354
 
+/* 
60355
 
+ * Context structures 
60356
 
+ */
60357
 
+
60358
 
+struct cmd_include_context_data {
60359
 
+       enum ext_include_script_location location;
60360
 
+       bool location_assigned;
60361
 
+       
60362
 
+       bool include_once;
60363
 
+       
60364
 
+       struct sieve_script *script;
60365
 
+};   
60366
 
+
60367
 
+/* 
60368
 
+ * Tagged arguments
60369
 
+ */
60370
 
+
60371
 
+static bool cmd_include_validate_location_tag
60372
 
+       (struct sieve_validator *validator, struct sieve_ast_argument **arg, 
60373
 
+               struct sieve_command_context *cmd);
60374
 
+
60375
 
+static const struct sieve_argument include_personal_tag = { 
60376
 
+       "personal", 
60377
 
+       NULL, NULL,
60378
 
+       cmd_include_validate_location_tag, 
60379
 
+       NULL, NULL 
60380
 
+};
60381
 
+
60382
 
+static const struct sieve_argument include_global_tag = { 
60383
 
+       "global", 
60384
 
+       NULL, NULL,
60385
 
+       cmd_include_validate_location_tag, 
60386
 
+       NULL, NULL 
60387
 
+};
60388
 
+
60389
 
+static bool cmd_include_validate_once_tag
60390
 
+       (struct sieve_validator *validator, struct sieve_ast_argument **arg, 
60391
 
+               struct sieve_command_context *cmd);
60392
 
+
60393
 
+static const struct sieve_argument include_once_tag = { 
60394
 
+       "once", 
60395
 
+       NULL, NULL,
60396
 
+       cmd_include_validate_once_tag, 
60397
 
+       NULL, NULL 
60398
 
+};
60399
 
+
60400
 
+/* 
60401
 
+ * Tag validation 
60402
 
+ */
60403
 
+
60404
 
+static bool cmd_include_validate_location_tag
60405
 
+(struct sieve_validator *validator,    struct sieve_ast_argument **arg, 
60406
 
+       struct sieve_command_context *cmd)
60407
 
+{    
60408
 
+       struct cmd_include_context_data *ctx_data = 
60409
 
+               (struct cmd_include_context_data *) cmd->data;
60410
 
+       
60411
 
+       if ( ctx_data->location_assigned) {
60412
 
+               sieve_argument_validate_error(validator, *arg, 
60413
 
+                       "include: cannot use location tags ':personal' and ':global' "
60414
 
+                       "multiple times");
60415
 
+               return FALSE;
60416
 
+       }
60417
 
+       
60418
 
+       if ( (*arg)->argument == &include_personal_tag )
60419
 
+               ctx_data->location = EXT_INCLUDE_LOCATION_PERSONAL;
60420
 
+       else if ( (*arg)->argument == &include_global_tag )
60421
 
+               ctx_data->location = EXT_INCLUDE_LOCATION_GLOBAL;
60422
 
+       else
60423
 
+               return FALSE;
60424
 
+       
60425
 
+       ctx_data->location_assigned = TRUE;
60426
 
+
60427
 
+       /* Delete this tag (for now) */
60428
 
+       *arg = sieve_ast_arguments_detach(*arg, 1);
60429
 
+
60430
 
+       return TRUE;
60431
 
+}
60432
 
+
60433
 
+static bool cmd_include_validate_once_tag
60434
 
+(struct sieve_validator *validator ATTR_UNUSED, struct sieve_ast_argument **arg, 
60435
 
+       struct sieve_command_context *cmd)
60436
 
+{    
60437
 
+       struct cmd_include_context_data *ctx_data = 
60438
 
+               (struct cmd_include_context_data *) cmd->data;
60439
 
+
60440
 
+       ctx_data->include_once = TRUE;
60441
 
+       
60442
 
+       /* Delete this tag (for now) */
60443
 
+       *arg = sieve_ast_arguments_detach(*arg, 1);
60444
 
+
60445
 
+       return TRUE;
60446
 
+}
60447
 
+
60448
 
+/* 
60449
 
+ * Command registration 
60450
 
+ */
60451
 
+
60452
 
+static bool cmd_include_registered
60453
 
+       (struct sieve_validator *validator, struct sieve_command_registration *cmd_reg) 
60454
 
+{
60455
 
+       sieve_validator_register_tag
60456
 
+               (validator, cmd_reg, &include_personal_tag, 0);         
60457
 
+       sieve_validator_register_tag
60458
 
+               (validator, cmd_reg, &include_global_tag, 0);   
60459
 
+       sieve_validator_register_tag
60460
 
+               (validator, cmd_reg, &include_once_tag, 0);     
60461
 
+
60462
 
+       return TRUE;
60463
 
+}
60464
 
+
60465
 
+/* 
60466
 
+ * Command validation 
60467
 
+ */
60468
 
+
60469
 
+static bool cmd_include_pre_validate
60470
 
+       (struct sieve_validator *validator ATTR_UNUSED, 
60471
 
+               struct sieve_command_context *cmd)
60472
 
+{
60473
 
+       struct cmd_include_context_data *ctx_data;
60474
 
+
60475
 
+       /* Assign context */
60476
 
+       ctx_data = p_new(sieve_command_pool(cmd), struct cmd_include_context_data, 1);
60477
 
+       ctx_data->location = EXT_INCLUDE_LOCATION_PERSONAL;
60478
 
+       cmd->data = ctx_data;
60479
 
+       
60480
 
+       return TRUE;
60481
 
+}
60482
 
+
60483
 
+static bool cmd_include_validate(struct sieve_validator *validator, 
60484
 
+       struct sieve_command_context *cmd) 
60485
 
+{      
60486
 
+       struct sieve_ast_argument *arg = cmd->first_positional;
60487
 
+       struct cmd_include_context_data *ctx_data = 
60488
 
+               (struct cmd_include_context_data *) cmd->data;
60489
 
+       struct sieve_script *script;
60490
 
+       const char *script_path, *script_name;
60491
 
+       bool exists = TRUE;
60492
 
+       
60493
 
+       /* Check argument */
60494
 
+       if ( !sieve_validate_positional_argument
60495
 
+               (validator, cmd, arg, "value", 1, SAAT_STRING) ) {
60496
 
+               return FALSE;
60497
 
+       }
60498
 
+
60499
 
+       if ( !sieve_validator_argument_activate(validator, cmd, arg, FALSE) )
60500
 
+               return FALSE;
60501
 
+
60502
 
+       /* 
60503
 
+        * Variables are not allowed.
60504
 
+        */
60505
 
+       if ( !sieve_argument_is_string_literal(arg) ) {
60506
 
+               sieve_argument_validate_error(validator, arg, 
60507
 
+                       "the include command requires a constant string for its value argument");
60508
 
+               return FALSE;
60509
 
+       }
60510
 
+
60511
 
+       /* Find the script */
60512
 
+
60513
 
+       script_name = sieve_ast_argument_strc(arg);
60514
 
+
60515
 
+       if ( strchr(script_name, '/') != NULL ) {
60516
 
+               sieve_argument_validate_error(validator, arg,
60517
 
+                       "include: '/' not allowed in script name (%s)",
60518
 
+                       str_sanitize(script_name, 80));
60519
 
+               return FALSE;
60520
 
+       }
60521
 
+               
60522
 
+       script_path = ext_include_get_script_directory
60523
 
+               (ctx_data->location, script_name);
60524
 
+       if ( script_path == NULL ) {
60525
 
+               sieve_argument_validate_error(validator, arg,
60526
 
+                       "include: %s location for included script '%s' is unavailable "
60527
 
+                       "(contact system administrator for more information)",
60528
 
+                       ext_include_script_location_name(ctx_data->location),
60529
 
+                       str_sanitize(script_name, 80));
60530
 
+               return FALSE;
60531
 
+       }
60532
 
+       
60533
 
+       /* Create script object */
60534
 
+       script = sieve_script_create_in_directory(script_path, script_name, 
60535
 
+               sieve_validator_error_handler(validator), &exists);
60536
 
+       if ( script == NULL ) {
60537
 
+               if ( !exists ) {
60538
 
+                       sieve_argument_validate_error(validator, arg, 
60539
 
+                               "included %s script '%s' does not exist", 
60540
 
+                               ext_include_script_location_name(ctx_data->location),
60541
 
+                               str_sanitize(script_name, 80));
60542
 
+               }
60543
 
+               return FALSE;
60544
 
+       }
60545
 
+
60546
 
+       ext_include_ast_link_included_script(cmd->ast_node->ast, script);               
60547
 
+       ctx_data->script = script;
60548
 
+               
60549
 
+       arg = sieve_ast_arguments_detach(arg, 1);
60550
 
+       
60551
 
+       return TRUE;
60552
 
+}
60553
 
+
60554
 
+/*
60555
 
+ * Code Generation
60556
 
+ */
60557
 
60558
 
+static bool cmd_include_generate
60559
 
+(const struct sieve_codegen_env *cgenv, struct sieve_command_context *cmd) 
60560
 
+{
60561
 
+       struct cmd_include_context_data *ctx_data = 
60562
 
+               (struct cmd_include_context_data *) cmd->data;
60563
 
+       const struct ext_include_script_info *included;
60564
 
+       unsigned int flags = ctx_data->include_once;
60565
 
+
60566
 
+       /* Compile (if necessary) and include the script into the binary.
60567
 
+        * This yields the id of the binary block containing the compiled byte code.  
60568
 
+        */
60569
 
+       if ( !ext_include_generate_include
60570
 
+               (cgenv, cmd, ctx_data->location, ctx_data->script, &included,
60571
 
+                       ctx_data->include_once) )
60572
 
+               return FALSE;
60573
 
+               
60574
 
+       (void)sieve_operation_emit_code(cgenv->sbin, &include_operation);
60575
 
+       (void)sieve_binary_emit_unsigned(cgenv->sbin, included->id); 
60576
 
+       (void)sieve_binary_emit_byte(cgenv->sbin, flags); 
60577
 
+                       
60578
 
+       return TRUE;
60579
 
+}
60580
 
+
60581
 
+/* 
60582
 
+ * Code dump
60583
 
+ */
60584
 
60585
 
+static bool opc_include_dump
60586
 
+(const struct sieve_operation *op ATTR_UNUSED,
60587
 
+       const struct sieve_dumptime_env *denv, sieve_size_t *address)
60588
 
+{
60589
 
+       const struct ext_include_script_info *included;
60590
 
+       struct ext_include_binary_context *binctx;
60591
 
+       unsigned int include_id, flags;
60592
 
+
60593
 
+       sieve_code_dumpf(denv, "INCLUDE:");
60594
 
+       
60595
 
+       sieve_code_mark(denv);
60596
 
+       if ( !sieve_binary_read_unsigned(denv->sbin, address, &include_id) )
60597
 
+               return FALSE;
60598
 
+
60599
 
+       if ( !sieve_binary_read_byte(denv->sbin, address, &flags) )
60600
 
+               return FALSE;
60601
 
+
60602
 
+       binctx = ext_include_binary_get_context(denv->sbin);
60603
 
+       included = ext_include_binary_script_get_included(binctx, include_id);
60604
 
+       if ( included == NULL )
60605
 
+               return FALSE;
60606
 
+               
60607
 
+       sieve_code_descend(denv);
60608
 
+       sieve_code_dumpf(denv, "script: %s %s[ID: %d, BLOCK: %d]", 
60609
 
+               sieve_script_filename(included->script), (flags & 0x01 ? "(once) " : ""),
60610
 
+               include_id, included->block_id);
60611
 
+
60612
 
+       return TRUE;
60613
 
+}
60614
 
+
60615
 
+/* 
60616
 
+ * Execution
60617
 
+ */
60618
 
60619
 
+static int opc_include_execute
60620
 
+(const struct sieve_operation *op ATTR_UNUSED,
60621
 
+       const struct sieve_runtime_env *renv, sieve_size_t *address)
60622
 
+{
60623
 
+       unsigned int include_id, flags;
60624
 
+               
60625
 
+       if ( !sieve_binary_read_unsigned(renv->sbin, address, &include_id) ) {
60626
 
+               sieve_runtime_trace_error(renv, "invalid include-id operand");
60627
 
+               return SIEVE_EXEC_BIN_CORRUPT;
60628
 
+       }
60629
 
+
60630
 
+       if ( !sieve_binary_read_unsigned(renv->sbin, address, &flags) ) {
60631
 
+               sieve_runtime_trace_error(renv, "invalid flags operand");
60632
 
+               return SIEVE_EXEC_BIN_CORRUPT;
60633
 
+       }
60634
 
+       
60635
 
+       return ext_include_execute_include(renv, include_id, flags & 0x01);
60636
 
+}
60637
 
+
60638
 
+
60639
 
+
60640
 
+
60641
 
+
60642
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/include/cmd-return.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/include/cmd-return.c
60643
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/include/cmd-return.c   1970-01-01 01:00:00.000000000 +0100
60644
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/include/cmd-return.c    2009-01-06 00:15:52.000000000 +0100
60645
 
@@ -0,0 +1,78 @@
60646
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
60647
 
+ */
60648
 
+
60649
 
+#include "lib.h"
60650
 
+
60651
 
+#include "sieve-code.h"
60652
 
+#include "sieve-commands.h"
60653
 
+#include "sieve-validator.h" 
60654
 
+#include "sieve-generator.h"
60655
 
+#include "sieve-interpreter.h"
60656
 
+
60657
 
+#include "ext-include-common.h"
60658
 
+
60659
 
+/* 
60660
 
+ * Return command 
60661
 
+ * 
60662
 
+ * Syntax
60663
 
+ *   return
60664
 
+ */
60665
 
+
60666
 
+static bool cmd_return_generate
60667
 
+       (const struct sieve_codegen_env *cgenv, 
60668
 
+               struct sieve_command_context *ctx ATTR_UNUSED);
60669
 
+       
60670
 
+const struct sieve_command cmd_return = { 
60671
 
+       "return", 
60672
 
+       SCT_COMMAND, 
60673
 
+       0, 0, FALSE, FALSE,
60674
 
+       NULL, NULL, NULL, 
60675
 
+       cmd_return_generate, 
60676
 
+       NULL
60677
 
+};
60678
 
+
60679
 
+/* 
60680
 
+ * Return operation 
60681
 
+ */
60682
 
+
60683
 
+static int opc_return_execute
60684
 
+       (const struct sieve_operation *op, 
60685
 
+               const struct sieve_runtime_env *renv, sieve_size_t *address);
60686
 
+
60687
 
+const struct sieve_operation return_operation = { 
60688
 
+       "return",
60689
 
+       &include_extension,
60690
 
+       EXT_INCLUDE_OPERATION_RETURN,
60691
 
+       NULL, 
60692
 
+       opc_return_execute 
60693
 
+};
60694
 
+
60695
 
+/*
60696
 
+ * Code generation
60697
 
+ */
60698
 
+
60699
 
+static bool cmd_return_generate
60700
 
+(const struct sieve_codegen_env *cgenv, 
60701
 
+       struct sieve_command_context *ctx ATTR_UNUSED) 
60702
 
+{
60703
 
+       sieve_operation_emit_code(cgenv->sbin, &return_operation);
60704
 
+
60705
 
+       return TRUE;
60706
 
+}
60707
 
+
60708
 
+/*
60709
 
+ * Execution
60710
 
+ */
60711
 
+
60712
 
+static int opc_return_execute
60713
 
+(const struct sieve_operation *op ATTR_UNUSED,
60714
 
+       const struct sieve_runtime_env *renv, 
60715
 
+       sieve_size_t *address ATTR_UNUSED)
60716
 
+{      
60717
 
+       sieve_runtime_trace(renv, "RETURN command");
60718
 
+
60719
 
+       ext_include_execute_return(renv);
60720
 
+       return SIEVE_EXEC_OK;
60721
 
+}
60722
 
+
60723
 
+
60724
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/include/ext-include-binary.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/include/ext-include-binary.c
60725
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/include/ext-include-binary.c   1970-01-01 01:00:00.000000000 +0100
60726
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/include/ext-include-binary.c    2009-08-08 14:57:37.000000000 +0200
60727
 
@@ -0,0 +1,425 @@
60728
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
60729
 
+ */
60730
 
+
60731
 
+#include "lib.h"
60732
 
+#include "str.h"
60733
 
+
60734
 
+#include "sieve-common.h"
60735
 
+#include "sieve-error.h"
60736
 
+#include "sieve-script.h"
60737
 
+#include "sieve-binary.h"
60738
 
+#include "sieve-generator.h"
60739
 
+#include "sieve-interpreter.h"
60740
 
+#include "sieve-dump.h"
60741
 
+
60742
 
+#include "sieve-ext-variables.h"
60743
 
+
60744
 
+#include "ext-include-common.h"
60745
 
+#include "ext-include-limits.h"
60746
 
+#include "ext-include-variables.h"
60747
 
+#include "ext-include-binary.h"
60748
 
+
60749
 
+/*
60750
 
+ * Forward declarations
60751
 
+ */
60752
 
60753
 
+static bool ext_include_binary_save(struct sieve_binary *sbin);
60754
 
+static bool ext_include_binary_open(struct sieve_binary *sbin);
60755
 
+static bool ext_include_binary_up_to_date(struct sieve_binary *sbin);
60756
 
+static void ext_include_binary_free(struct sieve_binary *sbin);
60757
 
+
60758
 
+/* 
60759
 
+ * Binary include extension
60760
 
+ */
60761
 
60762
 
+const struct sieve_binary_extension include_binary_ext = {
60763
 
+       &include_extension,
60764
 
+       ext_include_binary_save,
60765
 
+       ext_include_binary_open,
60766
 
+       ext_include_binary_free,
60767
 
+       ext_include_binary_up_to_date
60768
 
+};
60769
 
+
60770
 
+/*
60771
 
+ * Binary context management
60772
 
+ */
60773
 
60774
 
+struct ext_include_binary_context {
60775
 
+       struct sieve_binary *binary;
60776
 
+       unsigned int dependency_block;
60777
 
+       
60778
 
+       struct hash_table *included_scripts;
60779
 
+       ARRAY_DEFINE(include_index, struct ext_include_script_info *);
60780
 
+
60781
 
+       struct sieve_variable_scope *global_vars;
60782
 
+};
60783
 
+
60784
 
60785
 
+static struct ext_include_binary_context *ext_include_binary_create_context
60786
 
+(struct sieve_binary *sbin)
60787
 
+{
60788
 
+       pool_t pool = sieve_binary_pool(sbin);
60789
 
+       
60790
 
+       struct ext_include_binary_context *ctx = 
60791
 
+               p_new(pool, struct ext_include_binary_context, 1);
60792
 
+       
60793
 
+       ctx->binary = sbin;                     
60794
 
+       ctx->included_scripts = hash_table_create(default_pool, pool, 0, 
60795
 
+               (hash_callback_t *) sieve_script_hash, 
60796
 
+               (hash_cmp_callback_t *) sieve_script_cmp);
60797
 
+       p_array_init(&ctx->include_index, pool, 128);
60798
 
+
60799
 
+       sieve_binary_extension_set(sbin, &include_binary_ext, ctx);
60800
 
+
60801
 
+       return ctx;
60802
 
+}
60803
 
+
60804
 
+struct ext_include_binary_context *ext_include_binary_get_context
60805
 
+(struct sieve_binary *sbin)
60806
 
+{      
60807
 
+       struct ext_include_binary_context *ctx = (struct ext_include_binary_context *)
60808
 
+               sieve_binary_extension_get_context(sbin, &include_extension);
60809
 
+       
60810
 
+       if ( ctx == NULL )
60811
 
+               ctx = ext_include_binary_create_context(sbin);
60812
 
+       
60813
 
+       return ctx;
60814
 
+}
60815
 
60816
 
+struct ext_include_binary_context *ext_include_binary_init
60817
 
+(struct sieve_binary *sbin, struct sieve_ast *ast)
60818
 
+{
60819
 
+       struct ext_include_ast_context *ast_ctx =
60820
 
+               ext_include_get_ast_context(ast);
60821
 
+       struct ext_include_binary_context *ctx;
60822
 
+       
60823
 
+       /* Get/create our context from the binary we are working on */
60824
 
+       ctx = ext_include_binary_get_context(sbin);
60825
 
+       
60826
 
+       /* Create dependency block */
60827
 
+       if ( ctx->dependency_block == 0 )
60828
 
+               ctx->dependency_block = 
60829
 
+                       sieve_binary_extension_create_block(sbin, &include_extension);
60830
 
+
60831
 
+       if ( ctx->global_vars == NULL ) {
60832
 
+               ctx->global_vars = ast_ctx->global_vars;
60833
 
+               sieve_variable_scope_ref(ctx->global_vars);
60834
 
+       }
60835
 
+                       
60836
 
+       return ctx;
60837
 
+}
60838
 
+
60839
 
+/*
60840
 
+ * Script inclusion
60841
 
+ */
60842
 
+
60843
 
+const struct ext_include_script_info *ext_include_binary_script_include
60844
 
+(struct ext_include_binary_context *binctx, struct sieve_script *script,
60845
 
+       enum ext_include_script_location location, unsigned int block_id)
60846
 
+{
60847
 
+       pool_t pool = sieve_binary_pool(binctx->binary);
60848
 
+       struct ext_include_script_info *incscript;
60849
 
+
60850
 
+       incscript = p_new(pool, struct ext_include_script_info, 1);
60851
 
+       incscript->id = array_count(&binctx->include_index)+1;
60852
 
+       incscript->script = script;
60853
 
+       incscript->location = location;
60854
 
+       incscript->block_id = block_id;
60855
 
+       
60856
 
+       /* Unreferenced on binary_free */
60857
 
+       sieve_script_ref(script);
60858
 
+       
60859
 
+       hash_table_insert(binctx->included_scripts, (void *) script, (void *) incscript);
60860
 
+       array_append(&binctx->include_index, &incscript, 1);
60861
 
+
60862
 
+       return incscript;
60863
 
+}
60864
 
+
60865
 
+bool ext_include_binary_script_is_included
60866
 
+(struct ext_include_binary_context *binctx, struct sieve_script *script,
60867
 
+       const struct ext_include_script_info **script_info_r)
60868
 
+{
60869
 
+       struct ext_include_script_info *incscript = (struct ext_include_script_info *)
60870
 
+               hash_table_lookup(binctx->included_scripts, script);
60871
 
+               
60872
 
+       if ( incscript == NULL )
60873
 
+               return FALSE;
60874
 
+                               
60875
 
+       *script_info_r = incscript;
60876
 
+       return TRUE;
60877
 
+}
60878
 
+
60879
 
+const struct ext_include_script_info *ext_include_binary_script_get_included
60880
 
+(struct ext_include_binary_context *binctx, unsigned int include_id)
60881
 
+{              
60882
 
+       if ( include_id > 0 && (include_id - 1) < array_count(&binctx->include_index) ) {
60883
 
+               struct ext_include_script_info *const *sinfo =
60884
 
+                       array_idx(&binctx->include_index, include_id - 1);
60885
 
+
60886
 
+               return *sinfo;
60887
 
+       }
60888
 
+
60889
 
+       return NULL;
60890
 
+}
60891
 
+
60892
 
+const struct ext_include_script_info *ext_include_binary_script_get
60893
 
+(struct ext_include_binary_context *binctx, struct sieve_script *script)
60894
 
+{
60895
 
+       return (struct ext_include_script_info *)
60896
 
+               hash_table_lookup(binctx->included_scripts, script);
60897
 
+}
60898
 
+
60899
 
+unsigned int ext_include_binary_script_get_count
60900
 
+(struct ext_include_binary_context *binctx)
60901
 
+{
60902
 
+       return array_count(&binctx->include_index);
60903
 
+}
60904
 
+
60905
 
+/*
60906
 
+ * Variables 
60907
 
+ */
60908
 
+
60909
 
+struct sieve_variable_scope *ext_include_binary_get_global_scope
60910
 
+(struct sieve_binary *sbin)
60911
 
+{
60912
 
+       struct ext_include_binary_context *binctx = 
60913
 
+               ext_include_binary_get_context(sbin);
60914
 
+
60915
 
+       return binctx->global_vars;
60916
 
+}
60917
 
+
60918
 
+/*
60919
 
+ * Binary extension
60920
 
+ */
60921
 
+
60922
 
+static bool ext_include_binary_save(struct sieve_binary *sbin)
60923
 
+{
60924
 
+       struct ext_include_binary_context *binctx = 
60925
 
+               ext_include_binary_get_context(sbin);
60926
 
+       struct ext_include_script_info *const *scripts;
60927
 
+       unsigned int script_count, i;
60928
 
+       unsigned int prvblk;
60929
 
+       bool result = TRUE;
60930
 
+       
60931
 
+       sieve_binary_block_clear(sbin, binctx->dependency_block);
60932
 
+       if ( !sieve_binary_block_set_active(sbin, binctx->dependency_block, &prvblk) )  
60933
 
+               return FALSE;
60934
 
+
60935
 
+       scripts = array_get(&binctx->include_index, &script_count);
60936
 
+
60937
 
+       sieve_binary_emit_unsigned(sbin, script_count);
60938
 
+
60939
 
+       for ( i = 0; i < script_count; i++ ) {
60940
 
+               struct ext_include_script_info *incscript = scripts[i];
60941
 
+
60942
 
+               sieve_binary_emit_unsigned(sbin, incscript->block_id);
60943
 
+               sieve_binary_emit_byte(sbin, incscript->location);
60944
 
+               sieve_binary_emit_cstring(sbin, sieve_script_name(incscript->script));
60945
 
+       }
60946
 
+
60947
 
+       result = ext_include_variables_save(sbin, binctx->global_vars);
60948
 
+       
60949
 
+       (void) sieve_binary_block_set_active(sbin, prvblk, NULL);
60950
 
+
60951
 
+       return result;
60952
 
+}
60953
 
+
60954
 
+static bool ext_include_binary_open(struct sieve_binary *sbin)
60955
 
+{
60956
 
+       struct ext_include_binary_context *binctx; 
60957
 
+       unsigned int block, prvblk, depcount, i;
60958
 
+       sieve_size_t offset;
60959
 
+       
60960
 
+       block = sieve_binary_extension_get_block(sbin, &include_extension);
60961
 
+       
60962
 
+       if ( !sieve_binary_block_set_active(sbin, block, &prvblk) )
60963
 
+               return FALSE; 
60964
 
+               
60965
 
+       offset = 0;     
60966
 
+               
60967
 
+       if ( !sieve_binary_read_unsigned(sbin, &offset, &depcount) ) {
60968
 
+               sieve_sys_error("include: failed to read include count "
60969
 
+                       "for dependency block %d of binary %s", block, sieve_binary_path(sbin)); 
60970
 
+               return FALSE;
60971
 
+       }
60972
 
+       
60973
 
+       binctx = ext_include_binary_get_context(sbin);
60974
 
+
60975
 
+       /* Check include limit */       
60976
 
+       if ( depcount > EXT_INCLUDE_MAX_INCLUDES ) {
60977
 
+               sieve_sys_error("include: binary %s includes too many scripts (%u > %u)",
60978
 
+                       sieve_binary_path(sbin), depcount, EXT_INCLUDE_MAX_INCLUDES); 
60979
 
+               return FALSE;
60980
 
+       }
60981
 
+       
60982
 
+       /* Read dependencies */
60983
 
+       for ( i = 0; i < depcount; i++ ) {
60984
 
+               unsigned int block_id;
60985
 
+               enum ext_include_script_location location;
60986
 
+               string_t *script_name;
60987
 
+               const char *script_dir;
60988
 
+               struct sieve_script *script;
60989
 
+               
60990
 
+               if ( 
60991
 
+                       !sieve_binary_read_unsigned(sbin, &offset, &block_id) ||
60992
 
+                       !sieve_binary_read_byte(sbin, &offset, &location) ||
60993
 
+                       !sieve_binary_read_string(sbin, &offset, &script_name) ) {
60994
 
+                       /* Binary is corrupt, recompile */
60995
 
+                       sieve_sys_error("include: failed to read included script "
60996
 
+                               "from dependency block %d of binary %s", block, sieve_binary_path(sbin)); 
60997
 
+                       return FALSE;
60998
 
+               }
60999
 
+               
61000
 
+               if ( location >= EXT_INCLUDE_LOCATION_INVALID ) {
61001
 
+                       /* Binary is corrupt, recompile */
61002
 
+                       sieve_sys_error("include: dependency block %d of binary %s "
61003
 
+                               "reports invalid script location (id %d)", 
61004
 
+                               block, sieve_binary_path(sbin), location); 
61005
 
+                       return FALSE;
61006
 
+               }               
61007
 
+               
61008
 
+               /* Can we find/open the script dependency ? */
61009
 
+               script_dir = ext_include_get_script_directory(location, str_c(script_name));            
61010
 
+               if ( script_dir == NULL || 
61011
 
+                       !(script=sieve_script_create_in_directory
61012
 
+                               (script_dir, str_c(script_name), NULL, NULL)) ) {
61013
 
+                       /* No, recompile */
61014
 
+                       return FALSE;
61015
 
+               }
61016
 
+               
61017
 
+               (void)ext_include_binary_script_include(binctx, script, location, block_id);
61018
 
+                               
61019
 
+               sieve_script_unref(&script);
61020
 
+       }
61021
 
+
61022
 
+       if ( !ext_include_variables_load(sbin, &offset, block, &binctx->global_vars) )
61023
 
+               return FALSE;
61024
 
+       
61025
 
+       /* Restore previously active block */
61026
 
+       (void)sieve_binary_block_set_active(sbin, prvblk, NULL);
61027
 
+
61028
 
+       return TRUE;    
61029
 
+}
61030
 
+
61031
 
+static bool ext_include_binary_up_to_date(struct sieve_binary *sbin)
61032
 
+{
61033
 
+       struct ext_include_binary_context *binctx = 
61034
 
+               ext_include_binary_get_context(sbin);
61035
 
+       struct hash_iterate_context *hctx;
61036
 
+       void *key, *value;
61037
 
+               
61038
 
+       /* Check all included scripts for changes */
61039
 
+       hctx = hash_table_iterate_init(binctx->included_scripts);
61040
 
+       while ( hash_table_iterate(hctx, &key, &value) ) {
61041
 
+               struct ext_include_script_info *incscript = (struct ext_include_script_info *) value;
61042
 
+               
61043
 
+               /* Is the binary newer than this dependency? */
61044
 
+               if ( !sieve_binary_script_older(sbin, incscript->script) ) {
61045
 
+                       /* No, recompile */
61046
 
+                       return FALSE;
61047
 
+               }
61048
 
+       }
61049
 
+       hash_table_iterate_deinit(&hctx);
61050
 
+
61051
 
+       return TRUE;
61052
 
+}
61053
 
+
61054
 
+static void ext_include_binary_free(struct sieve_binary *sbin)
61055
 
+{
61056
 
+       struct ext_include_binary_context *binctx = 
61057
 
+               ext_include_binary_get_context(sbin);
61058
 
+       struct hash_iterate_context *hctx;
61059
 
+       void *key, *value;
61060
 
+               
61061
 
+       /* Release references to all included script objects */
61062
 
+       hctx = hash_table_iterate_init(binctx->included_scripts);
61063
 
+       while ( hash_table_iterate(hctx, &key, &value) ) {
61064
 
+               struct ext_include_script_info *incscript = (struct ext_include_script_info *) value;
61065
 
+               
61066
 
+               sieve_script_unref(&incscript->script);
61067
 
+       }
61068
 
+       hash_table_iterate_deinit(&hctx);
61069
 
+
61070
 
+       hash_table_destroy(&binctx->included_scripts);
61071
 
+
61072
 
+       if ( binctx->global_vars != NULL ) 
61073
 
+               sieve_variable_scope_unref(&binctx->global_vars);
61074
 
+}
61075
 
+
61076
 
+/*
61077
 
+ * Dumping the binary 
61078
 
+ */
61079
 
+
61080
 
+inline static const char *_script_location
61081
 
+(enum ext_include_script_location loc)
61082
 
+{
61083
 
+       switch ( loc ) {
61084
 
+       case EXT_INCLUDE_LOCATION_PERSONAL:
61085
 
+               return "personal";
61086
 
+       case EXT_INCLUDE_LOCATION_GLOBAL:
61087
 
+               return "global";
61088
 
+       default:
61089
 
+               break;
61090
 
+       }
61091
 
+       
61092
 
+       return "<<INVALID LOCATION>>";
61093
 
+}
61094
 
+
61095
 
+bool ext_include_binary_dump(struct sieve_dumptime_env *denv)
61096
 
+{
61097
 
+       struct sieve_binary *sbin = denv->sbin;
61098
 
+       struct ext_include_binary_context *binctx = 
61099
 
+               ext_include_binary_get_context(sbin);
61100
 
+       struct hash_iterate_context *hctx;
61101
 
+       void *key, *value;
61102
 
+       unsigned int prvblk = 0;
61103
 
+
61104
 
+       if ( !ext_include_variables_dump(denv, binctx->global_vars) )
61105
 
+               return FALSE;
61106
 
+
61107
 
+       hctx = hash_table_iterate_init(binctx->included_scripts);               
61108
 
+       while ( hash_table_iterate(hctx, &key, &value) ) {
61109
 
+               struct ext_include_script_info *incscript = (struct ext_include_script_info *) value;
61110
 
+
61111
 
+               sieve_binary_dump_sectionf(denv, "Included %s script '%s' (block: %d)", 
61112
 
+                       _script_location(incscript->location), 
61113
 
+                       sieve_script_name(incscript->script), incscript->block_id);
61114
 
+                       
61115
 
+               if ( prvblk == 0 ) {
61116
 
+                       if ( !sieve_binary_block_set_active(sbin, incscript->block_id, &prvblk) )       
61117
 
+                               return FALSE;
61118
 
+               } else {
61119
 
+                       if ( !sieve_binary_block_set_active(sbin, incscript->block_id, NULL) )  
61120
 
+                               return FALSE;
61121
 
+               }
61122
 
+                               
61123
 
+               denv->cdumper = sieve_code_dumper_create(denv);
61124
 
+
61125
 
+               if ( denv->cdumper == NULL )
61126
 
+                       return FALSE;
61127
 
+
61128
 
+               sieve_code_dumper_run(denv->cdumper);
61129
 
+               sieve_code_dumper_free(&(denv->cdumper));
61130
 
+       }
61131
 
+       
61132
 
+       if ( !sieve_binary_block_set_active(sbin, prvblk, NULL) ) 
61133
 
+               return FALSE;
61134
 
+       
61135
 
+       hash_table_iterate_deinit(&hctx);
61136
 
+       
61137
 
+       return TRUE;
61138
 
+}
61139
 
+
61140
 
+bool ext_include_code_dump
61141
 
+(const struct sieve_dumptime_env *denv, sieve_size_t *address ATTR_UNUSED)
61142
 
+{
61143
 
+       struct sieve_binary *sbin = denv->sbin;
61144
 
+       struct ext_include_binary_context *binctx = 
61145
 
+               ext_include_binary_get_context(sbin);
61146
 
+       
61147
 
+       sieve_ext_variables_dump_set_scope(denv, &include_extension, binctx->global_vars);
61148
 
+
61149
 
+       return TRUE;
61150
 
+}
61151
 
+
61152
 
+
61153
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/include/ext-include-binary.h dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/include/ext-include-binary.h
61154
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/include/ext-include-binary.h   1970-01-01 01:00:00.000000000 +0100
61155
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/include/ext-include-binary.h    2009-07-29 01:52:02.000000000 +0200
61156
 
@@ -0,0 +1,63 @@
61157
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
61158
 
+ */
61159
 
+
61160
 
+#ifndef __EXT_INCLUDE_BINARY_H
61161
 
+#define __EXT_INCLUDE_BINARY_H
61162
 
+
61163
 
+#include "sieve-common.h"
61164
 
+
61165
 
+/*
61166
 
+ * Binary context management
61167
 
+ */
61168
 
+
61169
 
+struct ext_include_binary_context;
61170
 
+
61171
 
+struct ext_include_binary_context *ext_include_binary_init
61172
 
+       (struct sieve_binary *sbin, struct sieve_ast *ast);
61173
 
+struct ext_include_binary_context *ext_include_binary_get_context
61174
 
+       (struct sieve_binary *sbin);
61175
 
+
61176
 
+/*
61177
 
+ * Variables
61178
 
+ */
61179
 
+
61180
 
+struct sieve_variable_scope *ext_include_binary_get_global_scope
61181
 
+    (struct sieve_binary *sbin);
61182
 
+
61183
 
+/*
61184
 
+ * Including scripts
61185
 
+ */
61186
 
+
61187
 
+struct ext_include_script_info {
61188
 
+    unsigned int id;
61189
 
+
61190
 
+    struct sieve_script *script;
61191
 
+    enum ext_include_script_location location;
61192
 
+
61193
 
+    unsigned int block_id;
61194
 
+};
61195
 
+
61196
 
+const struct ext_include_script_info *ext_include_binary_script_include
61197
 
+       (struct ext_include_binary_context *binctx, struct sieve_script *script,
61198
 
+               enum ext_include_script_location location, unsigned int block_id);
61199
 
+bool ext_include_binary_script_is_included
61200
 
+       (struct ext_include_binary_context *binctx, struct sieve_script *script,
61201
 
+               const struct ext_include_script_info **script_info_r);
61202
 
+
61203
 
+const struct ext_include_script_info *ext_include_binary_script_get_included
61204
 
+       (struct ext_include_binary_context *binctx, unsigned int include_id);
61205
 
+const struct ext_include_script_info *ext_include_binary_script_get
61206
 
+       (struct ext_include_binary_context *binctx, struct sieve_script *script);
61207
 
+unsigned int ext_include_binary_script_get_count
61208
 
+       (struct ext_include_binary_context *binctx);
61209
 
+
61210
 
+/*
61211
 
+ * Dumping the binary
61212
 
+ */
61213
 
+
61214
 
+bool ext_include_binary_dump(struct sieve_dumptime_env *denv);
61215
 
+bool ext_include_code_dump
61216
 
+       (const struct sieve_dumptime_env *denv, sieve_size_t *address ATTR_UNUSED);
61217
 
+               
61218
 
+#endif /* __EXT_INCLUDE_BINARY_H */
61219
 
+
61220
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/include/ext-include.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/include/ext-include.c
61221
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/include/ext-include.c  1970-01-01 01:00:00.000000000 +0100
61222
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/include/ext-include.c   2009-07-29 01:52:20.000000000 +0200
61223
 
@@ -0,0 +1,109 @@
61224
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
61225
 
+ */
61226
 
+
61227
 
+/* Extension include
61228
 
+ * -----------------
61229
 
+ *
61230
 
+ * Authors: Stephan Bosch
61231
 
+ * Specification: draft-ietf-sieve-include-01
61232
 
+ * Implementation: almost full; global namespace is missing. 
61233
 
+ * Status: experimental
61234
 
+ * 
61235
 
+ */
61236
 
61237
 
+/* FIXME: Current include implementation does not allow for parts of the script
61238
 
+ * to be located in external binaries; all included scripts are recompiled and
61239
 
+ * the resulting byte code is imported into the main binary in separate blocks.
61240
 
+ */
61241
 
61242
 
+#include "lib.h"
61243
 
+
61244
 
+#include "sieve-common.h"
61245
 
+
61246
 
+#include "sieve-extensions.h"
61247
 
+#include "sieve-validator.h"
61248
 
+#include "sieve-generator.h"
61249
 
+#include "sieve-interpreter.h"
61250
 
+#include "sieve-binary.h"
61251
 
+#include "sieve-dump.h"
61252
 
+
61253
 
+#include "ext-include-common.h"
61254
 
+#include "ext-include-binary.h"
61255
 
+
61256
 
+/* 
61257
 
+ * Operations 
61258
 
+ */
61259
 
+
61260
 
+static const struct sieve_operation *ext_include_operations[] = { 
61261
 
+       &include_operation, 
61262
 
+       &return_operation,
61263
 
+       &global_operation
61264
 
+};
61265
 
+
61266
 
+/* 
61267
 
+ * Extension
61268
 
+ */
61269
 
61270
 
+/* Forward declaration */
61271
 
+
61272
 
+static bool ext_include_validator_load(struct sieve_validator *validator);
61273
 
+static bool ext_include_generator_load(const struct sieve_codegen_env *cgenv);
61274
 
+static bool ext_include_interpreter_load
61275
 
+       (const struct sieve_runtime_env *renv, sieve_size_t *address);
61276
 
+static bool ext_include_binary_load(struct sieve_binary *binary);
61277
 
+
61278
 
+/* Extension objects */
61279
 
+
61280
 
+static int ext_my_id = -1;
61281
 
+
61282
 
+const struct sieve_extension include_extension = { 
61283
 
+       "include", 
61284
 
+       &ext_my_id,
61285
 
+       NULL, NULL,
61286
 
+       ext_include_validator_load, 
61287
 
+       ext_include_generator_load,
61288
 
+       ext_include_interpreter_load,
61289
 
+       ext_include_binary_load,
61290
 
+       ext_include_binary_dump,
61291
 
+       ext_include_code_dump,
61292
 
+       SIEVE_EXT_DEFINE_OPERATIONS(ext_include_operations),
61293
 
+       SIEVE_EXT_DEFINE_NO_OPERANDS
61294
 
+};
61295
 
+
61296
 
+/* Extension hooks */
61297
 
+
61298
 
+static bool ext_include_validator_load(struct sieve_validator *validator)
61299
 
+{
61300
 
+       /* Register new commands */
61301
 
+       sieve_validator_register_command(validator, &cmd_include);
61302
 
+       sieve_validator_register_command(validator, &cmd_return);
61303
 
+       sieve_validator_register_command(validator, &cmd_global);
61304
 
+
61305
 
+       /* DEPRICATED */
61306
 
+       sieve_validator_register_command(validator, &cmd_import);
61307
 
+       sieve_validator_register_command(validator, &cmd_export);
61308
 
+
61309
 
+       return TRUE;
61310
 
+}      
61311
 
+
61312
 
+static bool ext_include_generator_load(const struct sieve_codegen_env *cgenv)
61313
 
+{
61314
 
+       ext_include_register_generator_context(cgenv);
61315
 
+
61316
 
+       return TRUE;
61317
 
+}
61318
 
+
61319
 
+static bool ext_include_interpreter_load
61320
 
+(const struct sieve_runtime_env *renv, sieve_size_t *address ATTR_UNUSED)
61321
 
+{
61322
 
+       ext_include_interpreter_context_init(renv->interp);
61323
 
+       
61324
 
+       return TRUE;
61325
 
+}
61326
 
+
61327
 
+static bool ext_include_binary_load(struct sieve_binary *sbin)
61328
 
+{
61329
 
+       (void)ext_include_binary_get_context(sbin);
61330
 
+
61331
 
+       return TRUE;
61332
 
+}
61333
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/include/ext-include-common.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/include/ext-include-common.c
61334
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/include/ext-include-common.c   1970-01-01 01:00:00.000000000 +0100
61335
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/include/ext-include-common.c    2009-08-08 14:57:37.000000000 +0200
61336
 
@@ -0,0 +1,711 @@
61337
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
61338
 
+ */
61339
 
+
61340
 
+#include "lib.h"
61341
 
+#include "array.h"
61342
 
+#include "str-sanitize.h"
61343
 
+#include "home-expand.h"
61344
 
+
61345
 
+#include "sieve-common.h"
61346
 
+#include "sieve-error.h"
61347
 
+#include "sieve-script.h"
61348
 
+#include "sieve-ast.h"
61349
 
+#include "sieve-binary.h"
61350
 
+#include "sieve-commands.h"
61351
 
+#include "sieve-generator.h"
61352
 
+#include "sieve-interpreter.h"
61353
 
+
61354
 
+#include "ext-include-common.h"
61355
 
+#include "ext-include-limits.h"
61356
 
+#include "ext-include-binary.h"
61357
 
+#include "ext-include-variables.h"
61358
 
+
61359
 
+#include <stdlib.h>
61360
 
+
61361
 
+/*
61362
 
+ * Forward declarations
61363
 
+ */
61364
 
+
61365
 
+/* Generator context */
61366
 
+
61367
 
+struct ext_include_generator_context {
61368
 
+       unsigned int nesting_level;
61369
 
+       struct sieve_script *script;
61370
 
+       struct ext_include_generator_context *parent;
61371
 
+};
61372
 
+
61373
 
+static inline struct ext_include_generator_context *
61374
 
+       ext_include_get_generator_context
61375
 
+       (struct sieve_generator *gentr);
61376
 
+
61377
 
+/* Interpreter context */
61378
 
+
61379
 
+struct ext_include_interpreter_global {
61380
 
+       ARRAY_DEFINE(included_scripts, struct sieve_script *);
61381
 
+
61382
 
+       struct sieve_variable_storage *variables;
61383
 
+};
61384
 
+
61385
 
+struct ext_include_interpreter_context {
61386
 
+       struct ext_include_interpreter_context *parent;
61387
 
+       struct ext_include_interpreter_global *global;
61388
 
+
61389
 
+       struct sieve_interpreter *interp;
61390
 
+       pool_t pool;
61391
 
+
61392
 
+       unsigned int nesting_level;
61393
 
+
61394
 
+       struct sieve_script *script;
61395
 
+       const struct ext_include_script_info *script_info;
61396
 
+       
61397
 
+       const struct ext_include_script_info *include;
61398
 
+       bool returned;
61399
 
+};
61400
 
+
61401
 
+/* 
61402
 
+ * Script access 
61403
 
+ */
61404
 
+
61405
 
+const char *ext_include_get_script_directory
61406
 
+(enum ext_include_script_location location, const char *script_name)
61407
 
+{
61408
 
+       const char *home, *sieve_dir;
61409
 
+
61410
 
+       switch ( location ) {
61411
 
+       case EXT_INCLUDE_LOCATION_PERSONAL:
61412
 
+               sieve_dir = getenv("SIEVE_DIR");
61413
 
+               home = getenv("HOME");
61414
 
+
61415
 
+               if (sieve_dir == NULL) {
61416
 
+                       if ( home == NULL )     {               
61417
 
+                               sieve_sys_error(
61418
 
+                                       "include: sieve_dir and home not set for :personal script include "     
61419
 
+                                       "(wanted script '%s')", str_sanitize(script_name, 80));
61420
 
+                               return NULL;
61421
 
+                       }
61422
 
+
61423
 
+                       sieve_dir = "~/sieve"; 
61424
 
+               }
61425
 
+
61426
 
+               if ( home != NULL )
61427
 
+                       sieve_dir = home_expand_tilde(sieve_dir, home); 
61428
 
+
61429
 
+               break;
61430
 
+       case EXT_INCLUDE_LOCATION_GLOBAL:
61431
 
+               sieve_dir = getenv("SIEVE_GLOBAL_DIR");
61432
 
+
61433
 
+               if (sieve_dir == NULL) {
61434
 
+                       sieve_sys_error(
61435
 
+                               "include: sieve_global_dir not set for :global script include " 
61436
 
+                               "(wanted script '%s')", str_sanitize(script_name, 80));
61437
 
+                       return NULL;
61438
 
+               }
61439
 
+
61440
 
+               break;
61441
 
+       default:
61442
 
+               return NULL;
61443
 
+       }
61444
 
+
61445
 
+
61446
 
+       return sieve_dir;
61447
 
+}
61448
 
+
61449
 
+/*
61450
 
+ * AST context management
61451
 
+ */
61452
 
+
61453
 
+static void ext_include_ast_free
61454
 
+(struct sieve_ast *ast ATTR_UNUSED, void *context)
61455
 
+{
61456
 
+       struct ext_include_ast_context *actx = 
61457
 
+               (struct ext_include_ast_context *) context;
61458
 
+       struct sieve_script **scripts;
61459
 
+       unsigned int count, i;
61460
 
+
61461
 
+       /* Unreference included scripts */
61462
 
+       scripts = array_get_modifiable(&actx->included_scripts, &count);
61463
 
+       for ( i = 0; i < count; i++ ) {
61464
 
+               sieve_script_unref(&scripts[i]);
61465
 
+       }       
61466
 
+
61467
 
+       /* Unreference variable scopes */
61468
 
+       if ( actx->global_vars != NULL )
61469
 
+               sieve_variable_scope_unref(&actx->global_vars);
61470
 
+}
61471
 
+
61472
 
+static const struct sieve_ast_extension include_ast_extension = {
61473
 
+       &include_extension,
61474
 
+       ext_include_ast_free
61475
 
+};
61476
 
+
61477
 
+struct ext_include_ast_context *ext_include_create_ast_context
61478
 
+(struct sieve_ast *ast, struct sieve_ast *parent)
61479
 
+{
61480
 
+       struct ext_include_ast_context *actx;
61481
 
+
61482
 
+       pool_t pool = sieve_ast_pool(ast);
61483
 
+       actx = p_new(pool, struct ext_include_ast_context, 1);
61484
 
+       p_array_init(&actx->included_scripts, pool, 32);
61485
 
+
61486
 
+       if ( parent != NULL ) {
61487
 
+               struct ext_include_ast_context *parent_ctx =
61488
 
+                       (struct ext_include_ast_context *)
61489
 
+                               sieve_ast_extension_get_context(parent, &include_extension);
61490
 
+               actx->global_vars = parent_ctx->global_vars;
61491
 
+
61492
 
+               i_assert( actx->global_vars != NULL );
61493
 
+
61494
 
+               sieve_variable_scope_ref(actx->global_vars);
61495
 
+       } else
61496
 
+               actx->global_vars = sieve_variable_scope_create(&include_extension);                    
61497
 
+
61498
 
+       sieve_ast_extension_register(ast, &include_ast_extension, (void *) actx);
61499
 
+
61500
 
+       return actx;
61501
 
+}
61502
 
+
61503
 
+struct ext_include_ast_context *ext_include_get_ast_context
61504
 
+(struct sieve_ast *ast)
61505
 
+{
61506
 
+       struct ext_include_ast_context *actx = (struct ext_include_ast_context *)
61507
 
+               sieve_ast_extension_get_context(ast, &include_extension);
61508
 
+
61509
 
+       if ( actx != NULL ) return actx;
61510
 
+
61511
 
+       return ext_include_create_ast_context(ast, NULL);
61512
 
+}
61513
 
+
61514
 
+void ext_include_ast_link_included_script
61515
 
+(struct sieve_ast *ast, struct sieve_script *script) 
61516
 
+{
61517
 
+       struct ext_include_ast_context *actx = ext_include_get_ast_context(ast);
61518
 
+
61519
 
+       array_append(&actx->included_scripts, &script, 1);
61520
 
+}
61521
 
+
61522
 
+/* 
61523
 
+ * Generator context management 
61524
 
+ */
61525
 
61526
 
+static struct ext_include_generator_context *
61527
 
+       ext_include_create_generator_context
61528
 
+(struct sieve_generator *gentr, struct ext_include_generator_context *parent, 
61529
 
+       struct sieve_script *script)
61530
 
+{      
61531
 
+       struct ext_include_generator_context *ctx;
61532
 
+
61533
 
+       pool_t pool = sieve_generator_pool(gentr);
61534
 
+       ctx = p_new(pool, struct ext_include_generator_context, 1);
61535
 
+       ctx->parent = parent;
61536
 
+       ctx->script = script;
61537
 
+       if ( parent == NULL ) {
61538
 
+               ctx->nesting_level = 0;
61539
 
+       } else {
61540
 
+               ctx->nesting_level = parent->nesting_level + 1;
61541
 
+       }
61542
 
+       
61543
 
+       return ctx;
61544
 
+}
61545
 
+
61546
 
+static inline struct ext_include_generator_context *
61547
 
+       ext_include_get_generator_context
61548
 
+(struct sieve_generator *gentr)
61549
 
+{
61550
 
+       return (struct ext_include_generator_context *)
61551
 
+               sieve_generator_extension_get_context(gentr, &include_extension);
61552
 
+}
61553
 
+
61554
 
+static inline void ext_include_initialize_generator_context
61555
 
+(struct sieve_generator *gentr, struct ext_include_generator_context *parent, 
61556
 
+       struct sieve_script *script)
61557
 
+{
61558
 
+       sieve_generator_extension_set_context(gentr, &include_extension,
61559
 
+               ext_include_create_generator_context(gentr, parent, script));
61560
 
+}
61561
 
+
61562
 
+void ext_include_register_generator_context
61563
 
+(const struct sieve_codegen_env *cgenv)
61564
 
+{
61565
 
+       struct ext_include_generator_context *ctx = 
61566
 
+               ext_include_get_generator_context(cgenv->gentr);
61567
 
+       
61568
 
+       /* Initialize generator context if necessary */
61569
 
+       if ( ctx == NULL ) {
61570
 
+               ctx = ext_include_create_generator_context(
61571
 
+                       cgenv->gentr, NULL, cgenv->script);
61572
 
+               
61573
 
+               sieve_generator_extension_set_context
61574
 
+                       (cgenv->gentr, &include_extension, (void *) ctx);               
61575
 
+       }
61576
 
+
61577
 
+       /* Initialize ast context if necessary */
61578
 
+       (void)ext_include_get_ast_context(cgenv->ast);
61579
 
+       (void)ext_include_binary_init(cgenv->sbin, cgenv->ast);
61580
 
+}
61581
 
+
61582
 
+/*
61583
 
+ * Runtime initialization
61584
 
+ */
61585
 
+
61586
 
+static void ext_include_runtime_init
61587
 
+    (const struct sieve_runtime_env *renv, void *context)
61588
 
+{
61589
 
+       struct ext_include_interpreter_context *ctx = 
61590
 
+               (struct ext_include_interpreter_context *) context;
61591
 
+
61592
 
+       if ( ctx->parent == NULL ) {
61593
 
+               ctx->global = p_new(ctx->pool, struct ext_include_interpreter_global, 1);
61594
 
+               ctx->global->variables = sieve_variable_storage_create
61595
 
+                       (ctx->pool, ext_include_binary_get_global_scope(renv->sbin), 0);
61596
 
+               p_array_init(&ctx->global->included_scripts, ctx->pool, 10);
61597
 
+       } else {
61598
 
+               ctx->global = ctx->parent->global;
61599
 
+       }
61600
 
+
61601
 
+       sieve_ext_variables_set_storage
61602
 
+               (renv->interp, ctx->global->variables, &include_extension);     
61603
 
+}
61604
 
+
61605
 
+static struct sieve_interpreter_extension include_interpreter_extension = {
61606
 
+       &include_extension,
61607
 
+       ext_include_runtime_init,
61608
 
+       NULL,
61609
 
+};
61610
 
+
61611
 
+/* 
61612
 
+ * Interpreter context management 
61613
 
+ */
61614
 
+
61615
 
+static struct ext_include_interpreter_context *
61616
 
+       ext_include_interpreter_context_create
61617
 
+(struct sieve_interpreter *interp, 
61618
 
+       struct ext_include_interpreter_context *parent, 
61619
 
+       struct sieve_script *script, const struct ext_include_script_info *sinfo)
61620
 
+{      
61621
 
+       struct ext_include_interpreter_context *ctx;
61622
 
+
61623
 
+       pool_t pool = sieve_interpreter_pool(interp);
61624
 
+       ctx = p_new(pool, struct ext_include_interpreter_context, 1);
61625
 
+       ctx->pool = pool;
61626
 
+       ctx->parent = parent;
61627
 
+       ctx->interp = interp;
61628
 
+       ctx->script = script;
61629
 
+       ctx->script_info = sinfo;
61630
 
+
61631
 
+       if ( parent == NULL ) {
61632
 
+               ctx->nesting_level = 0;
61633
 
+       } else {
61634
 
+               ctx->nesting_level = parent->nesting_level + 1;
61635
 
+       }
61636
 
+
61637
 
+       return ctx;
61638
 
+}
61639
 
+
61640
 
+static inline struct ext_include_interpreter_context *
61641
 
+       ext_include_get_interpreter_context
61642
 
+(struct sieve_interpreter *interp)
61643
 
+{
61644
 
+       return (struct ext_include_interpreter_context *)
61645
 
+               sieve_interpreter_extension_get_context(interp, &include_extension);
61646
 
+}
61647
 
+
61648
 
+static inline struct ext_include_interpreter_context *
61649
 
+       ext_include_interpreter_context_init_child
61650
 
+(struct sieve_interpreter *interp, 
61651
 
+       struct ext_include_interpreter_context *parent, 
61652
 
+       struct sieve_script *script, const struct ext_include_script_info *sinfo)
61653
 
+{
61654
 
+       struct ext_include_interpreter_context *ctx = 
61655
 
+               ext_include_interpreter_context_create(interp, parent, script, sinfo);
61656
 
+               
61657
 
+       sieve_interpreter_extension_register
61658
 
+               (interp, &include_interpreter_extension, ctx);
61659
 
+       
61660
 
+       return ctx;
61661
 
+}
61662
 
+
61663
 
+void ext_include_interpreter_context_init
61664
 
+(struct sieve_interpreter *interp)
61665
 
+{
61666
 
+       struct ext_include_interpreter_context *ctx = 
61667
 
+               ext_include_get_interpreter_context(interp);
61668
 
+
61669
 
+       /* Is this is the top-level interpreter ? */    
61670
 
+       if ( ctx == NULL ) {
61671
 
+               struct sieve_script *script;
61672
 
+
61673
 
+               /* Initialize top context */
61674
 
+               script = sieve_interpreter_script(interp);
61675
 
+               ctx = ext_include_interpreter_context_create
61676
 
+                       (interp, NULL, script, NULL);
61677
 
+               
61678
 
+               sieve_interpreter_extension_register
61679
 
+                       (interp, &include_interpreter_extension, (void *) ctx);                 
61680
 
+       }
61681
 
+}
61682
 
+
61683
 
+struct sieve_variable_storage *ext_include_interpreter_get_global_variables
61684
 
+(struct sieve_interpreter *interp)
61685
 
+{
61686
 
+       struct ext_include_interpreter_context *ctx =
61687
 
+               ext_include_get_interpreter_context(interp);
61688
 
+               
61689
 
+       return ctx->global->variables;
61690
 
+}
61691
 
+
61692
 
+/* 
61693
 
+ * Including a script during code generation 
61694
 
+ */
61695
 
+
61696
 
+bool ext_include_generate_include
61697
 
+(const struct sieve_codegen_env *cgenv, struct sieve_command_context *cmd,
61698
 
+       enum ext_include_script_location location, struct sieve_script *script, 
61699
 
+       const struct ext_include_script_info **included_r, bool once)
61700
 
+{
61701
 
+       bool result = TRUE;
61702
 
+       struct sieve_ast *ast;
61703
 
+       struct sieve_binary *sbin = cgenv->sbin;
61704
 
+       struct sieve_generator *gentr = cgenv->gentr;
61705
 
+       struct ext_include_binary_context *binctx;
61706
 
+       struct sieve_generator *subgentr;
61707
 
+       struct ext_include_generator_context *ctx =
61708
 
+               ext_include_get_generator_context(gentr);
61709
 
+       struct ext_include_generator_context *pctx;
61710
 
+       struct sieve_error_handler *ehandler = sieve_generator_error_handler(gentr);
61711
 
+       const struct ext_include_script_info *included;
61712
 
+               
61713
 
+       *included_r = NULL;
61714
 
+
61715
 
+       /* Just to be sure: do not include more scripts when errors have occured 
61716
 
+        * already. 
61717
 
+        */
61718
 
+       if ( sieve_get_errors(ehandler) > 0 )
61719
 
+               return FALSE;
61720
 
+               
61721
 
+       /* Limit nesting level */
61722
 
+       if ( ctx->nesting_level >= EXT_INCLUDE_MAX_NESTING_LEVEL ) {
61723
 
+               sieve_command_generate_error
61724
 
+                       (gentr, cmd, "cannot nest includes deeper than %d levels",
61725
 
+                               EXT_INCLUDE_MAX_NESTING_LEVEL);
61726
 
+               return FALSE;
61727
 
+       }
61728
 
+       
61729
 
+       /* Check for circular include */
61730
 
+       if ( !once ) {
61731
 
+               pctx = ctx;
61732
 
+               while ( pctx != NULL ) {
61733
 
+                       if ( sieve_script_equals(pctx->script, script) ) {
61734
 
+                               sieve_command_generate_error(gentr, cmd, "circular include");
61735
 
+                               
61736
 
+                               return FALSE;
61737
 
+                       }
61738
 
+               
61739
 
+                       pctx = pctx->parent;
61740
 
+               }
61741
 
+       }
61742
 
+
61743
 
+       /* Get binary context */
61744
 
+       binctx = ext_include_binary_init(sbin, cgenv->ast);
61745
 
+
61746
 
+       /* Is the script already compiled into the current binary? */
61747
 
+       if ( !ext_include_binary_script_is_included(binctx, script, &included) )        
61748
 
+       {       
61749
 
+               unsigned int inc_block_id, this_block_id;
61750
 
+               const char *script_name = sieve_script_name(script);
61751
 
+
61752
 
+               /* Check whether include limit is exceeded */
61753
 
+               if ( ext_include_binary_script_get_count(binctx) >= 
61754
 
+                       EXT_INCLUDE_MAX_INCLUDES ) {
61755
 
+                       sieve_command_generate_error(gentr, cmd, 
61756
 
+                               "failed to include script '%s': no more than %u includes allowed", 
61757
 
+                               str_sanitize(script_name, 80), EXT_INCLUDE_MAX_INCLUDES);
61758
 
+                       return FALSE;                   
61759
 
+               }
61760
 
+               
61761
 
+               /* No, allocate a new block in the binary and mark the script as included.
61762
 
+                */
61763
 
+               inc_block_id = sieve_binary_block_create(sbin);
61764
 
+               included = ext_include_binary_script_include
61765
 
+                       (binctx, script, location, inc_block_id);
61766
 
+
61767
 
+               /* Parse */
61768
 
+               if ( (ast = sieve_parse(script, ehandler)) == NULL ) {
61769
 
+                       sieve_command_generate_error(gentr, cmd, 
61770
 
+                               "failed to parse included script '%s'", str_sanitize(script_name, 80));
61771
 
+                       return FALSE;
61772
 
+               }
61773
 
+               
61774
 
+               /* Included scripts inherit global variable scope */
61775
 
+               (void)ext_include_create_ast_context(ast, cmd->ast_node->ast);
61776
 
+
61777
 
+               /* Validate */
61778
 
+               if ( !sieve_validate(ast, ehandler) ) {
61779
 
+                       sieve_command_generate_error(gentr, cmd, 
61780
 
+                               "failed to validate included script '%s'", str_sanitize(script_name, 80));
61781
 
+                       sieve_ast_unref(&ast);
61782
 
+                       return FALSE;
61783
 
+               }
61784
 
+
61785
 
+               /* Generate 
61786
 
+                *
61787
 
+                * FIXME: It might not be a good idea to recurse code generation for 
61788
 
+                * included scripts.
61789
 
+                */
61790
 
+               if ( sieve_binary_block_set_active(sbin, inc_block_id, &this_block_id) ) {
61791
 
+                       subgentr = sieve_generator_create(ast, ehandler);                       
61792
 
+                       ext_include_initialize_generator_context(subgentr, ctx, script);
61793
 
+                               
61794
 
+                       if ( !sieve_generator_run(subgentr, &sbin) ) {
61795
 
+                               sieve_command_generate_error(gentr, cmd, 
61796
 
+                                       "failed to generate code for included script '%s'", 
61797
 
+                                       str_sanitize(script_name, 80));
61798
 
+                               result = FALSE;
61799
 
+                       }
61800
 
+                       
61801
 
+                       if ( sbin != NULL )             
61802
 
+                               (void) sieve_binary_block_set_active(sbin, this_block_id, NULL);        
61803
 
+                       sieve_generator_free(&subgentr);
61804
 
+               } else {
61805
 
+                       sieve_sys_error("include: failed to activate binary  block %d for "
61806
 
+                               "generating code for the included script", inc_block_id);
61807
 
+                       result = FALSE;
61808
 
+               }
61809
 
+               
61810
 
+               /* Cleanup */
61811
 
+               sieve_ast_unref(&ast);          
61812
 
+       } 
61813
 
+
61814
 
+       if ( result ) *included_r = included;
61815
 
+       
61816
 
+       return result;
61817
 
+}
61818
 
+
61819
 
+/* 
61820
 
+ * Executing an included script during interpretation 
61821
 
+ */
61822
 
+
61823
 
+static int ext_include_runtime_check_circular
61824
 
+(struct ext_include_interpreter_context *ctx,
61825
 
+       const struct ext_include_script_info *include)
61826
 
+{
61827
 
+       struct ext_include_interpreter_context *pctx;
61828
 
+
61829
 
+       pctx = ctx;
61830
 
+       while ( pctx != NULL ) {
61831
 
+
61832
 
+               if ( sieve_script_equals(include->script, pctx->script) )
61833
 
+                       return TRUE;
61834
 
+
61835
 
+               pctx = pctx->parent;
61836
 
+       }
61837
 
+
61838
 
+       return FALSE;
61839
 
+}
61840
 
+
61841
 
+static bool ext_include_runtime_include_mark
61842
 
+(struct ext_include_interpreter_context *ctx,
61843
 
+       const struct ext_include_script_info *include, bool once)
61844
 
+{
61845
 
+       struct sieve_script *const *includes;
61846
 
+       unsigned int count, i;
61847
 
+       
61848
 
+       includes = array_get(&ctx->global->included_scripts, &count);
61849
 
+       for ( i = 0; i < count; i++ )   {
61850
 
+               if ( sieve_script_equals(include->script, includes[i]) )
61851
 
+                       return ( !once );
61852
 
+       }
61853
 
+       
61854
 
+       array_append(&ctx->global->included_scripts, &include->script, 1);
61855
 
+
61856
 
+       return TRUE;
61857
 
+}
61858
 
+
61859
 
+int ext_include_execute_include
61860
 
+(const struct sieve_runtime_env *renv, unsigned int include_id, bool once)
61861
 
+{
61862
 
+       int result = SIEVE_EXEC_OK;
61863
 
+       struct ext_include_interpreter_context *ctx;
61864
 
+       const struct ext_include_script_info *included;
61865
 
+       struct ext_include_binary_context *binctx = 
61866
 
+               ext_include_binary_get_context(renv->sbin);
61867
 
+
61868
 
+       /* Check for invalid include id (== corrupt binary) */
61869
 
+       included = ext_include_binary_script_get_included(binctx, include_id);
61870
 
+       if ( included == NULL ) {
61871
 
+               sieve_runtime_trace_error(renv, "invalid include id: %d", include_id);
61872
 
+               return SIEVE_EXEC_BIN_CORRUPT;
61873
 
+       }
61874
 
+
61875
 
+       ctx = ext_include_get_interpreter_context(renv->interp);
61876
 
+       
61877
 
+       sieve_runtime_trace(renv, 
61878
 
+               "INCLUDE command (script: %s, id: %d block: %d) START::", 
61879
 
+               sieve_script_name(included->script), include_id, included->block_id);
61880
 
+
61881
 
+       /* If :once modifier is specified, check for duplicate include */
61882
 
+       if ( !ext_include_runtime_include_mark(ctx, included, once) ) {
61883
 
+               /* skip */
61884
 
+
61885
 
+               sieve_runtime_trace(renv, 
61886
 
+                       "INCLUDE command (block: %d) SKIPPED ::", included->block_id);
61887
 
+               return result;
61888
 
+       }
61889
 
+
61890
 
+       /* Check circular include during interpretation as well. 
61891
 
+        * Let's not trust binaries.
61892
 
+        */
61893
 
+       if ( ext_include_runtime_check_circular(ctx, included) ) {
61894
 
+               sieve_runtime_trace_error(renv, 
61895
 
+                       "circular include for script: %s [%d]", 
61896
 
+                       sieve_script_name(included->script), included->block_id);
61897
 
+
61898
 
+               /* Situation has no valid way to emerge at runtime */
61899
 
+               return SIEVE_EXEC_BIN_CORRUPT; 
61900
 
+       }
61901
 
+
61902
 
+       if ( ctx->parent == NULL ) {
61903
 
+               struct ext_include_interpreter_context *curctx = NULL;
61904
 
+               struct sieve_error_handler *ehandler = 
61905
 
+                       sieve_interpreter_get_error_handler(renv->interp);
61906
 
+               struct sieve_interpreter *subinterp;
61907
 
+               unsigned int this_block_id;
61908
 
+               bool interrupted = FALSE;       
61909
 
+
61910
 
+               /* We are the top-level interpreter instance */ 
61911
 
+               
61912
 
+               /* Activate block for included script */
61913
 
+               if ( !sieve_binary_block_set_active
61914
 
+                       (renv->sbin, included->block_id, &this_block_id) ) {                    
61915
 
+                       sieve_runtime_trace_error(renv, "invalid block id: %d", 
61916
 
+                               included->block_id);
61917
 
+                       result = SIEVE_EXEC_BIN_CORRUPT;
61918
 
+               }
61919
 
+
61920
 
+               if ( result == SIEVE_EXEC_OK ) {
61921
 
+                       /* Create interpreter for top-level included script
61922
 
+                        * (first sub-interpreter) 
61923
 
+                        */
61924
 
+                       subinterp = sieve_interpreter_create(renv->sbin, ehandler);
61925
 
+
61926
 
+                       if ( subinterp != NULL ) {                      
61927
 
+                               curctx = ext_include_interpreter_context_init_child
61928
 
+                                       (subinterp, ctx, included->script, included);
61929
 
+
61930
 
+                               /* Activate and start the top-level included script */
61931
 
+                               result = ( sieve_interpreter_start
61932
 
+                                       (subinterp, renv->msgdata, renv->scriptenv, renv->result, 
61933
 
+                                               &interrupted) == 1 );
61934
 
+                       } else
61935
 
+                               result = SIEVE_EXEC_BIN_CORRUPT;
61936
 
+               }
61937
 
+               
61938
 
+               /* Included scripts can have includes of their own. This is not implemented
61939
 
+                * recursively. Rather, the sub-interpreter interrupts and defers the 
61940
 
+                * include to the top-level interpreter, which is here.
61941
 
+                */
61942
 
+               if ( result == SIEVE_EXEC_OK && interrupted && !curctx->returned ) {
61943
 
+                       while ( result == SIEVE_EXEC_OK ) {
61944
 
+
61945
 
+                               if ( ( (interrupted && curctx->returned) || (!interrupted) ) && 
61946
 
+                                       curctx->parent != NULL ) {
61947
 
+                                       
61948
 
+                                       /* Sub-interpreter ended or executed return */
61949
 
+                                       
61950
 
+                                       sieve_runtime_trace(renv, "INCLUDE command (block: %d) END ::", 
61951
 
+                                               curctx->script_info->block_id);
61952
 
+
61953
 
+                                       /* Ascend interpreter stack */
61954
 
+                                       curctx = curctx->parent;
61955
 
+                                       sieve_interpreter_free(&subinterp);
61956
 
+                                       
61957
 
+                                       /* This is the top-most sub-interpreter, bail out */
61958
 
+                                       if ( curctx->parent == NULL ) break;
61959
 
+                                       
61960
 
+                                       /* Reactivate parent */
61961
 
+                                       (void) sieve_binary_block_set_active
61962
 
+                                               (renv->sbin, curctx->script_info->block_id, NULL);
61963
 
+                                       subinterp = curctx->interp;     
61964
 
+                                       
61965
 
+                                       /* Continue parent */
61966
 
+                                       curctx->include = NULL;
61967
 
+                                       curctx->returned = FALSE;
61968
 
+
61969
 
+                                       result = ( sieve_interpreter_continue(subinterp, &interrupted) == 1 );
61970
 
+                               } else {
61971
 
+                                       if ( curctx->include != NULL ) {
61972
 
+
61973
 
+                                               /* Sub-include requested */
61974
 
+                                                                                                                       
61975
 
+                                               /* Activate the sub-include's block */
61976
 
+                                               if ( !sieve_binary_block_set_active
61977
 
+                                                       (renv->sbin, curctx->include->block_id, NULL) ) {
61978
 
+                                                       sieve_runtime_trace_error(renv, "invalid block id: %d", 
61979
 
+                                                               curctx->include->block_id);
61980
 
+                                                       result = SIEVE_EXEC_BIN_CORRUPT;
61981
 
+                                               }
61982
 
+                               
61983
 
+                                               if ( result == SIEVE_EXEC_OK ) {
61984
 
+                                                       /* Create sub-interpreter */
61985
 
+                                                       subinterp = sieve_interpreter_create(renv->sbin, ehandler);                     
61986
 
+
61987
 
+                                                       if ( subinterp != NULL ) {
61988
 
+                                                               curctx = ext_include_interpreter_context_init_child
61989
 
+                                                                       (subinterp, curctx, curctx->include->script, 
61990
 
+                                                                               curctx->include);
61991
 
+
61992
 
+                                                               /* Start the sub-include's interpreter */
61993
 
+                                                               curctx->include = NULL;
61994
 
+                                                               curctx->returned = FALSE;
61995
 
+                                                               result = ( sieve_interpreter_start
61996
 
+                                                                       (subinterp, renv->msgdata, renv->scriptenv, renv->result, 
61997
 
+                                                                               &interrupted) == 1 );                   
61998
 
+                                                       } else
61999
 
+                                                               result = SIEVE_EXEC_BIN_CORRUPT;
62000
 
+                                               }
62001
 
+                                       } else {
62002
 
+                                               /* Sub-interpreter was interrupted outside this extension, probably
62003
 
+                                                * stop command was executed. Generate an interrupt ourselves, 
62004
 
+                                                * ending all script execution.
62005
 
+                                                */
62006
 
+                                               sieve_interpreter_interrupt(renv->interp);
62007
 
+                                               break;
62008
 
+                                       }
62009
 
+                               }
62010
 
+                       }
62011
 
+               } else 
62012
 
+                       sieve_runtime_trace(renv, "INCLUDE command (block: %d) END ::", 
62013
 
+                               curctx->script_info->block_id);
62014
 
+
62015
 
+               /* Free any sub-interpreters that might still be active */
62016
 
+               while ( curctx != NULL && curctx->parent != NULL ) {
62017
 
+                       struct ext_include_interpreter_context *nextctx = curctx->parent;
62018
 
+                       struct sieve_interpreter *killed_interp = curctx->interp;
62019
 
+
62020
 
+                       /* This kills curctx too */
62021
 
+                       sieve_interpreter_free(&killed_interp);
62022
 
+
62023
 
+                       /* Luckily we recorded the parent earlier */
62024
 
+                       curctx = nextctx;
62025
 
+               }
62026
 
+
62027
 
+               /* Return to our own block */
62028
 
+               (void) sieve_binary_block_set_active(renv->sbin, this_block_id, NULL);  
62029
 
+       } else {
62030
 
+               /* We are an included script already, defer inclusion to main interpreter */
62031
 
+
62032
 
+               ctx->include = included;
62033
 
+               sieve_interpreter_interrupt(renv->interp);
62034
 
+       }
62035
 
+       
62036
 
+       return result;
62037
 
+}
62038
 
+
62039
 
+void ext_include_execute_return(const struct sieve_runtime_env *renv)
62040
 
+{
62041
 
+       struct ext_include_interpreter_context *ctx =
62042
 
+               ext_include_get_interpreter_context(renv->interp);
62043
 
+       
62044
 
+       ctx->returned = TRUE;
62045
 
+       sieve_interpreter_interrupt(renv->interp);      
62046
 
+}
62047
 
+       
62048
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/include/ext-include-common.h dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/include/ext-include-common.h
62049
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/include/ext-include-common.h   1970-01-01 01:00:00.000000000 +0100
62050
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/include/ext-include-common.h    2009-08-08 14:57:37.000000000 +0200
62051
 
@@ -0,0 +1,128 @@
62052
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
62053
 
+ */
62054
 
+
62055
 
+#ifndef __EXT_INCLUDE_COMMON_H
62056
 
+#define __EXT_INCLUDE_COMMON_H
62057
 
+
62058
 
+#include "lib.h"
62059
 
+#include "hash.h"
62060
 
+
62061
 
+#include "sieve-common.h"
62062
 
+
62063
 
+/* 
62064
 
+ * Forward declarations
62065
 
+ */
62066
 
+
62067
 
+struct ext_include_script_info;
62068
 
+struct ext_include_binary_context;
62069
 
+
62070
 
+/* 
62071
 
+ * Types 
62072
 
+ */
62073
 
+
62074
 
+enum ext_include_script_location { 
62075
 
+       EXT_INCLUDE_LOCATION_PERSONAL, 
62076
 
+       EXT_INCLUDE_LOCATION_GLOBAL,
62077
 
+       EXT_INCLUDE_LOCATION_INVALID 
62078
 
+};
62079
 
+
62080
 
+static inline const char *ext_include_script_location_name
62081
 
+(enum ext_include_script_location location)
62082
 
+{
62083
 
+       switch ( location ) {
62084
 
+       case EXT_INCLUDE_LOCATION_PERSONAL:
62085
 
+               return "personal";
62086
 
+
62087
 
+       case EXT_INCLUDE_LOCATION_GLOBAL:
62088
 
+               return "global";
62089
 
+
62090
 
+       default:
62091
 
+               break;
62092
 
+       }
62093
 
+
62094
 
+       return "[INVALUD LOCATION]";
62095
 
+}
62096
 
+
62097
 
+
62098
 
+/* 
62099
 
+ * Extension 
62100
 
+ */
62101
 
+
62102
 
+extern const struct sieve_extension include_extension;
62103
 
+extern const struct sieve_binary_extension include_binary_ext;
62104
 
+
62105
 
+/* 
62106
 
+ * Commands 
62107
 
+ */
62108
 
+
62109
 
+extern const struct sieve_command cmd_include;
62110
 
+extern const struct sieve_command cmd_return;
62111
 
+extern const struct sieve_command cmd_global;
62112
 
+
62113
 
+/* DEPRICATED */ 
62114
 
+extern const struct sieve_command cmd_import;
62115
 
+extern const struct sieve_command cmd_export;
62116
 
+
62117
 
+/*
62118
 
+ * Operations
62119
 
+ */
62120
 
62121
 
+enum ext_include_opcode {
62122
 
+       EXT_INCLUDE_OPERATION_INCLUDE,
62123
 
+       EXT_INCLUDE_OPERATION_RETURN,
62124
 
+       EXT_INCLUDE_OPERATION_GLOBAL
62125
 
+};
62126
 
62127
 
+extern const struct sieve_operation include_operation;
62128
 
+extern const struct sieve_operation return_operation;
62129
 
+extern const struct sieve_operation global_operation;
62130
 
+
62131
 
+/* 
62132
 
+ * Script access 
62133
 
+ */
62134
 
+
62135
 
+const char *ext_include_get_script_directory
62136
 
+       (enum ext_include_script_location location, const char *script_name);
62137
 
+
62138
 
+/* 
62139
 
+ * Context 
62140
 
+ */
62141
 
62142
 
+/* AST Context */
62143
 
+
62144
 
+struct ext_include_ast_context {
62145
 
+    struct sieve_variable_scope *global_vars;
62146
 
+
62147
 
+    ARRAY_DEFINE(included_scripts, struct sieve_script *);
62148
 
+};
62149
 
+
62150
 
+struct ext_include_ast_context *ext_include_create_ast_context
62151
 
+       (struct sieve_ast *ast, struct sieve_ast *parent);
62152
 
+struct ext_include_ast_context *ext_include_get_ast_context
62153
 
+       (struct sieve_ast *ast);
62154
 
+
62155
 
+void ext_include_ast_link_included_script
62156
 
+       (struct sieve_ast *ast, struct sieve_script *script);
62157
 
+
62158
 
+/* Generator context */
62159
 
+
62160
 
+void ext_include_register_generator_context
62161
 
+       (const struct sieve_codegen_env *cgenv);
62162
 
+
62163
 
+bool ext_include_generate_include
62164
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_command_context *cmd,
62165
 
+               enum ext_include_script_location location, struct sieve_script *script, 
62166
 
+               const struct ext_include_script_info **included_r, bool once);
62167
 
+
62168
 
+/* Interpreter context */
62169
 
+
62170
 
+void ext_include_interpreter_context_init(struct sieve_interpreter *interp);
62171
 
+
62172
 
+int ext_include_execute_include
62173
 
+       (const struct sieve_runtime_env *renv, unsigned int block_id, bool once);
62174
 
+void ext_include_execute_return(const struct sieve_runtime_env *renv);
62175
 
+
62176
 
+struct sieve_variable_storage *ext_include_interpreter_get_global_variables
62177
 
+       (struct sieve_interpreter *interp);
62178
 
+
62179
 
+#endif /* __EXT_INCLUDE_COMMON_H */
62180
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/include/ext-include-limits.h dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/include/ext-include-limits.h
62181
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/include/ext-include-limits.h   1970-01-01 01:00:00.000000000 +0100
62182
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/include/ext-include-limits.h    2009-01-06 00:15:52.000000000 +0100
62183
 
@@ -0,0 +1,12 @@
62184
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
62185
 
+ */
62186
 
+
62187
 
+#ifndef __EXT_INCLUDE_LIMITS_H
62188
 
+#define __EXT_INCLUDE_LIMITS_H
62189
 
+
62190
 
+#include "sieve-common.h"
62191
 
+
62192
 
+#define EXT_INCLUDE_MAX_NESTING_LEVEL 10
62193
 
+#define EXT_INCLUDE_MAX_INCLUDES      255
62194
 
+
62195
 
+#endif /* __EXT_INCLUDE_LIMITS_H */
62196
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/include/ext-include-variables.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/include/ext-include-variables.c
62197
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/include/ext-include-variables.c        1970-01-01 01:00:00.000000000 +0100
62198
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/include/ext-include-variables.c 2009-07-29 01:23:49.000000000 +0200
62199
 
@@ -0,0 +1,148 @@
62200
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
62201
 
+ */
62202
 
+
62203
 
+#include "sieve-common.h"
62204
 
+#include "sieve-error.h"
62205
 
+#include "sieve-script.h"
62206
 
+#include "sieve-ast.h"
62207
 
+#include "sieve-binary.h"
62208
 
+#include "sieve-commands.h"
62209
 
+#include "sieve-validator.h"
62210
 
+#include "sieve-generator.h"
62211
 
+#include "sieve-interpreter.h"
62212
 
+#include "sieve-dump.h"
62213
 
+
62214
 
+#include "sieve-ext-variables.h"
62215
 
+
62216
 
+#include "ext-include-common.h"
62217
 
+#include "ext-include-binary.h"
62218
 
+#include "ext-include-variables.h"
62219
 
+
62220
 
+/* 
62221
 
+ * Variable import-export
62222
 
+ */
62223
 
62224
 
+struct sieve_variable *ext_include_variable_import_global
62225
 
+(struct sieve_validator *valdtr, struct sieve_command_context *cmd, 
62226
 
+       const char *variable)
62227
 
+{
62228
 
+       struct sieve_ast *ast = cmd->ast_node->ast;
62229
 
+       struct ext_include_ast_context *ctx = ext_include_get_ast_context(ast);
62230
 
+       struct sieve_variable_scope *main_scope;
62231
 
+       struct sieve_variable *var = NULL;
62232
 
+
62233
 
+       /* Sanity safeguard */  
62234
 
+       i_assert ( ctx->global_vars != NULL );
62235
 
+
62236
 
+       /* Get/Declare the variable in the global scope */
62237
 
+       var = sieve_variable_scope_get_variable(ctx->global_vars, variable, TRUE);
62238
 
+
62239
 
+       /* Check whether scope is over its size limit */
62240
 
+       if ( var == NULL ) {
62241
 
+               sieve_command_validate_error(valdtr, cmd,
62242
 
+                       "declaration of new global variable '%s' exceeds the limit "
62243
 
+                       "(max variables: %u)", 
62244
 
+                       variable, SIEVE_VARIABLES_MAX_SCOPE_SIZE);
62245
 
+       }
62246
 
+       
62247
 
+       /* Import the global variable into the local script scope */
62248
 
+       main_scope = sieve_ext_variables_get_main_scope(valdtr);
62249
 
+       (void)sieve_variable_scope_import(main_scope, var);
62250
 
+
62251
 
+       return var;     
62252
 
+}
62253
 
+
62254
 
+/*
62255
 
+ * Binary symbol table
62256
 
+ */
62257
 
62258
 
+bool ext_include_variables_save
62259
 
+(struct sieve_binary *sbin, struct sieve_variable_scope *global_vars)
62260
 
+{
62261
 
+       unsigned int count = sieve_variable_scope_size(global_vars);
62262
 
+
62263
 
+       sieve_binary_emit_unsigned(sbin, count);
62264
 
+
62265
 
+       if ( count > 0 ) {
62266
 
+               unsigned int size, i;
62267
 
+               struct sieve_variable *const *vars = 
62268
 
+                       sieve_variable_scope_get_variables(global_vars, &size);
62269
 
+
62270
 
+               for ( i = 0; i < size; i++ ) {
62271
 
+                       sieve_binary_emit_cstring(sbin, vars[i]->identifier);
62272
 
+               }
62273
 
+       }
62274
 
+
62275
 
+       return TRUE;
62276
 
+}
62277
 
+
62278
 
+bool ext_include_variables_load
62279
 
+(struct sieve_binary *sbin, sieve_size_t *offset, unsigned int block,
62280
 
+       struct sieve_variable_scope **global_vars_r)
62281
 
+{
62282
 
+       unsigned int count = 0;
62283
 
+       unsigned int i;
62284
 
+       pool_t pool;
62285
 
+
62286
 
+       /* Sanity assert */
62287
 
+       i_assert( *global_vars_r == NULL );
62288
 
+
62289
 
+       if ( !sieve_binary_read_unsigned(sbin, offset, &count) ) {
62290
 
+               sieve_sys_error("include: failed to read global variables count "
62291
 
+                       "from dependency block %d of binary %s", block, sieve_binary_path(sbin));
62292
 
+               return FALSE;
62293
 
+       }
62294
 
+
62295
 
+       if ( count > SIEVE_VARIABLES_MAX_SCOPE_SIZE ) {
62296
 
+               sieve_sys_error("include: global variable scope size of binary %s "
62297
 
+                       "exceeds the limit (%u > %u)", sieve_binary_path(sbin),
62298
 
+                       count, SIEVE_VARIABLES_MAX_SCOPE_SIZE );
62299
 
+               return FALSE;
62300
 
+       }
62301
 
+
62302
 
+       *global_vars_r = sieve_variable_scope_create(&include_extension);
62303
 
+       pool = sieve_variable_scope_pool(*global_vars_r);
62304
 
+
62305
 
+       /* Read global variable scope */
62306
 
+       for ( i = 0; i < count; i++ ) {
62307
 
+               struct sieve_variable *var;
62308
 
+               string_t *identifier;
62309
 
+
62310
 
+               if ( !sieve_binary_read_string(sbin, offset, &identifier) ) {
62311
 
+                       /* Binary is corrupt, recompile */
62312
 
+                       sieve_sys_error("include: failed to read global variable specification "
62313
 
+                               "from dependency block %d of binary %s", block, sieve_binary_path(sbin));
62314
 
+                       return FALSE;
62315
 
+               }
62316
 
+               
62317
 
+               var = sieve_variable_scope_declare(*global_vars_r, str_c(identifier));
62318
 
+
62319
 
+               i_assert( var != NULL );
62320
 
+               i_assert( var->index == i );
62321
 
+       }
62322
 
+       
62323
 
+       return TRUE;
62324
 
+}
62325
 
+
62326
 
+bool ext_include_variables_dump
62327
 
+(struct sieve_dumptime_env *denv, struct sieve_variable_scope *global_vars)
62328
 
+{
62329
 
+       unsigned int size;
62330
 
+       struct sieve_variable *const *vars;
62331
 
+
62332
 
+       i_assert(global_vars != NULL);
62333
 
+
62334
 
+       vars = sieve_variable_scope_get_variables(global_vars, &size);
62335
 
+
62336
 
+       if ( size > 0 ) {
62337
 
+               unsigned int i;
62338
 
+
62339
 
+               sieve_binary_dump_sectionf(denv, "Global variables");
62340
 
+       
62341
 
+               for ( i = 0; i < size; i++ ) {
62342
 
+                       sieve_binary_dumpf(denv, "%3d: '%s' \n", i, vars[i]->identifier);
62343
 
+               }       
62344
 
+       }
62345
 
+
62346
 
+       return TRUE;
62347
 
+}
62348
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/include/ext-include-variables.h dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/include/ext-include-variables.h
62349
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/include/ext-include-variables.h        1970-01-01 01:00:00.000000000 +0100
62350
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/include/ext-include-variables.h 2009-04-10 14:54:25.000000000 +0200
62351
 
@@ -0,0 +1,34 @@
62352
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
62353
 
+ */
62354
 
+
62355
 
+#ifndef __EXT_INCLUDE_VARIABLES_H
62356
 
+#define __EXT_INCLUDE_VARIABLES_H
62357
 
+
62358
 
+#include "sieve-common.h"
62359
 
+
62360
 
+#include "sieve-ext-variables.h"
62361
 
+
62362
 
+#include "ext-include-common.h"
62363
 
+
62364
 
+/* 
62365
 
+ * Variable import-export
62366
 
+ */
62367
 
62368
 
+struct sieve_variable *ext_include_variable_import_global
62369
 
+       (struct sieve_validator *valdtr, struct sieve_command_context *cmd, 
62370
 
+               const char *variable);
62371
 
+
62372
 
+/*
62373
 
+ * Binary symbol table
62374
 
+ */
62375
 
+
62376
 
+bool ext_include_variables_save
62377
 
+       (struct sieve_binary *sbin, struct sieve_variable_scope *global_vars);
62378
 
+bool ext_include_variables_load
62379
 
+       (struct sieve_binary *sbin, sieve_size_t *offset, unsigned int block,
62380
 
+               struct sieve_variable_scope **global_vars_r);
62381
 
+bool ext_include_variables_dump
62382
 
+       (struct sieve_dumptime_env *denv, struct sieve_variable_scope *global_vars);
62383
 
+               
62384
 
+#endif /* __EXT_INCLUDE_VARIABLES_H */
62385
 
+
62386
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/include/Makefile.am dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/include/Makefile.am
62387
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/include/Makefile.am    1970-01-01 01:00:00.000000000 +0100
62388
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/include/Makefile.am     2009-04-10 14:32:03.000000000 +0200
62389
 
@@ -0,0 +1,27 @@
62390
 
+noinst_LTLIBRARIES = libsieve_ext_include.la
62391
 
+
62392
 
+AM_CPPFLAGS = \
62393
 
+       -I../../ \
62394
 
+       -I../variables \
62395
 
+       -I$(dovecot_incdir) \
62396
 
+       -I$(dovecot_incdir)/src/lib \
62397
 
+       -I$(dovecot_incdir)/src/lib-mail \
62398
 
+       -I$(dovecot_incdir)/src/lib-storage
62399
 
+
62400
 
+cmds = \
62401
 
+       cmd-include.c \
62402
 
+       cmd-return.c \
62403
 
+       cmd-global.c
62404
 
+
62405
 
+libsieve_ext_include_la_SOURCES = \
62406
 
+       $(cmds) \
62407
 
+       ext-include-common.c \
62408
 
+       ext-include-binary.c \
62409
 
+       ext-include-variables.c \
62410
 
+       ext-include.c
62411
 
+
62412
 
+noinst_HEADERS = \
62413
 
+       ext-include-common.h \
62414
 
+       ext-include-limits.h \
62415
 
+       ext-include-binary.h \
62416
 
+       ext-include-variables.h
62417
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/include/Makefile.in dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/include/Makefile.in
62418
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/include/Makefile.in    1970-01-01 01:00:00.000000000 +0100
62419
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/include/Makefile.in     2009-08-21 00:55:43.000000000 +0200
62420
 
@@ -0,0 +1,482 @@
62421
 
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
62422
 
+# @configure_input@
62423
 
+
62424
 
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
62425
 
+# 2003, 2004, 2005, 2006, 2007, 2008  Free Software Foundation, Inc.
62426
 
+# This Makefile.in is free software; the Free Software Foundation
62427
 
+# gives unlimited permission to copy and/or distribute it,
62428
 
+# with or without modifications, as long as this notice is preserved.
62429
 
+
62430
 
+# This program is distributed in the hope that it will be useful,
62431
 
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
62432
 
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
62433
 
+# PARTICULAR PURPOSE.
62434
 
+
62435
 
+@SET_MAKE@
62436
 
+
62437
 
+
62438
 
+VPATH = @srcdir@
62439
 
+pkgdatadir = $(datadir)/@PACKAGE@
62440
 
+pkglibdir = $(libdir)/@PACKAGE@
62441
 
+pkgincludedir = $(includedir)/@PACKAGE@
62442
 
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
62443
 
+install_sh_DATA = $(install_sh) -c -m 644
62444
 
+install_sh_PROGRAM = $(install_sh) -c
62445
 
+install_sh_SCRIPT = $(install_sh) -c
62446
 
+INSTALL_HEADER = $(INSTALL_DATA)
62447
 
+transform = $(program_transform_name)
62448
 
+NORMAL_INSTALL = :
62449
 
+PRE_INSTALL = :
62450
 
+POST_INSTALL = :
62451
 
+NORMAL_UNINSTALL = :
62452
 
+PRE_UNINSTALL = :
62453
 
+POST_UNINSTALL = :
62454
 
+build_triplet = @build@
62455
 
+host_triplet = @host@
62456
 
+subdir = src/lib-sieve/plugins/include
62457
 
+DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
62458
 
+       $(srcdir)/Makefile.in
62459
 
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
62460
 
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
62461
 
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
62462
 
+       $(ACLOCAL_M4)
62463
 
+mkinstalldirs = $(install_sh) -d
62464
 
+CONFIG_HEADER = $(top_builddir)/dummy-config.h \
62465
 
+       $(top_builddir)/dsieve-config.h
62466
 
+CONFIG_CLEAN_FILES =
62467
 
+LTLIBRARIES = $(noinst_LTLIBRARIES)
62468
 
+libsieve_ext_include_la_LIBADD =
62469
 
+am__objects_1 = cmd-include.lo cmd-return.lo cmd-global.lo
62470
 
+am_libsieve_ext_include_la_OBJECTS = $(am__objects_1) \
62471
 
+       ext-include-common.lo ext-include-binary.lo \
62472
 
+       ext-include-variables.lo ext-include.lo
62473
 
+libsieve_ext_include_la_OBJECTS =  \
62474
 
+       $(am_libsieve_ext_include_la_OBJECTS)
62475
 
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
62476
 
+depcomp = $(SHELL) $(top_srcdir)/depcomp
62477
 
+am__depfiles_maybe = depfiles
62478
 
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
62479
 
+       $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
62480
 
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
62481
 
+       --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
62482
 
+       $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
62483
 
+CCLD = $(CC)
62484
 
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
62485
 
+       --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
62486
 
+       $(LDFLAGS) -o $@
62487
 
+SOURCES = $(libsieve_ext_include_la_SOURCES)
62488
 
+DIST_SOURCES = $(libsieve_ext_include_la_SOURCES)
62489
 
+HEADERS = $(noinst_HEADERS)
62490
 
+ETAGS = etags
62491
 
+CTAGS = ctags
62492
 
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
62493
 
+ACLOCAL = @ACLOCAL@
62494
 
+AMTAR = @AMTAR@
62495
 
+AR = @AR@
62496
 
+AUTOCONF = @AUTOCONF@
62497
 
+AUTOHEADER = @AUTOHEADER@
62498
 
+AUTOMAKE = @AUTOMAKE@
62499
 
+AWK = @AWK@
62500
 
+CC = @CC@
62501
 
+CCDEPMODE = @CCDEPMODE@
62502
 
+CFLAGS = @CFLAGS@
62503
 
+CPP = @CPP@
62504
 
+CPPFLAGS = @CPPFLAGS@
62505
 
+CYGPATH_W = @CYGPATH_W@
62506
 
+DEFS = @DEFS@
62507
 
+DEPDIR = @DEPDIR@
62508
 
+DSYMUTIL = @DSYMUTIL@
62509
 
+DUMPBIN = @DUMPBIN@
62510
 
+ECHO_C = @ECHO_C@
62511
 
+ECHO_N = @ECHO_N@
62512
 
+ECHO_T = @ECHO_T@
62513
 
+EGREP = @EGREP@
62514
 
+EXEEXT = @EXEEXT@
62515
 
+FGREP = @FGREP@
62516
 
+GREP = @GREP@
62517
 
+INSTALL = @INSTALL@
62518
 
+INSTALL_DATA = @INSTALL_DATA@
62519
 
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
62520
 
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
62521
 
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
62522
 
+LD = @LD@
62523
 
+LDFLAGS = @LDFLAGS@
62524
 
+LIBICONV = @LIBICONV@
62525
 
+LIBOBJS = @LIBOBJS@
62526
 
+LIBS = @LIBS@
62527
 
+LIBTOOL = @LIBTOOL@
62528
 
+LIPO = @LIPO@
62529
 
+LN_S = @LN_S@
62530
 
+LTLIBOBJS = @LTLIBOBJS@
62531
 
+MAINT = @MAINT@
62532
 
+MAKEINFO = @MAKEINFO@
62533
 
+MKDIR_P = @MKDIR_P@
62534
 
+MODULE_LIBS = @MODULE_LIBS@
62535
 
+NM = @NM@
62536
 
+NMEDIT = @NMEDIT@
62537
 
+OBJDUMP = @OBJDUMP@
62538
 
+OBJEXT = @OBJEXT@
62539
 
+OTOOL = @OTOOL@
62540
 
+OTOOL64 = @OTOOL64@
62541
 
+PACKAGE = @PACKAGE@
62542
 
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
62543
 
+PACKAGE_NAME = @PACKAGE_NAME@
62544
 
+PACKAGE_STRING = @PACKAGE_STRING@
62545
 
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
62546
 
+PACKAGE_URL = @PACKAGE_URL@
62547
 
+PACKAGE_VERSION = @PACKAGE_VERSION@
62548
 
+PATH_SEPARATOR = @PATH_SEPARATOR@
62549
 
+RAND_LIBS = @RAND_LIBS@
62550
 
+RANLIB = @RANLIB@
62551
 
+SED = @SED@
62552
 
+SET_MAKE = @SET_MAKE@
62553
 
+SHELL = @SHELL@
62554
 
+STORAGE_LIBS = @STORAGE_LIBS@
62555
 
+STRIP = @STRIP@
62556
 
+VERSION = @VERSION@
62557
 
+abs_builddir = @abs_builddir@
62558
 
+abs_srcdir = @abs_srcdir@
62559
 
+abs_top_builddir = @abs_top_builddir@
62560
 
+abs_top_srcdir = @abs_top_srcdir@
62561
 
+ac_ct_CC = @ac_ct_CC@
62562
 
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
62563
 
+am__include = @am__include@
62564
 
+am__leading_dot = @am__leading_dot@
62565
 
+am__quote = @am__quote@
62566
 
+am__tar = @am__tar@
62567
 
+am__untar = @am__untar@
62568
 
+bindir = @bindir@
62569
 
+build = @build@
62570
 
+build_alias = @build_alias@
62571
 
+build_cpu = @build_cpu@
62572
 
+build_os = @build_os@
62573
 
+build_vendor = @build_vendor@
62574
 
+builddir = @builddir@
62575
 
+datadir = @datadir@
62576
 
+datarootdir = @datarootdir@
62577
 
+docdir = @docdir@
62578
 
+dovecot_incdir = @dovecot_incdir@
62579
 
+dovecotdir = @dovecotdir@
62580
 
+dvidir = @dvidir@
62581
 
+exec_prefix = @exec_prefix@
62582
 
+host = @host@
62583
 
+host_alias = @host_alias@
62584
 
+host_cpu = @host_cpu@
62585
 
+host_os = @host_os@
62586
 
+host_vendor = @host_vendor@
62587
 
+htmldir = @htmldir@
62588
 
+includedir = @includedir@
62589
 
+infodir = @infodir@
62590
 
+install_sh = @install_sh@
62591
 
+libdir = @libdir@
62592
 
+libexecdir = @libexecdir@
62593
 
+localedir = @localedir@
62594
 
+localstatedir = @localstatedir@
62595
 
+lt_ECHO = @lt_ECHO@
62596
 
+mandir = @mandir@
62597
 
+mkdir_p = @mkdir_p@
62598
 
+moduledir = @moduledir@
62599
 
+oldincludedir = @oldincludedir@
62600
 
+pdfdir = @pdfdir@
62601
 
+prefix = @prefix@
62602
 
+program_transform_name = @program_transform_name@
62603
 
+psdir = @psdir@
62604
 
+sbindir = @sbindir@
62605
 
+sharedstatedir = @sharedstatedir@
62606
 
+srcdir = @srcdir@
62607
 
+sysconfdir = @sysconfdir@
62608
 
+target_alias = @target_alias@
62609
 
+top_build_prefix = @top_build_prefix@
62610
 
+top_builddir = @top_builddir@
62611
 
+top_srcdir = @top_srcdir@
62612
 
+noinst_LTLIBRARIES = libsieve_ext_include.la
62613
 
+AM_CPPFLAGS = \
62614
 
+       -I../../ \
62615
 
+       -I../variables \
62616
 
+       -I$(dovecot_incdir) \
62617
 
+       -I$(dovecot_incdir)/src/lib \
62618
 
+       -I$(dovecot_incdir)/src/lib-mail \
62619
 
+       -I$(dovecot_incdir)/src/lib-storage
62620
 
+
62621
 
+cmds = \
62622
 
+       cmd-include.c \
62623
 
+       cmd-return.c \
62624
 
+       cmd-global.c
62625
 
+
62626
 
+libsieve_ext_include_la_SOURCES = \
62627
 
+       $(cmds) \
62628
 
+       ext-include-common.c \
62629
 
+       ext-include-binary.c \
62630
 
+       ext-include-variables.c \
62631
 
+       ext-include.c
62632
 
+
62633
 
+noinst_HEADERS = \
62634
 
+       ext-include-common.h \
62635
 
+       ext-include-limits.h \
62636
 
+       ext-include-binary.h \
62637
 
+       ext-include-variables.h
62638
 
+
62639
 
+all: all-am
62640
 
+
62641
 
+.SUFFIXES:
62642
 
+.SUFFIXES: .c .lo .o .obj
62643
 
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
62644
 
+       @for dep in $?; do \
62645
 
+         case '$(am__configure_deps)' in \
62646
 
+           *$$dep*) \
62647
 
+             ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
62648
 
+               && { if test -f $@; then exit 0; else break; fi; }; \
62649
 
+             exit 1;; \
62650
 
+         esac; \
62651
 
+       done; \
62652
 
+       echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign  src/lib-sieve/plugins/include/Makefile'; \
62653
 
+       cd $(top_srcdir) && \
62654
 
+         $(AUTOMAKE) --foreign  src/lib-sieve/plugins/include/Makefile
62655
 
+.PRECIOUS: Makefile
62656
 
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
62657
 
+       @case '$?' in \
62658
 
+         *config.status*) \
62659
 
+           cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
62660
 
+         *) \
62661
 
+           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
62662
 
+           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
62663
 
+       esac;
62664
 
+
62665
 
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
62666
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
62667
 
+
62668
 
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
62669
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
62670
 
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
62671
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
62672
 
+
62673
 
+clean-noinstLTLIBRARIES:
62674
 
+       -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
62675
 
+       @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
62676
 
+         dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
62677
 
+         test "$$dir" != "$$p" || dir=.; \
62678
 
+         echo "rm -f \"$${dir}/so_locations\""; \
62679
 
+         rm -f "$${dir}/so_locations"; \
62680
 
+       done
62681
 
+libsieve_ext_include.la: $(libsieve_ext_include_la_OBJECTS) $(libsieve_ext_include_la_DEPENDENCIES) 
62682
 
+       $(LINK)  $(libsieve_ext_include_la_OBJECTS) $(libsieve_ext_include_la_LIBADD) $(LIBS)
62683
 
+
62684
 
+mostlyclean-compile:
62685
 
+       -rm -f *.$(OBJEXT)
62686
 
+
62687
 
+distclean-compile:
62688
 
+       -rm -f *.tab.c
62689
 
+
62690
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd-global.Plo@am__quote@
62691
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd-include.Plo@am__quote@
62692
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd-return.Plo@am__quote@
62693
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-include-binary.Plo@am__quote@
62694
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-include-common.Plo@am__quote@
62695
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-include-variables.Plo@am__quote@
62696
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-include.Plo@am__quote@
62697
 
+
62698
 
+.c.o:
62699
 
+@am__fastdepCC_TRUE@   $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
62700
 
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
62701
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
62702
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
62703
 
+@am__fastdepCC_FALSE@  $(COMPILE) -c $<
62704
 
+
62705
 
+.c.obj:
62706
 
+@am__fastdepCC_TRUE@   $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
62707
 
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
62708
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
62709
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
62710
 
+@am__fastdepCC_FALSE@  $(COMPILE) -c `$(CYGPATH_W) '$<'`
62711
 
+
62712
 
+.c.lo:
62713
 
+@am__fastdepCC_TRUE@   $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
62714
 
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
62715
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
62716
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
62717
 
+@am__fastdepCC_FALSE@  $(LTCOMPILE) -c -o $@ $<
62718
 
+
62719
 
+mostlyclean-libtool:
62720
 
+       -rm -f *.lo
62721
 
+
62722
 
+clean-libtool:
62723
 
+       -rm -rf .libs _libs
62724
 
+
62725
 
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
62726
 
+       list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
62727
 
+       unique=`for i in $$list; do \
62728
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
62729
 
+         done | \
62730
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
62731
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
62732
 
+       mkid -fID $$unique
62733
 
+tags: TAGS
62734
 
+
62735
 
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
62736
 
+               $(TAGS_FILES) $(LISP)
62737
 
+       tags=; \
62738
 
+       here=`pwd`; \
62739
 
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
62740
 
+       unique=`for i in $$list; do \
62741
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
62742
 
+         done | \
62743
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
62744
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
62745
 
+       if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
62746
 
+         test -n "$$unique" || unique=$$empty_fix; \
62747
 
+         $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
62748
 
+           $$tags $$unique; \
62749
 
+       fi
62750
 
+ctags: CTAGS
62751
 
+CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
62752
 
+               $(TAGS_FILES) $(LISP)
62753
 
+       tags=; \
62754
 
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
62755
 
+       unique=`for i in $$list; do \
62756
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
62757
 
+         done | \
62758
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
62759
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
62760
 
+       test -z "$(CTAGS_ARGS)$$tags$$unique" \
62761
 
+         || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
62762
 
+            $$tags $$unique
62763
 
+
62764
 
+GTAGS:
62765
 
+       here=`$(am__cd) $(top_builddir) && pwd` \
62766
 
+         && cd $(top_srcdir) \
62767
 
+         && gtags -i $(GTAGS_ARGS) $$here
62768
 
+
62769
 
+distclean-tags:
62770
 
+       -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
62771
 
+
62772
 
+distdir: $(DISTFILES)
62773
 
+       @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
62774
 
+       topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
62775
 
+       list='$(DISTFILES)'; \
62776
 
+         dist_files=`for file in $$list; do echo $$file; done | \
62777
 
+         sed -e "s|^$$srcdirstrip/||;t" \
62778
 
+             -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
62779
 
+       case $$dist_files in \
62780
 
+         */*) $(MKDIR_P) `echo "$$dist_files" | \
62781
 
+                          sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
62782
 
+                          sort -u` ;; \
62783
 
+       esac; \
62784
 
+       for file in $$dist_files; do \
62785
 
+         if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
62786
 
+         if test -d $$d/$$file; then \
62787
 
+           dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
62788
 
+           if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
62789
 
+             cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
62790
 
+           fi; \
62791
 
+           cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
62792
 
+         else \
62793
 
+           test -f $(distdir)/$$file \
62794
 
+           || cp -p $$d/$$file $(distdir)/$$file \
62795
 
+           || exit 1; \
62796
 
+         fi; \
62797
 
+       done
62798
 
+check-am: all-am
62799
 
+check: check-am
62800
 
+all-am: Makefile $(LTLIBRARIES) $(HEADERS)
62801
 
+installdirs:
62802
 
+install: install-am
62803
 
+install-exec: install-exec-am
62804
 
+install-data: install-data-am
62805
 
+uninstall: uninstall-am
62806
 
+
62807
 
+install-am: all-am
62808
 
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
62809
 
+
62810
 
+installcheck: installcheck-am
62811
 
+install-strip:
62812
 
+       $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
62813
 
+         install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
62814
 
+         `test -z '$(STRIP)' || \
62815
 
+           echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
62816
 
+mostlyclean-generic:
62817
 
+
62818
 
+clean-generic:
62819
 
+
62820
 
+distclean-generic:
62821
 
+       -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
62822
 
+
62823
 
+maintainer-clean-generic:
62824
 
+       @echo "This command is intended for maintainers to use"
62825
 
+       @echo "it deletes files that may require special tools to rebuild."
62826
 
+clean: clean-am
62827
 
+
62828
 
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
62829
 
+       mostlyclean-am
62830
 
+
62831
 
+distclean: distclean-am
62832
 
+       -rm -rf ./$(DEPDIR)
62833
 
+       -rm -f Makefile
62834
 
+distclean-am: clean-am distclean-compile distclean-generic \
62835
 
+       distclean-tags
62836
 
+
62837
 
+dvi: dvi-am
62838
 
+
62839
 
+dvi-am:
62840
 
+
62841
 
+html: html-am
62842
 
+
62843
 
+info: info-am
62844
 
+
62845
 
+info-am:
62846
 
+
62847
 
+install-data-am:
62848
 
+
62849
 
+install-dvi: install-dvi-am
62850
 
+
62851
 
+install-exec-am:
62852
 
+
62853
 
+install-html: install-html-am
62854
 
+
62855
 
+install-info: install-info-am
62856
 
+
62857
 
+install-man:
62858
 
+
62859
 
+install-pdf: install-pdf-am
62860
 
+
62861
 
+install-ps: install-ps-am
62862
 
+
62863
 
+installcheck-am:
62864
 
+
62865
 
+maintainer-clean: maintainer-clean-am
62866
 
+       -rm -rf ./$(DEPDIR)
62867
 
+       -rm -f Makefile
62868
 
+maintainer-clean-am: distclean-am maintainer-clean-generic
62869
 
+
62870
 
+mostlyclean: mostlyclean-am
62871
 
+
62872
 
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
62873
 
+       mostlyclean-libtool
62874
 
+
62875
 
+pdf: pdf-am
62876
 
+
62877
 
+pdf-am:
62878
 
+
62879
 
+ps: ps-am
62880
 
+
62881
 
+ps-am:
62882
 
+
62883
 
+uninstall-am:
62884
 
+
62885
 
+.MAKE: install-am install-strip
62886
 
+
62887
 
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
62888
 
+       clean-libtool clean-noinstLTLIBRARIES ctags distclean \
62889
 
+       distclean-compile distclean-generic distclean-libtool \
62890
 
+       distclean-tags distdir dvi dvi-am html html-am info info-am \
62891
 
+       install install-am install-data install-data-am install-dvi \
62892
 
+       install-dvi-am install-exec install-exec-am install-html \
62893
 
+       install-html-am install-info install-info-am install-man \
62894
 
+       install-pdf install-pdf-am install-ps install-ps-am \
62895
 
+       install-strip installcheck installcheck-am installdirs \
62896
 
+       maintainer-clean maintainer-clean-generic mostlyclean \
62897
 
+       mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
62898
 
+       pdf pdf-am ps ps-am tags uninstall uninstall-am
62899
 
+
62900
 
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
62901
 
+# Otherwise a system limit (for SysV at least) may be exceeded.
62902
 
+.NOEXPORT:
62903
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/mailbox/cmd-mailboxexists.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/mailbox/cmd-mailboxexists.c
62904
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/mailbox/cmd-mailboxexists.c    1970-01-01 01:00:00.000000000 +0100
62905
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/mailbox/cmd-mailboxexists.c     2009-08-02 09:44:14.000000000 +0200
62906
 
@@ -0,0 +1,175 @@
62907
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
62908
 
+ */
62909
 
+
62910
 
+#include "lib.h"
62911
 
+#include "mail-storage.h"
62912
 
+#include "mail-namespace.h"
62913
 
+
62914
 
+#include "sieve-common.h"
62915
 
+#include "sieve-commands.h"
62916
 
+#include "sieve-code.h"
62917
 
+#include "sieve-validator.h"
62918
 
+#include "sieve-generator.h"
62919
 
+#include "sieve-interpreter.h"
62920
 
+#include "sieve-dump.h"
62921
 
+
62922
 
+#include "ext-mailbox-common.h"
62923
 
+
62924
 
+/* 
62925
 
+ * Mailboxexists command 
62926
 
+ *
62927
 
+ * Syntax:
62928
 
+ *    mailboxexists <mailbox-names: string-list>
62929
 
+ */
62930
 
+
62931
 
+static bool tst_mailboxexists_validate
62932
 
+       (struct sieve_validator *validator, struct sieve_command_context *tst);
62933
 
+static bool tst_mailboxexists_generate
62934
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx);
62935
 
+
62936
 
+const struct sieve_command mailboxexists_test = { 
62937
 
+       "mailboxexists", 
62938
 
+       SCT_TEST, 
62939
 
+       1, 0, FALSE, FALSE,
62940
 
+       NULL, NULL,
62941
 
+       tst_mailboxexists_validate, 
62942
 
+       tst_mailboxexists_generate, 
62943
 
+       NULL 
62944
 
+};
62945
 
+
62946
 
+/* 
62947
 
+ * Mailboxexists operation
62948
 
+ */
62949
 
+
62950
 
+static bool tst_mailboxexists_operation_dump
62951
 
+       (const struct sieve_operation *op, 
62952
 
+               const struct sieve_dumptime_env *denv, sieve_size_t *address);
62953
 
+static int tst_mailboxexists_operation_execute
62954
 
+       (const struct sieve_operation *op, 
62955
 
+               const struct sieve_runtime_env *renv, sieve_size_t *address);
62956
 
+
62957
 
+const struct sieve_operation mailboxexists_operation = { 
62958
 
+       "MAILBOXEXISTS",
62959
 
+       &mailbox_extension, 
62960
 
+       0, 
62961
 
+       tst_mailboxexists_operation_dump, 
62962
 
+       tst_mailboxexists_operation_execute 
62963
 
+};
62964
 
+
62965
 
+/* 
62966
 
+ * Test validation 
62967
 
+ */
62968
 
+
62969
 
+static bool tst_mailboxexists_validate
62970
 
+       (struct sieve_validator *validator, struct sieve_command_context *tst) 
62971
 
+{              
62972
 
+       struct sieve_ast_argument *arg = tst->first_positional;
62973
 
+       
62974
 
+       if ( !sieve_validate_positional_argument
62975
 
+               (validator, tst, arg, "mailbox-names", 1, SAAT_STRING_LIST) ) {
62976
 
+               return FALSE;
62977
 
+       }
62978
 
+       
62979
 
+       return sieve_validator_argument_activate(validator, tst, arg, FALSE);
62980
 
+}
62981
 
+
62982
 
+/* 
62983
 
+ * Test generation 
62984
 
+ */
62985
 
+
62986
 
+static bool tst_mailboxexists_generate
62987
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_command_context *tst) 
62988
 
+{
62989
 
+       sieve_operation_emit_code(cgenv->sbin, &mailboxexists_operation);
62990
 
+
62991
 
+       /* Generate arguments */
62992
 
+       return sieve_generate_arguments(cgenv, tst, NULL);
62993
 
+}
62994
 
+
62995
 
+/* 
62996
 
+ * Code dump 
62997
 
+ */
62998
 
+
62999
 
+static bool tst_mailboxexists_operation_dump
63000
 
+(const struct sieve_operation *op ATTR_UNUSED,
63001
 
+       const struct sieve_dumptime_env *denv, sieve_size_t *address)
63002
 
+{
63003
 
+       sieve_code_dumpf(denv, "MAILBOXEXISTS");
63004
 
+       sieve_code_descend(denv);
63005
 
+               
63006
 
+       return
63007
 
+               sieve_opr_stringlist_dump(denv, address, "mailbox-names");
63008
 
+}
63009
 
+
63010
 
+/* 
63011
 
+ * Code execution 
63012
 
+ */
63013
 
+
63014
 
+static int tst_mailboxexists_operation_execute
63015
 
+(const struct sieve_operation *op ATTR_UNUSED, 
63016
 
+       const struct sieve_runtime_env *renv, sieve_size_t *address)
63017
 
+{
63018
 
+       struct sieve_coded_stringlist *mailbox_names;
63019
 
+       string_t *mailbox_item;
63020
 
+       bool result = TRUE, all_exist = TRUE;
63021
 
+
63022
 
+       /*
63023
 
+        * Read operands 
63024
 
+        */
63025
 
+       
63026
 
+       /* Read notify uris */
63027
 
+       if ( (mailbox_names=sieve_opr_stringlist_read(renv, address)) == NULL ) {
63028
 
+               sieve_runtime_trace_error(renv, "invalid mailbox-names operand");
63029
 
+               return SIEVE_EXEC_BIN_CORRUPT;
63030
 
+       }
63031
 
+       
63032
 
+       /*
63033
 
+        * Perform operation
63034
 
+        */
63035
 
+
63036
 
+       sieve_runtime_trace(renv, "MAILBOXEXISTS command");
63037
 
+
63038
 
+       if ( renv->scriptenv->namespaces != NULL ) {
63039
 
+               mailbox_item = NULL;
63040
 
+               while ( (result=sieve_coded_stringlist_next_item
63041
 
+                       (mailbox_names, &mailbox_item)) 
63042
 
+                       && mailbox_item != NULL ) {
63043
 
+                       struct mail_namespace *ns;
63044
 
+                       struct mail_storage *storage;
63045
 
+                       const char *mailbox = str_c(mailbox_item);
63046
 
+                       struct mailbox *box;
63047
 
+
63048
 
+                       /* Find the namespace */        
63049
 
+                       ns = mail_namespace_find(renv->scriptenv->namespaces, &mailbox);
63050
 
+                       if ( ns == NULL) {
63051
 
+                               all_exist = FALSE;
63052
 
+                               break;
63053
 
+                       }
63054
 
+
63055
 
+                       /* Open the box */
63056
 
+                       storage = ns->storage;
63057
 
+                       box = mailbox_open(&storage, mailbox, NULL, MAILBOX_OPEN_FAST);
63058
 
+                       if ( box == NULL ) {
63059
 
+                               all_exist = FALSE;
63060
 
+                               break;
63061
 
+                       }
63062
 
+
63063
 
+                       /* Also fail when it is readonly */
63064
 
+                       if ( mailbox_is_readonly(box) )
63065
 
+                               all_exist = FALSE;
63066
 
+
63067
 
+                       /* FIXME: check acl for 'p' or 'i' ACL permissions as required by RFC */
63068
 
+
63069
 
+                       /* Close mailbox */
63070
 
+                       mailbox_close(&box);
63071
 
+               }
63072
 
+       }
63073
 
+       
63074
 
+       if ( !result ) {
63075
 
+               sieve_runtime_trace_error(renv, "invalid mailbox name item");
63076
 
+               return SIEVE_EXEC_BIN_CORRUPT;
63077
 
+       }
63078
 
+       
63079
 
+       sieve_interpreter_set_test_result(renv->interp, all_exist);
63080
 
+       return SIEVE_EXEC_OK;
63081
 
+}
63082
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/mailbox/ext-mailbox.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/mailbox/ext-mailbox.c
63083
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/mailbox/ext-mailbox.c  1970-01-01 01:00:00.000000000 +0100
63084
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/mailbox/ext-mailbox.c   2009-08-05 12:42:59.000000000 +0200
63085
 
@@ -0,0 +1,62 @@
63086
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
63087
 
+ */
63088
 
+
63089
 
+/* Extension mailbox
63090
 
+ * ------------------
63091
 
+ *
63092
 
+ * Authors: Stephan Bosch
63093
 
+ * Specification: RFC 5490
63094
 
+ * Implementation: almost full; acl support is missing for mailboxexists
63095
 
+ * Status: experimental, largely untested
63096
 
+ * 
63097
 
+ */
63098
 
+
63099
 
+#include <stdio.h>
63100
 
+
63101
 
+#include "sieve-common.h"
63102
 
+
63103
 
+#include "sieve-code.h"
63104
 
+#include "sieve-extensions.h"
63105
 
+#include "sieve-actions.h"
63106
 
+#include "sieve-commands.h"
63107
 
+#include "sieve-validator.h"
63108
 
+#include "sieve-generator.h"
63109
 
+#include "sieve-interpreter.h"
63110
 
+#include "sieve-result.h"
63111
 
+
63112
 
+#include "ext-mailbox-common.h"
63113
 
+
63114
 
+/* 
63115
 
+ * Extension
63116
 
+ */
63117
 
+
63118
 
+static bool ext_mailbox_validator_load(struct sieve_validator *valdtr);
63119
 
+
63120
 
+static int ext_my_id = -1;
63121
 
+
63122
 
+const struct sieve_extension mailbox_extension = { 
63123
 
+       "mailbox", 
63124
 
+       &ext_my_id,
63125
 
+       NULL, NULL,
63126
 
+       ext_mailbox_validator_load, 
63127
 
+       NULL, NULL, NULL, NULL, NULL,
63128
 
+       SIEVE_EXT_DEFINE_OPERATION(mailboxexists_operation),
63129
 
+       SIEVE_EXT_DEFINE_OPERAND(mailbox_create_operand)
63130
 
+};
63131
 
+
63132
 
+static bool ext_mailbox_validator_load(struct sieve_validator *valdtr)
63133
 
+{
63134
 
+       /* Register :create tag with fileinto command and we don't care whether this 
63135
 
+        * command is registered or even whether it will be registered at all. The 
63136
 
+        * validator handles either situation gracefully 
63137
 
+        */
63138
 
+       sieve_validator_register_external_tag
63139
 
+               (valdtr, &mailbox_create_tag, "fileinto", SIEVE_OPT_SIDE_EFFECT);
63140
 
+
63141
 
+       /* Register new test */
63142
 
+       sieve_validator_register_command(valdtr, &mailboxexists_test);
63143
 
+
63144
 
+       return TRUE;
63145
 
+}
63146
 
+
63147
 
+
63148
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/mailbox/ext-mailbox-common.h dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/mailbox/ext-mailbox-common.h
63149
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/mailbox/ext-mailbox-common.h   1970-01-01 01:00:00.000000000 +0100
63150
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/mailbox/ext-mailbox-common.h    2009-07-27 13:30:18.000000000 +0200
63151
 
@@ -0,0 +1,40 @@
63152
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
63153
 
+ */
63154
 
+
63155
 
+#ifndef __EXT_MAILBOX_COMMON_H
63156
 
+#define __EXT_MAILBOX_COMMON_H
63157
 
+
63158
 
+#include "sieve-common.h"
63159
 
+
63160
 
+/*
63161
 
+ * Tagged arguments
63162
 
+ */
63163
 
+
63164
 
+extern const struct sieve_argument mailbox_create_tag;
63165
 
+
63166
 
+/*
63167
 
+ * Commands
63168
 
+ */
63169
 
+
63170
 
+extern const struct sieve_command mailboxexists_test;
63171
 
+
63172
 
+/*
63173
 
+ * Operands
63174
 
+ */
63175
 
+
63176
 
+extern const struct sieve_operand mailbox_create_operand;
63177
 
+
63178
 
+/*
63179
 
+ * Operations
63180
 
+ */
63181
 
+
63182
 
+extern const struct sieve_operation mailboxexists_operation;
63183
 
+
63184
 
+/*
63185
 
+ * Extension
63186
 
+ */
63187
 
+
63188
 
+extern const struct sieve_extension mailbox_extension;
63189
 
+
63190
 
+#endif /* __EXT_MAILBOX_COMMON_H */
63191
 
+
63192
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/mailbox/Makefile.am dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/mailbox/Makefile.am
63193
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/mailbox/Makefile.am    1970-01-01 01:00:00.000000000 +0100
63194
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/mailbox/Makefile.am     2009-08-03 16:39:12.000000000 +0200
63195
 
@@ -0,0 +1,22 @@
63196
 
+noinst_LTLIBRARIES = libsieve_ext_mailbox.la
63197
 
+
63198
 
+AM_CPPFLAGS = \
63199
 
+       -I../../ \
63200
 
+       -I$(dovecot_incdir) \
63201
 
+       -I$(dovecot_incdir)/src/lib \
63202
 
+       -I$(dovecot_incdir)/src/lib-mail \
63203
 
+       -I$(dovecot_incdir)/src/lib-storage 
63204
 
+
63205
 
+tags = \
63206
 
+       tag-mailbox-create.c
63207
 
+
63208
 
+commands = \
63209
 
+       cmd-mailboxexists.c
63210
 
+
63211
 
+libsieve_ext_mailbox_la_SOURCES = \
63212
 
+       $(tags) \
63213
 
+       $(commands) \
63214
 
+       ext-mailbox.c
63215
 
+
63216
 
+noinst_HEADERS = \
63217
 
+       ext-mailbox-common.h
63218
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/mailbox/Makefile.in dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/mailbox/Makefile.in
63219
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/mailbox/Makefile.in    1970-01-01 01:00:00.000000000 +0100
63220
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/mailbox/Makefile.in     2009-08-21 00:55:43.000000000 +0200
63221
 
@@ -0,0 +1,473 @@
63222
 
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
63223
 
+# @configure_input@
63224
 
+
63225
 
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
63226
 
+# 2003, 2004, 2005, 2006, 2007, 2008  Free Software Foundation, Inc.
63227
 
+# This Makefile.in is free software; the Free Software Foundation
63228
 
+# gives unlimited permission to copy and/or distribute it,
63229
 
+# with or without modifications, as long as this notice is preserved.
63230
 
+
63231
 
+# This program is distributed in the hope that it will be useful,
63232
 
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
63233
 
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
63234
 
+# PARTICULAR PURPOSE.
63235
 
+
63236
 
+@SET_MAKE@
63237
 
+
63238
 
+
63239
 
+VPATH = @srcdir@
63240
 
+pkgdatadir = $(datadir)/@PACKAGE@
63241
 
+pkglibdir = $(libdir)/@PACKAGE@
63242
 
+pkgincludedir = $(includedir)/@PACKAGE@
63243
 
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
63244
 
+install_sh_DATA = $(install_sh) -c -m 644
63245
 
+install_sh_PROGRAM = $(install_sh) -c
63246
 
+install_sh_SCRIPT = $(install_sh) -c
63247
 
+INSTALL_HEADER = $(INSTALL_DATA)
63248
 
+transform = $(program_transform_name)
63249
 
+NORMAL_INSTALL = :
63250
 
+PRE_INSTALL = :
63251
 
+POST_INSTALL = :
63252
 
+NORMAL_UNINSTALL = :
63253
 
+PRE_UNINSTALL = :
63254
 
+POST_UNINSTALL = :
63255
 
+build_triplet = @build@
63256
 
+host_triplet = @host@
63257
 
+subdir = src/lib-sieve/plugins/mailbox
63258
 
+DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
63259
 
+       $(srcdir)/Makefile.in
63260
 
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
63261
 
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
63262
 
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
63263
 
+       $(ACLOCAL_M4)
63264
 
+mkinstalldirs = $(install_sh) -d
63265
 
+CONFIG_HEADER = $(top_builddir)/dummy-config.h \
63266
 
+       $(top_builddir)/dsieve-config.h
63267
 
+CONFIG_CLEAN_FILES =
63268
 
+LTLIBRARIES = $(noinst_LTLIBRARIES)
63269
 
+libsieve_ext_mailbox_la_LIBADD =
63270
 
+am__objects_1 = tag-mailbox-create.lo
63271
 
+am__objects_2 = cmd-mailboxexists.lo
63272
 
+am_libsieve_ext_mailbox_la_OBJECTS = $(am__objects_1) $(am__objects_2) \
63273
 
+       ext-mailbox.lo
63274
 
+libsieve_ext_mailbox_la_OBJECTS =  \
63275
 
+       $(am_libsieve_ext_mailbox_la_OBJECTS)
63276
 
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
63277
 
+depcomp = $(SHELL) $(top_srcdir)/depcomp
63278
 
+am__depfiles_maybe = depfiles
63279
 
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
63280
 
+       $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
63281
 
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
63282
 
+       --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
63283
 
+       $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
63284
 
+CCLD = $(CC)
63285
 
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
63286
 
+       --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
63287
 
+       $(LDFLAGS) -o $@
63288
 
+SOURCES = $(libsieve_ext_mailbox_la_SOURCES)
63289
 
+DIST_SOURCES = $(libsieve_ext_mailbox_la_SOURCES)
63290
 
+HEADERS = $(noinst_HEADERS)
63291
 
+ETAGS = etags
63292
 
+CTAGS = ctags
63293
 
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
63294
 
+ACLOCAL = @ACLOCAL@
63295
 
+AMTAR = @AMTAR@
63296
 
+AR = @AR@
63297
 
+AUTOCONF = @AUTOCONF@
63298
 
+AUTOHEADER = @AUTOHEADER@
63299
 
+AUTOMAKE = @AUTOMAKE@
63300
 
+AWK = @AWK@
63301
 
+CC = @CC@
63302
 
+CCDEPMODE = @CCDEPMODE@
63303
 
+CFLAGS = @CFLAGS@
63304
 
+CPP = @CPP@
63305
 
+CPPFLAGS = @CPPFLAGS@
63306
 
+CYGPATH_W = @CYGPATH_W@
63307
 
+DEFS = @DEFS@
63308
 
+DEPDIR = @DEPDIR@
63309
 
+DSYMUTIL = @DSYMUTIL@
63310
 
+DUMPBIN = @DUMPBIN@
63311
 
+ECHO_C = @ECHO_C@
63312
 
+ECHO_N = @ECHO_N@
63313
 
+ECHO_T = @ECHO_T@
63314
 
+EGREP = @EGREP@
63315
 
+EXEEXT = @EXEEXT@
63316
 
+FGREP = @FGREP@
63317
 
+GREP = @GREP@
63318
 
+INSTALL = @INSTALL@
63319
 
+INSTALL_DATA = @INSTALL_DATA@
63320
 
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
63321
 
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
63322
 
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
63323
 
+LD = @LD@
63324
 
+LDFLAGS = @LDFLAGS@
63325
 
+LIBICONV = @LIBICONV@
63326
 
+LIBOBJS = @LIBOBJS@
63327
 
+LIBS = @LIBS@
63328
 
+LIBTOOL = @LIBTOOL@
63329
 
+LIPO = @LIPO@
63330
 
+LN_S = @LN_S@
63331
 
+LTLIBOBJS = @LTLIBOBJS@
63332
 
+MAINT = @MAINT@
63333
 
+MAKEINFO = @MAKEINFO@
63334
 
+MKDIR_P = @MKDIR_P@
63335
 
+MODULE_LIBS = @MODULE_LIBS@
63336
 
+NM = @NM@
63337
 
+NMEDIT = @NMEDIT@
63338
 
+OBJDUMP = @OBJDUMP@
63339
 
+OBJEXT = @OBJEXT@
63340
 
+OTOOL = @OTOOL@
63341
 
+OTOOL64 = @OTOOL64@
63342
 
+PACKAGE = @PACKAGE@
63343
 
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
63344
 
+PACKAGE_NAME = @PACKAGE_NAME@
63345
 
+PACKAGE_STRING = @PACKAGE_STRING@
63346
 
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
63347
 
+PACKAGE_URL = @PACKAGE_URL@
63348
 
+PACKAGE_VERSION = @PACKAGE_VERSION@
63349
 
+PATH_SEPARATOR = @PATH_SEPARATOR@
63350
 
+RAND_LIBS = @RAND_LIBS@
63351
 
+RANLIB = @RANLIB@
63352
 
+SED = @SED@
63353
 
+SET_MAKE = @SET_MAKE@
63354
 
+SHELL = @SHELL@
63355
 
+STORAGE_LIBS = @STORAGE_LIBS@
63356
 
+STRIP = @STRIP@
63357
 
+VERSION = @VERSION@
63358
 
+abs_builddir = @abs_builddir@
63359
 
+abs_srcdir = @abs_srcdir@
63360
 
+abs_top_builddir = @abs_top_builddir@
63361
 
+abs_top_srcdir = @abs_top_srcdir@
63362
 
+ac_ct_CC = @ac_ct_CC@
63363
 
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
63364
 
+am__include = @am__include@
63365
 
+am__leading_dot = @am__leading_dot@
63366
 
+am__quote = @am__quote@
63367
 
+am__tar = @am__tar@
63368
 
+am__untar = @am__untar@
63369
 
+bindir = @bindir@
63370
 
+build = @build@
63371
 
+build_alias = @build_alias@
63372
 
+build_cpu = @build_cpu@
63373
 
+build_os = @build_os@
63374
 
+build_vendor = @build_vendor@
63375
 
+builddir = @builddir@
63376
 
+datadir = @datadir@
63377
 
+datarootdir = @datarootdir@
63378
 
+docdir = @docdir@
63379
 
+dovecot_incdir = @dovecot_incdir@
63380
 
+dovecotdir = @dovecotdir@
63381
 
+dvidir = @dvidir@
63382
 
+exec_prefix = @exec_prefix@
63383
 
+host = @host@
63384
 
+host_alias = @host_alias@
63385
 
+host_cpu = @host_cpu@
63386
 
+host_os = @host_os@
63387
 
+host_vendor = @host_vendor@
63388
 
+htmldir = @htmldir@
63389
 
+includedir = @includedir@
63390
 
+infodir = @infodir@
63391
 
+install_sh = @install_sh@
63392
 
+libdir = @libdir@
63393
 
+libexecdir = @libexecdir@
63394
 
+localedir = @localedir@
63395
 
+localstatedir = @localstatedir@
63396
 
+lt_ECHO = @lt_ECHO@
63397
 
+mandir = @mandir@
63398
 
+mkdir_p = @mkdir_p@
63399
 
+moduledir = @moduledir@
63400
 
+oldincludedir = @oldincludedir@
63401
 
+pdfdir = @pdfdir@
63402
 
+prefix = @prefix@
63403
 
+program_transform_name = @program_transform_name@
63404
 
+psdir = @psdir@
63405
 
+sbindir = @sbindir@
63406
 
+sharedstatedir = @sharedstatedir@
63407
 
+srcdir = @srcdir@
63408
 
+sysconfdir = @sysconfdir@
63409
 
+target_alias = @target_alias@
63410
 
+top_build_prefix = @top_build_prefix@
63411
 
+top_builddir = @top_builddir@
63412
 
+top_srcdir = @top_srcdir@
63413
 
+noinst_LTLIBRARIES = libsieve_ext_mailbox.la
63414
 
+AM_CPPFLAGS = \
63415
 
+       -I../../ \
63416
 
+       -I$(dovecot_incdir) \
63417
 
+       -I$(dovecot_incdir)/src/lib \
63418
 
+       -I$(dovecot_incdir)/src/lib-mail \
63419
 
+       -I$(dovecot_incdir)/src/lib-storage 
63420
 
+
63421
 
+tags = \
63422
 
+       tag-mailbox-create.c
63423
 
+
63424
 
+commands = \
63425
 
+       cmd-mailboxexists.c
63426
 
+
63427
 
+libsieve_ext_mailbox_la_SOURCES = \
63428
 
+       $(tags) \
63429
 
+       $(commands) \
63430
 
+       ext-mailbox.c
63431
 
+
63432
 
+noinst_HEADERS = \
63433
 
+       ext-mailbox-common.h
63434
 
+
63435
 
+all: all-am
63436
 
+
63437
 
+.SUFFIXES:
63438
 
+.SUFFIXES: .c .lo .o .obj
63439
 
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
63440
 
+       @for dep in $?; do \
63441
 
+         case '$(am__configure_deps)' in \
63442
 
+           *$$dep*) \
63443
 
+             ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
63444
 
+               && { if test -f $@; then exit 0; else break; fi; }; \
63445
 
+             exit 1;; \
63446
 
+         esac; \
63447
 
+       done; \
63448
 
+       echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign  src/lib-sieve/plugins/mailbox/Makefile'; \
63449
 
+       cd $(top_srcdir) && \
63450
 
+         $(AUTOMAKE) --foreign  src/lib-sieve/plugins/mailbox/Makefile
63451
 
+.PRECIOUS: Makefile
63452
 
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
63453
 
+       @case '$?' in \
63454
 
+         *config.status*) \
63455
 
+           cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
63456
 
+         *) \
63457
 
+           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
63458
 
+           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
63459
 
+       esac;
63460
 
+
63461
 
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
63462
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
63463
 
+
63464
 
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
63465
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
63466
 
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
63467
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
63468
 
+
63469
 
+clean-noinstLTLIBRARIES:
63470
 
+       -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
63471
 
+       @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
63472
 
+         dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
63473
 
+         test "$$dir" != "$$p" || dir=.; \
63474
 
+         echo "rm -f \"$${dir}/so_locations\""; \
63475
 
+         rm -f "$${dir}/so_locations"; \
63476
 
+       done
63477
 
+libsieve_ext_mailbox.la: $(libsieve_ext_mailbox_la_OBJECTS) $(libsieve_ext_mailbox_la_DEPENDENCIES) 
63478
 
+       $(LINK)  $(libsieve_ext_mailbox_la_OBJECTS) $(libsieve_ext_mailbox_la_LIBADD) $(LIBS)
63479
 
+
63480
 
+mostlyclean-compile:
63481
 
+       -rm -f *.$(OBJEXT)
63482
 
+
63483
 
+distclean-compile:
63484
 
+       -rm -f *.tab.c
63485
 
+
63486
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd-mailboxexists.Plo@am__quote@
63487
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-mailbox.Plo@am__quote@
63488
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tag-mailbox-create.Plo@am__quote@
63489
 
+
63490
 
+.c.o:
63491
 
+@am__fastdepCC_TRUE@   $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
63492
 
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
63493
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
63494
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
63495
 
+@am__fastdepCC_FALSE@  $(COMPILE) -c $<
63496
 
+
63497
 
+.c.obj:
63498
 
+@am__fastdepCC_TRUE@   $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
63499
 
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
63500
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
63501
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
63502
 
+@am__fastdepCC_FALSE@  $(COMPILE) -c `$(CYGPATH_W) '$<'`
63503
 
+
63504
 
+.c.lo:
63505
 
+@am__fastdepCC_TRUE@   $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
63506
 
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
63507
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
63508
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
63509
 
+@am__fastdepCC_FALSE@  $(LTCOMPILE) -c -o $@ $<
63510
 
+
63511
 
+mostlyclean-libtool:
63512
 
+       -rm -f *.lo
63513
 
+
63514
 
+clean-libtool:
63515
 
+       -rm -rf .libs _libs
63516
 
+
63517
 
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
63518
 
+       list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
63519
 
+       unique=`for i in $$list; do \
63520
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
63521
 
+         done | \
63522
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
63523
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
63524
 
+       mkid -fID $$unique
63525
 
+tags: TAGS
63526
 
+
63527
 
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
63528
 
+               $(TAGS_FILES) $(LISP)
63529
 
+       tags=; \
63530
 
+       here=`pwd`; \
63531
 
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
63532
 
+       unique=`for i in $$list; do \
63533
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
63534
 
+         done | \
63535
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
63536
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
63537
 
+       if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
63538
 
+         test -n "$$unique" || unique=$$empty_fix; \
63539
 
+         $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
63540
 
+           $$tags $$unique; \
63541
 
+       fi
63542
 
+ctags: CTAGS
63543
 
+CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
63544
 
+               $(TAGS_FILES) $(LISP)
63545
 
+       tags=; \
63546
 
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
63547
 
+       unique=`for i in $$list; do \
63548
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
63549
 
+         done | \
63550
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
63551
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
63552
 
+       test -z "$(CTAGS_ARGS)$$tags$$unique" \
63553
 
+         || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
63554
 
+            $$tags $$unique
63555
 
+
63556
 
+GTAGS:
63557
 
+       here=`$(am__cd) $(top_builddir) && pwd` \
63558
 
+         && cd $(top_srcdir) \
63559
 
+         && gtags -i $(GTAGS_ARGS) $$here
63560
 
+
63561
 
+distclean-tags:
63562
 
+       -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
63563
 
+
63564
 
+distdir: $(DISTFILES)
63565
 
+       @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
63566
 
+       topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
63567
 
+       list='$(DISTFILES)'; \
63568
 
+         dist_files=`for file in $$list; do echo $$file; done | \
63569
 
+         sed -e "s|^$$srcdirstrip/||;t" \
63570
 
+             -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
63571
 
+       case $$dist_files in \
63572
 
+         */*) $(MKDIR_P) `echo "$$dist_files" | \
63573
 
+                          sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
63574
 
+                          sort -u` ;; \
63575
 
+       esac; \
63576
 
+       for file in $$dist_files; do \
63577
 
+         if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
63578
 
+         if test -d $$d/$$file; then \
63579
 
+           dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
63580
 
+           if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
63581
 
+             cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
63582
 
+           fi; \
63583
 
+           cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
63584
 
+         else \
63585
 
+           test -f $(distdir)/$$file \
63586
 
+           || cp -p $$d/$$file $(distdir)/$$file \
63587
 
+           || exit 1; \
63588
 
+         fi; \
63589
 
+       done
63590
 
+check-am: all-am
63591
 
+check: check-am
63592
 
+all-am: Makefile $(LTLIBRARIES) $(HEADERS)
63593
 
+installdirs:
63594
 
+install: install-am
63595
 
+install-exec: install-exec-am
63596
 
+install-data: install-data-am
63597
 
+uninstall: uninstall-am
63598
 
+
63599
 
+install-am: all-am
63600
 
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
63601
 
+
63602
 
+installcheck: installcheck-am
63603
 
+install-strip:
63604
 
+       $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
63605
 
+         install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
63606
 
+         `test -z '$(STRIP)' || \
63607
 
+           echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
63608
 
+mostlyclean-generic:
63609
 
+
63610
 
+clean-generic:
63611
 
+
63612
 
+distclean-generic:
63613
 
+       -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
63614
 
+
63615
 
+maintainer-clean-generic:
63616
 
+       @echo "This command is intended for maintainers to use"
63617
 
+       @echo "it deletes files that may require special tools to rebuild."
63618
 
+clean: clean-am
63619
 
+
63620
 
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
63621
 
+       mostlyclean-am
63622
 
+
63623
 
+distclean: distclean-am
63624
 
+       -rm -rf ./$(DEPDIR)
63625
 
+       -rm -f Makefile
63626
 
+distclean-am: clean-am distclean-compile distclean-generic \
63627
 
+       distclean-tags
63628
 
+
63629
 
+dvi: dvi-am
63630
 
+
63631
 
+dvi-am:
63632
 
+
63633
 
+html: html-am
63634
 
+
63635
 
+info: info-am
63636
 
+
63637
 
+info-am:
63638
 
+
63639
 
+install-data-am:
63640
 
+
63641
 
+install-dvi: install-dvi-am
63642
 
+
63643
 
+install-exec-am:
63644
 
+
63645
 
+install-html: install-html-am
63646
 
+
63647
 
+install-info: install-info-am
63648
 
+
63649
 
+install-man:
63650
 
+
63651
 
+install-pdf: install-pdf-am
63652
 
+
63653
 
+install-ps: install-ps-am
63654
 
+
63655
 
+installcheck-am:
63656
 
+
63657
 
+maintainer-clean: maintainer-clean-am
63658
 
+       -rm -rf ./$(DEPDIR)
63659
 
+       -rm -f Makefile
63660
 
+maintainer-clean-am: distclean-am maintainer-clean-generic
63661
 
+
63662
 
+mostlyclean: mostlyclean-am
63663
 
+
63664
 
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
63665
 
+       mostlyclean-libtool
63666
 
+
63667
 
+pdf: pdf-am
63668
 
+
63669
 
+pdf-am:
63670
 
+
63671
 
+ps: ps-am
63672
 
+
63673
 
+ps-am:
63674
 
+
63675
 
+uninstall-am:
63676
 
+
63677
 
+.MAKE: install-am install-strip
63678
 
+
63679
 
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
63680
 
+       clean-libtool clean-noinstLTLIBRARIES ctags distclean \
63681
 
+       distclean-compile distclean-generic distclean-libtool \
63682
 
+       distclean-tags distdir dvi dvi-am html html-am info info-am \
63683
 
+       install install-am install-data install-data-am install-dvi \
63684
 
+       install-dvi-am install-exec install-exec-am install-html \
63685
 
+       install-html-am install-info install-info-am install-man \
63686
 
+       install-pdf install-pdf-am install-ps install-ps-am \
63687
 
+       install-strip installcheck installcheck-am installdirs \
63688
 
+       maintainer-clean maintainer-clean-generic mostlyclean \
63689
 
+       mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
63690
 
+       pdf pdf-am ps ps-am tags uninstall uninstall-am
63691
 
+
63692
 
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
63693
 
+# Otherwise a system limit (for SysV at least) may be exceeded.
63694
 
+.NOEXPORT:
63695
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/mailbox/tag-mailbox-create.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/mailbox/tag-mailbox-create.c
63696
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/mailbox/tag-mailbox-create.c   1970-01-01 01:00:00.000000000 +0100
63697
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/mailbox/tag-mailbox-create.c    2009-07-30 01:00:42.000000000 +0200
63698
 
@@ -0,0 +1,175 @@
63699
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
63700
 
+ */
63701
 
+
63702
 
+#include "lib.h"
63703
 
+#include "mail-storage.h"
63704
 
+#include "mail-namespace.h"
63705
 
+
63706
 
+#include "sieve-common.h"
63707
 
+#include "sieve-commands.h"
63708
 
+#include "sieve-code.h"
63709
 
+#include "sieve-actions.h"
63710
 
+#include "sieve-result.h"
63711
 
+#include "sieve-generator.h"
63712
 
+
63713
 
+#include "ext-mailbox-common.h"
63714
 
+
63715
 
+/* 
63716
 
+ * Tagged argument 
63717
 
+ */
63718
 
+
63719
 
+static bool tag_mailbox_create_validate
63720
 
+       (struct sieve_validator *validator, struct sieve_ast_argument **arg, 
63721
 
+               struct sieve_command_context *cmd);
63722
 
+static bool tag_mailbox_create_generate
63723
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg,
63724
 
+    struct sieve_command_context *context);
63725
 
+
63726
 
+const struct sieve_argument mailbox_create_tag = { 
63727
 
+       "create", 
63728
 
+       NULL, NULL,
63729
 
+       tag_mailbox_create_validate, 
63730
 
+       NULL,
63731
 
+       tag_mailbox_create_generate
63732
 
+};
63733
 
+
63734
 
+/*
63735
 
+ * Side effect 
63736
 
+ */
63737
 
+
63738
 
+static void seff_mailbox_create_print
63739
 
+       (const struct sieve_side_effect *seffect, const struct sieve_action *action, 
63740
 
+               const struct sieve_result_print_env *rpenv, void *se_context, bool *keep);
63741
 
+static bool seff_mailbox_create_pre_execute
63742
 
+       (const struct sieve_side_effect *seffect, const struct sieve_action *action, 
63743
 
+               const struct sieve_action_exec_env *aenv, void **se_context, 
63744
 
+               void *tr_context);;
63745
 
+
63746
 
+const struct sieve_side_effect mailbox_create_side_effect = {
63747
 
+       SIEVE_OBJECT("create", &mailbox_create_operand, 0),
63748
 
+       &act_store,
63749
 
+       NULL, NULL, NULL,
63750
 
+       seff_mailbox_create_print,
63751
 
+       seff_mailbox_create_pre_execute, 
63752
 
+       NULL, NULL, NULL
63753
 
+};
63754
 
+
63755
 
+/*
63756
 
+ * Operand
63757
 
+ */
63758
 
+
63759
 
+static const struct sieve_extension_objects ext_side_effects =
63760
 
+       SIEVE_EXT_DEFINE_SIDE_EFFECT(mailbox_create_side_effect);
63761
 
+
63762
 
+const struct sieve_operand mailbox_create_operand = {
63763
 
+       "create operand",
63764
 
+       &mailbox_extension,
63765
 
+       0,
63766
 
+       &sieve_side_effect_operand_class,
63767
 
+       &ext_side_effects
63768
 
+};
63769
 
+
63770
 
+/* 
63771
 
+ * Tag validation 
63772
 
+ */
63773
 
+
63774
 
+static bool tag_mailbox_create_validate
63775
 
+       (struct sieve_validator *validator ATTR_UNUSED, 
63776
 
+       struct sieve_ast_argument **arg ATTR_UNUSED, 
63777
 
+       struct sieve_command_context *cmd ATTR_UNUSED)
63778
 
+{
63779
 
+       *arg = sieve_ast_argument_next(*arg);
63780
 
+
63781
 
+       return TRUE;
63782
 
+}
63783
 
+
63784
 
+/*
63785
 
+ * Code generation 
63786
 
+ */
63787
 
+
63788
 
+static bool tag_mailbox_create_generate
63789
 
+(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg,
63790
 
+    struct sieve_command_context *context ATTR_UNUSED)
63791
 
+{
63792
 
+       if ( sieve_ast_argument_type(arg) != SAAT_TAG ) {
63793
 
+               return FALSE;
63794
 
+       }
63795
 
+
63796
 
+       sieve_opr_side_effect_emit(cgenv->sbin, &mailbox_create_side_effect);
63797
 
+
63798
 
+       return TRUE;
63799
 
+}
63800
 
+
63801
 
+/* 
63802
 
+ * Side effect implementation
63803
 
+ */
63804
 
+
63805
 
+static void seff_mailbox_create_print
63806
 
+(const struct sieve_side_effect *seffect ATTR_UNUSED, 
63807
 
+       const struct sieve_action *action ATTR_UNUSED, 
63808
 
+       const struct sieve_result_print_env *rpenv,
63809
 
+       void *se_context ATTR_UNUSED, bool *keep ATTR_UNUSED)
63810
 
+{
63811
 
+       sieve_result_seffect_printf(rpenv, "create mailbox if it does not exist");
63812
 
+}
63813
 
+
63814
 
+static bool seff_mailbox_create_pre_execute
63815
 
+(const struct sieve_side_effect *seffect ATTR_UNUSED, 
63816
 
+       const struct sieve_action *action ATTR_UNUSED, 
63817
 
+       const struct sieve_action_exec_env *aenv ATTR_UNUSED,
63818
 
+       void **se_context ATTR_UNUSED, void *tr_context ATTR_UNUSED)
63819
 
+{      
63820
 
+       struct act_store_transaction *trans = 
63821
 
+               (struct act_store_transaction *) tr_context;
63822
 
+       struct mail_storage **storage = &(aenv->exec_status->last_storage);
63823
 
+       enum mailbox_open_flags open_flags = 
63824
 
+               MAILBOX_OPEN_FAST | MAILBOX_OPEN_KEEP_RECENT | 
63825
 
+               MAILBOX_OPEN_SAVEONLY | MAILBOX_OPEN_POST_SESSION;
63826
 
+       struct mailbox *box = NULL;
63827
 
+       
63828
 
+       /* Check whether creation is necessary */
63829
 
+       if ( trans->box != NULL || trans->redundant || trans->disabled ) 
63830
 
+               return TRUE;
63831
 
+
63832
 
+       /* Check availability of namespace and folder name */
63833
 
+       if ( trans->namespace == NULL || trans->folder == NULL )
63834
 
+               return FALSE;
63835
 
+
63836
 
+       /* Check whether creation has a chance of working */
63837
 
+       if ( trans->error_code != MAIL_ERROR_NONE 
63838
 
+               && trans->error_code != MAIL_ERROR_NOTFOUND )
63839
 
+               return FALSE;
63840
 
+
63841
 
+       *storage = trans->namespace->storage; 
63842
 
+
63843
 
+       /* Create mailbox */
63844
 
+       if ( mail_storage_mailbox_create(*storage, trans->folder, FALSE) < 0 ) {
63845
 
+               box = NULL;
63846
 
+
63847
 
+       } else {
63848
 
+               /* Subscribe to it if necessary */
63849
 
+               if ( aenv->scriptenv->mailbox_autosubscribe ) {
63850
 
+                       (void)mailbox_list_set_subscribed
63851
 
+                               (trans->namespace->list, trans->folder, TRUE);
63852
 
+               }
63853
 
+
63854
 
+               /* Open it */
63855
 
+               box = mailbox_open(storage, trans->folder, NULL, open_flags);
63856
 
+    
63857
 
+               if ( box != NULL && mailbox_sync(box, 0, 0, NULL) < 0 ) {
63858
 
+                       mailbox_close(&box);
63859
 
+                       box = NULL;
63860
 
+               }
63861
 
+       } 
63862
 
+
63863
 
+       /* Fetch error */
63864
 
+       if ( box == NULL )
63865
 
+               sieve_act_store_get_storage_error(aenv, trans); 
63866
 
+
63867
 
+       trans->box = box;
63868
 
+       
63869
 
+       return ( box != NULL );
63870
 
+}
63871
 
+
63872
 
+
63873
 
+
63874
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/Makefile.am dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/Makefile.am
63875
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/Makefile.am    1970-01-01 01:00:00.000000000 +0100
63876
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/Makefile.am     2009-08-21 00:52:15.000000000 +0200
63877
 
@@ -0,0 +1,22 @@
63878
 
+if BUILD_UNFINISHED
63879
 
+UNFINISHED =
63880
 
+endif
63881
 
+
63882
 
+SUBDIRS = \
63883
 
+       vacation \
63884
 
+       subaddress \
63885
 
+       comparator-i-ascii-numeric \
63886
 
+       relational \
63887
 
+       regex \
63888
 
+       imap4flags \
63889
 
+       copy \
63890
 
+       include \
63891
 
+       body \
63892
 
+       variables \
63893
 
+       enotify \
63894
 
+       notify \
63895
 
+       environment \
63896
 
+       mailbox \
63897
 
+       date \
63898
 
+       $(UNFINISHED)
63899
 
+
63900
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/Makefile.in dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/Makefile.in
63901
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/Makefile.in    1970-01-01 01:00:00.000000000 +0100
63902
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/Makefile.in     2009-08-21 00:55:42.000000000 +0200
63903
 
@@ -0,0 +1,511 @@
63904
 
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
63905
 
+# @configure_input@
63906
 
+
63907
 
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
63908
 
+# 2003, 2004, 2005, 2006, 2007, 2008  Free Software Foundation, Inc.
63909
 
+# This Makefile.in is free software; the Free Software Foundation
63910
 
+# gives unlimited permission to copy and/or distribute it,
63911
 
+# with or without modifications, as long as this notice is preserved.
63912
 
+
63913
 
+# This program is distributed in the hope that it will be useful,
63914
 
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
63915
 
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
63916
 
+# PARTICULAR PURPOSE.
63917
 
+
63918
 
+@SET_MAKE@
63919
 
+VPATH = @srcdir@
63920
 
+pkgdatadir = $(datadir)/@PACKAGE@
63921
 
+pkglibdir = $(libdir)/@PACKAGE@
63922
 
+pkgincludedir = $(includedir)/@PACKAGE@
63923
 
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
63924
 
+install_sh_DATA = $(install_sh) -c -m 644
63925
 
+install_sh_PROGRAM = $(install_sh) -c
63926
 
+install_sh_SCRIPT = $(install_sh) -c
63927
 
+INSTALL_HEADER = $(INSTALL_DATA)
63928
 
+transform = $(program_transform_name)
63929
 
+NORMAL_INSTALL = :
63930
 
+PRE_INSTALL = :
63931
 
+POST_INSTALL = :
63932
 
+NORMAL_UNINSTALL = :
63933
 
+PRE_UNINSTALL = :
63934
 
+POST_UNINSTALL = :
63935
 
+build_triplet = @build@
63936
 
+host_triplet = @host@
63937
 
+subdir = src/lib-sieve/plugins
63938
 
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
63939
 
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
63940
 
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
63941
 
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
63942
 
+       $(ACLOCAL_M4)
63943
 
+mkinstalldirs = $(install_sh) -d
63944
 
+CONFIG_HEADER = $(top_builddir)/dummy-config.h \
63945
 
+       $(top_builddir)/dsieve-config.h
63946
 
+CONFIG_CLEAN_FILES =
63947
 
+SOURCES =
63948
 
+DIST_SOURCES =
63949
 
+RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
63950
 
+       html-recursive info-recursive install-data-recursive \
63951
 
+       install-dvi-recursive install-exec-recursive \
63952
 
+       install-html-recursive install-info-recursive \
63953
 
+       install-pdf-recursive install-ps-recursive install-recursive \
63954
 
+       installcheck-recursive installdirs-recursive pdf-recursive \
63955
 
+       ps-recursive uninstall-recursive
63956
 
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive        \
63957
 
+  distclean-recursive maintainer-clean-recursive
63958
 
+ETAGS = etags
63959
 
+CTAGS = ctags
63960
 
+DIST_SUBDIRS = $(SUBDIRS)
63961
 
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
63962
 
+ACLOCAL = @ACLOCAL@
63963
 
+AMTAR = @AMTAR@
63964
 
+AR = @AR@
63965
 
+AUTOCONF = @AUTOCONF@
63966
 
+AUTOHEADER = @AUTOHEADER@
63967
 
+AUTOMAKE = @AUTOMAKE@
63968
 
+AWK = @AWK@
63969
 
+CC = @CC@
63970
 
+CCDEPMODE = @CCDEPMODE@
63971
 
+CFLAGS = @CFLAGS@
63972
 
+CPP = @CPP@
63973
 
+CPPFLAGS = @CPPFLAGS@
63974
 
+CYGPATH_W = @CYGPATH_W@
63975
 
+DEFS = @DEFS@
63976
 
+DEPDIR = @DEPDIR@
63977
 
+DSYMUTIL = @DSYMUTIL@
63978
 
+DUMPBIN = @DUMPBIN@
63979
 
+ECHO_C = @ECHO_C@
63980
 
+ECHO_N = @ECHO_N@
63981
 
+ECHO_T = @ECHO_T@
63982
 
+EGREP = @EGREP@
63983
 
+EXEEXT = @EXEEXT@
63984
 
+FGREP = @FGREP@
63985
 
+GREP = @GREP@
63986
 
+INSTALL = @INSTALL@
63987
 
+INSTALL_DATA = @INSTALL_DATA@
63988
 
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
63989
 
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
63990
 
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
63991
 
+LD = @LD@
63992
 
+LDFLAGS = @LDFLAGS@
63993
 
+LIBICONV = @LIBICONV@
63994
 
+LIBOBJS = @LIBOBJS@
63995
 
+LIBS = @LIBS@
63996
 
+LIBTOOL = @LIBTOOL@
63997
 
+LIPO = @LIPO@
63998
 
+LN_S = @LN_S@
63999
 
+LTLIBOBJS = @LTLIBOBJS@
64000
 
+MAINT = @MAINT@
64001
 
+MAKEINFO = @MAKEINFO@
64002
 
+MKDIR_P = @MKDIR_P@
64003
 
+MODULE_LIBS = @MODULE_LIBS@
64004
 
+NM = @NM@
64005
 
+NMEDIT = @NMEDIT@
64006
 
+OBJDUMP = @OBJDUMP@
64007
 
+OBJEXT = @OBJEXT@
64008
 
+OTOOL = @OTOOL@
64009
 
+OTOOL64 = @OTOOL64@
64010
 
+PACKAGE = @PACKAGE@
64011
 
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
64012
 
+PACKAGE_NAME = @PACKAGE_NAME@
64013
 
+PACKAGE_STRING = @PACKAGE_STRING@
64014
 
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
64015
 
+PACKAGE_URL = @PACKAGE_URL@
64016
 
+PACKAGE_VERSION = @PACKAGE_VERSION@
64017
 
+PATH_SEPARATOR = @PATH_SEPARATOR@
64018
 
+RAND_LIBS = @RAND_LIBS@
64019
 
+RANLIB = @RANLIB@
64020
 
+SED = @SED@
64021
 
+SET_MAKE = @SET_MAKE@
64022
 
+SHELL = @SHELL@
64023
 
+STORAGE_LIBS = @STORAGE_LIBS@
64024
 
+STRIP = @STRIP@
64025
 
+VERSION = @VERSION@
64026
 
+abs_builddir = @abs_builddir@
64027
 
+abs_srcdir = @abs_srcdir@
64028
 
+abs_top_builddir = @abs_top_builddir@
64029
 
+abs_top_srcdir = @abs_top_srcdir@
64030
 
+ac_ct_CC = @ac_ct_CC@
64031
 
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
64032
 
+am__include = @am__include@
64033
 
+am__leading_dot = @am__leading_dot@
64034
 
+am__quote = @am__quote@
64035
 
+am__tar = @am__tar@
64036
 
+am__untar = @am__untar@
64037
 
+bindir = @bindir@
64038
 
+build = @build@
64039
 
+build_alias = @build_alias@
64040
 
+build_cpu = @build_cpu@
64041
 
+build_os = @build_os@
64042
 
+build_vendor = @build_vendor@
64043
 
+builddir = @builddir@
64044
 
+datadir = @datadir@
64045
 
+datarootdir = @datarootdir@
64046
 
+docdir = @docdir@
64047
 
+dovecot_incdir = @dovecot_incdir@
64048
 
+dovecotdir = @dovecotdir@
64049
 
+dvidir = @dvidir@
64050
 
+exec_prefix = @exec_prefix@
64051
 
+host = @host@
64052
 
+host_alias = @host_alias@
64053
 
+host_cpu = @host_cpu@
64054
 
+host_os = @host_os@
64055
 
+host_vendor = @host_vendor@
64056
 
+htmldir = @htmldir@
64057
 
+includedir = @includedir@
64058
 
+infodir = @infodir@
64059
 
+install_sh = @install_sh@
64060
 
+libdir = @libdir@
64061
 
+libexecdir = @libexecdir@
64062
 
+localedir = @localedir@
64063
 
+localstatedir = @localstatedir@
64064
 
+lt_ECHO = @lt_ECHO@
64065
 
+mandir = @mandir@
64066
 
+mkdir_p = @mkdir_p@
64067
 
+moduledir = @moduledir@
64068
 
+oldincludedir = @oldincludedir@
64069
 
+pdfdir = @pdfdir@
64070
 
+prefix = @prefix@
64071
 
+program_transform_name = @program_transform_name@
64072
 
+psdir = @psdir@
64073
 
+sbindir = @sbindir@
64074
 
+sharedstatedir = @sharedstatedir@
64075
 
+srcdir = @srcdir@
64076
 
+sysconfdir = @sysconfdir@
64077
 
+target_alias = @target_alias@
64078
 
+top_build_prefix = @top_build_prefix@
64079
 
+top_builddir = @top_builddir@
64080
 
+top_srcdir = @top_srcdir@
64081
 
+@BUILD_UNFINISHED_TRUE@UNFINISHED = 
64082
 
+SUBDIRS = \
64083
 
+       vacation \
64084
 
+       subaddress \
64085
 
+       comparator-i-ascii-numeric \
64086
 
+       relational \
64087
 
+       regex \
64088
 
+       imap4flags \
64089
 
+       copy \
64090
 
+       include \
64091
 
+       body \
64092
 
+       variables \
64093
 
+       enotify \
64094
 
+       notify \
64095
 
+       environment \
64096
 
+       mailbox \
64097
 
+       date \
64098
 
+       $(UNFINISHED)
64099
 
+
64100
 
+all: all-recursive
64101
 
+
64102
 
+.SUFFIXES:
64103
 
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
64104
 
+       @for dep in $?; do \
64105
 
+         case '$(am__configure_deps)' in \
64106
 
+           *$$dep*) \
64107
 
+             ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
64108
 
+               && { if test -f $@; then exit 0; else break; fi; }; \
64109
 
+             exit 1;; \
64110
 
+         esac; \
64111
 
+       done; \
64112
 
+       echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign  src/lib-sieve/plugins/Makefile'; \
64113
 
+       cd $(top_srcdir) && \
64114
 
+         $(AUTOMAKE) --foreign  src/lib-sieve/plugins/Makefile
64115
 
+.PRECIOUS: Makefile
64116
 
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
64117
 
+       @case '$?' in \
64118
 
+         *config.status*) \
64119
 
+           cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
64120
 
+         *) \
64121
 
+           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
64122
 
+           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
64123
 
+       esac;
64124
 
+
64125
 
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
64126
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
64127
 
+
64128
 
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
64129
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
64130
 
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
64131
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
64132
 
+
64133
 
+mostlyclean-libtool:
64134
 
+       -rm -f *.lo
64135
 
+
64136
 
+clean-libtool:
64137
 
+       -rm -rf .libs _libs
64138
 
+
64139
 
+# This directory's subdirectories are mostly independent; you can cd
64140
 
+# into them and run `make' without going through this Makefile.
64141
 
+# To change the values of `make' variables: instead of editing Makefiles,
64142
 
+# (1) if the variable is set in `config.status', edit `config.status'
64143
 
+#     (which will cause the Makefiles to be regenerated when you run `make');
64144
 
+# (2) otherwise, pass the desired values on the `make' command line.
64145
 
+$(RECURSIVE_TARGETS):
64146
 
+       @failcom='exit 1'; \
64147
 
+       for f in x $$MAKEFLAGS; do \
64148
 
+         case $$f in \
64149
 
+           *=* | --[!k]*);; \
64150
 
+           *k*) failcom='fail=yes';; \
64151
 
+         esac; \
64152
 
+       done; \
64153
 
+       dot_seen=no; \
64154
 
+       target=`echo $@ | sed s/-recursive//`; \
64155
 
+       list='$(SUBDIRS)'; for subdir in $$list; do \
64156
 
+         echo "Making $$target in $$subdir"; \
64157
 
+         if test "$$subdir" = "."; then \
64158
 
+           dot_seen=yes; \
64159
 
+           local_target="$$target-am"; \
64160
 
+         else \
64161
 
+           local_target="$$target"; \
64162
 
+         fi; \
64163
 
+         (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
64164
 
+         || eval $$failcom; \
64165
 
+       done; \
64166
 
+       if test "$$dot_seen" = "no"; then \
64167
 
+         $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
64168
 
+       fi; test -z "$$fail"
64169
 
+
64170
 
+$(RECURSIVE_CLEAN_TARGETS):
64171
 
+       @failcom='exit 1'; \
64172
 
+       for f in x $$MAKEFLAGS; do \
64173
 
+         case $$f in \
64174
 
+           *=* | --[!k]*);; \
64175
 
+           *k*) failcom='fail=yes';; \
64176
 
+         esac; \
64177
 
+       done; \
64178
 
+       dot_seen=no; \
64179
 
+       case "$@" in \
64180
 
+         distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
64181
 
+         *) list='$(SUBDIRS)' ;; \
64182
 
+       esac; \
64183
 
+       rev=''; for subdir in $$list; do \
64184
 
+         if test "$$subdir" = "."; then :; else \
64185
 
+           rev="$$subdir $$rev"; \
64186
 
+         fi; \
64187
 
+       done; \
64188
 
+       rev="$$rev ."; \
64189
 
+       target=`echo $@ | sed s/-recursive//`; \
64190
 
+       for subdir in $$rev; do \
64191
 
+         echo "Making $$target in $$subdir"; \
64192
 
+         if test "$$subdir" = "."; then \
64193
 
+           local_target="$$target-am"; \
64194
 
+         else \
64195
 
+           local_target="$$target"; \
64196
 
+         fi; \
64197
 
+         (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
64198
 
+         || eval $$failcom; \
64199
 
+       done && test -z "$$fail"
64200
 
+tags-recursive:
64201
 
+       list='$(SUBDIRS)'; for subdir in $$list; do \
64202
 
+         test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
64203
 
+       done
64204
 
+ctags-recursive:
64205
 
+       list='$(SUBDIRS)'; for subdir in $$list; do \
64206
 
+         test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
64207
 
+       done
64208
 
+
64209
 
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
64210
 
+       list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
64211
 
+       unique=`for i in $$list; do \
64212
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
64213
 
+         done | \
64214
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
64215
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
64216
 
+       mkid -fID $$unique
64217
 
+tags: TAGS
64218
 
+
64219
 
+TAGS: tags-recursive $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
64220
 
+               $(TAGS_FILES) $(LISP)
64221
 
+       tags=; \
64222
 
+       here=`pwd`; \
64223
 
+       if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
64224
 
+         include_option=--etags-include; \
64225
 
+         empty_fix=.; \
64226
 
+       else \
64227
 
+         include_option=--include; \
64228
 
+         empty_fix=; \
64229
 
+       fi; \
64230
 
+       list='$(SUBDIRS)'; for subdir in $$list; do \
64231
 
+         if test "$$subdir" = .; then :; else \
64232
 
+           test ! -f $$subdir/TAGS || \
64233
 
+             tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \
64234
 
+         fi; \
64235
 
+       done; \
64236
 
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
64237
 
+       unique=`for i in $$list; do \
64238
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
64239
 
+         done | \
64240
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
64241
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
64242
 
+       if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
64243
 
+         test -n "$$unique" || unique=$$empty_fix; \
64244
 
+         $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
64245
 
+           $$tags $$unique; \
64246
 
+       fi
64247
 
+ctags: CTAGS
64248
 
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
64249
 
+               $(TAGS_FILES) $(LISP)
64250
 
+       tags=; \
64251
 
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
64252
 
+       unique=`for i in $$list; do \
64253
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
64254
 
+         done | \
64255
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
64256
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
64257
 
+       test -z "$(CTAGS_ARGS)$$tags$$unique" \
64258
 
+         || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
64259
 
+            $$tags $$unique
64260
 
+
64261
 
+GTAGS:
64262
 
+       here=`$(am__cd) $(top_builddir) && pwd` \
64263
 
+         && cd $(top_srcdir) \
64264
 
+         && gtags -i $(GTAGS_ARGS) $$here
64265
 
+
64266
 
+distclean-tags:
64267
 
+       -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
64268
 
+
64269
 
+distdir: $(DISTFILES)
64270
 
+       @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
64271
 
+       topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
64272
 
+       list='$(DISTFILES)'; \
64273
 
+         dist_files=`for file in $$list; do echo $$file; done | \
64274
 
+         sed -e "s|^$$srcdirstrip/||;t" \
64275
 
+             -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
64276
 
+       case $$dist_files in \
64277
 
+         */*) $(MKDIR_P) `echo "$$dist_files" | \
64278
 
+                          sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
64279
 
+                          sort -u` ;; \
64280
 
+       esac; \
64281
 
+       for file in $$dist_files; do \
64282
 
+         if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
64283
 
+         if test -d $$d/$$file; then \
64284
 
+           dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
64285
 
+           if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
64286
 
+             cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
64287
 
+           fi; \
64288
 
+           cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
64289
 
+         else \
64290
 
+           test -f $(distdir)/$$file \
64291
 
+           || cp -p $$d/$$file $(distdir)/$$file \
64292
 
+           || exit 1; \
64293
 
+         fi; \
64294
 
+       done
64295
 
+       list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
64296
 
+         if test "$$subdir" = .; then :; else \
64297
 
+           test -d "$(distdir)/$$subdir" \
64298
 
+           || $(MKDIR_P) "$(distdir)/$$subdir" \
64299
 
+           || exit 1; \
64300
 
+           distdir=`$(am__cd) $(distdir) && pwd`; \
64301
 
+           top_distdir=`$(am__cd) $(top_distdir) && pwd`; \
64302
 
+           (cd $$subdir && \
64303
 
+             $(MAKE) $(AM_MAKEFLAGS) \
64304
 
+               top_distdir="$$top_distdir" \
64305
 
+               distdir="$$distdir/$$subdir" \
64306
 
+               am__remove_distdir=: \
64307
 
+               am__skip_length_check=: \
64308
 
+               distdir) \
64309
 
+             || exit 1; \
64310
 
+         fi; \
64311
 
+       done
64312
 
+check-am: all-am
64313
 
+check: check-recursive
64314
 
+all-am: Makefile
64315
 
+installdirs: installdirs-recursive
64316
 
+installdirs-am:
64317
 
+install: install-recursive
64318
 
+install-exec: install-exec-recursive
64319
 
+install-data: install-data-recursive
64320
 
+uninstall: uninstall-recursive
64321
 
+
64322
 
+install-am: all-am
64323
 
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
64324
 
+
64325
 
+installcheck: installcheck-recursive
64326
 
+install-strip:
64327
 
+       $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
64328
 
+         install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
64329
 
+         `test -z '$(STRIP)' || \
64330
 
+           echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
64331
 
+mostlyclean-generic:
64332
 
+
64333
 
+clean-generic:
64334
 
+
64335
 
+distclean-generic:
64336
 
+       -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
64337
 
+
64338
 
+maintainer-clean-generic:
64339
 
+       @echo "This command is intended for maintainers to use"
64340
 
+       @echo "it deletes files that may require special tools to rebuild."
64341
 
+clean: clean-recursive
64342
 
+
64343
 
+clean-am: clean-generic clean-libtool mostlyclean-am
64344
 
+
64345
 
+distclean: distclean-recursive
64346
 
+       -rm -f Makefile
64347
 
+distclean-am: clean-am distclean-generic distclean-tags
64348
 
+
64349
 
+dvi: dvi-recursive
64350
 
+
64351
 
+dvi-am:
64352
 
+
64353
 
+html: html-recursive
64354
 
+
64355
 
+info: info-recursive
64356
 
+
64357
 
+info-am:
64358
 
+
64359
 
+install-data-am:
64360
 
+
64361
 
+install-dvi: install-dvi-recursive
64362
 
+
64363
 
+install-exec-am:
64364
 
+
64365
 
+install-html: install-html-recursive
64366
 
+
64367
 
+install-info: install-info-recursive
64368
 
+
64369
 
+install-man:
64370
 
+
64371
 
+install-pdf: install-pdf-recursive
64372
 
+
64373
 
+install-ps: install-ps-recursive
64374
 
+
64375
 
+installcheck-am:
64376
 
+
64377
 
+maintainer-clean: maintainer-clean-recursive
64378
 
+       -rm -f Makefile
64379
 
+maintainer-clean-am: distclean-am maintainer-clean-generic
64380
 
+
64381
 
+mostlyclean: mostlyclean-recursive
64382
 
+
64383
 
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
64384
 
+
64385
 
+pdf: pdf-recursive
64386
 
+
64387
 
+pdf-am:
64388
 
+
64389
 
+ps: ps-recursive
64390
 
+
64391
 
+ps-am:
64392
 
+
64393
 
+uninstall-am:
64394
 
+
64395
 
+.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) install-am \
64396
 
+       install-strip
64397
 
+
64398
 
+.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
64399
 
+       all all-am check check-am clean clean-generic clean-libtool \
64400
 
+       ctags ctags-recursive distclean distclean-generic \
64401
 
+       distclean-libtool distclean-tags distdir dvi dvi-am html \
64402
 
+       html-am info info-am install install-am install-data \
64403
 
+       install-data-am install-dvi install-dvi-am install-exec \
64404
 
+       install-exec-am install-html install-html-am install-info \
64405
 
+       install-info-am install-man install-pdf install-pdf-am \
64406
 
+       install-ps install-ps-am install-strip installcheck \
64407
 
+       installcheck-am installdirs installdirs-am maintainer-clean \
64408
 
+       maintainer-clean-generic mostlyclean mostlyclean-generic \
64409
 
+       mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \
64410
 
+       uninstall uninstall-am
64411
 
+
64412
 
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
64413
 
+# Otherwise a system limit (for SysV at least) may be exceeded.
64414
 
+.NOEXPORT:
64415
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/notify/cmd-denotify.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/notify/cmd-denotify.c
64416
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/notify/cmd-denotify.c  1970-01-01 01:00:00.000000000 +0100
64417
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/notify/cmd-denotify.c   2009-07-27 13:30:18.000000000 +0200
64418
 
@@ -0,0 +1,306 @@
64419
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
64420
 
+ */
64421
 
+
64422
 
+#include "lib.h"
64423
 
+
64424
 
+#include "sieve-common.h"
64425
 
+#include "sieve-code.h"
64426
 
+#include "sieve-extensions.h"
64427
 
+#include "sieve-ast.h"
64428
 
+#include "sieve-commands.h"
64429
 
+#include "sieve-match-types.h"
64430
 
+#include "sieve-comparators.h"
64431
 
+#include "sieve-actions.h"
64432
 
+#include "sieve-validator.h"
64433
 
+#include "sieve-generator.h"
64434
 
+#include "sieve-interpreter.h"
64435
 
+#include "sieve-dump.h"
64436
 
+#include "sieve-result.h"
64437
 
+
64438
 
+#include "ext-notify-common.h"
64439
 
64440
 
+/* 
64441
 
+ * Denotify command (NOT IMPLEMENTED)
64442
 
+ *
64443
 
+ * Syntax:
64444
 
+ *   denotify [MATCH-TYPE string] [<":low" / ":normal" / ":high">]
64445
 
+ */
64446
 
+
64447
 
+static bool cmd_denotify_registered
64448
 
+       (struct sieve_validator *valdtr, struct sieve_command_registration *cmd_reg);
64449
 
+static bool cmd_denotify_generate
64450
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx);
64451
 
+
64452
 
+const struct sieve_command cmd_denotify = {
64453
 
+       "denotify",
64454
 
+       SCT_COMMAND,
64455
 
+       0, 0, FALSE, FALSE,
64456
 
+       cmd_denotify_registered,
64457
 
+       NULL,
64458
 
+       NULL, 
64459
 
+       cmd_denotify_generate, 
64460
 
+       NULL
64461
 
+};
64462
 
+
64463
 
+/*
64464
 
+ * Tagged arguments
64465
 
+ */
64466
 
+
64467
 
+/* Forward declarations */
64468
 
+
64469
 
+static bool tag_match_type_is_instance_of
64470
 
+       (struct sieve_validator *validator, struct sieve_command_context *cmd,
64471
 
+               struct sieve_ast_argument *arg);
64472
 
+static bool tag_match_type_validate
64473
 
+       (struct sieve_validator *validator, struct sieve_ast_argument **arg,
64474
 
+               struct sieve_command_context *cmd);
64475
 
+
64476
 
+/* Argument object */
64477
 
+
64478
 
+const struct sieve_argument denotify_match_tag = {
64479
 
+       "MATCH-TYPE-STRING",
64480
 
+       tag_match_type_is_instance_of,
64481
 
+       NULL,
64482
 
+       tag_match_type_validate,
64483
 
+       NULL, NULL
64484
 
+};
64485
 
+
64486
 
+/* Codes for optional operands */
64487
 
+
64488
 
+enum cmd_denotify_optional {
64489
 
+  OPT_END,
64490
 
+  OPT_IMPORTANCE,
64491
 
+  OPT_MATCH_TYPE,
64492
 
+       OPT_MATCH_KEY
64493
 
+};
64494
 
+
64495
 
+/* 
64496
 
+ * Denotify operation 
64497
 
+ */
64498
 
+
64499
 
+static bool cmd_denotify_operation_dump
64500
 
+       (const struct sieve_operation *op ATTR_UNUSED,
64501
 
+               const struct sieve_dumptime_env *denv, sieve_size_t *address);
64502
 
+static int cmd_denotify_operation_execute
64503
 
+       (const struct sieve_operation *op ATTR_UNUSED,
64504
 
+               const struct sieve_runtime_env *renv, sieve_size_t *address);
64505
 
+
64506
 
+const struct sieve_operation denotify_operation = { 
64507
 
+       "DENOTIFY",
64508
 
+       &notify_extension,
64509
 
+       EXT_NOTIFY_OPERATION_DENOTIFY,
64510
 
+       cmd_denotify_operation_dump,
64511
 
+       cmd_denotify_operation_execute
64512
 
+};
64513
 
+
64514
 
+/*
64515
 
+ * Tag validation
64516
 
+ */
64517
 
+
64518
 
+static bool tag_match_type_is_instance_of
64519
 
+(struct sieve_validator *valdtr, struct sieve_command_context *cmd,
64520
 
+       struct sieve_ast_argument *arg)
64521
 
+{
64522
 
+       return match_type_tag.is_instance_of(valdtr, cmd, arg);
64523
 
+}
64524
 
+
64525
 
+static bool tag_match_type_validate
64526
 
+(struct sieve_validator *valdtr, struct sieve_ast_argument **arg,
64527
 
+       struct sieve_command_context *cmd)
64528
 
+{
64529
 
+       struct sieve_ast_argument *tag = *arg;
64530
 
+
64531
 
+       if ( !match_type_tag.validate(valdtr, arg, cmd) )
64532
 
+               return FALSE;
64533
 
+
64534
 
+       if ( *arg == NULL ) {
64535
 
+               sieve_argument_validate_error(valdtr, tag, 
64536
 
+                       "the MATCH-TYPE argument (:%s) for the denotify command requires "
64537
 
+                       "an additional key-string paramterer, but no more arguments were found", 
64538
 
+                       sieve_ast_argument_tag(tag));
64539
 
+               return FALSE;   
64540
 
+       }
64541
 
+       
64542
 
+       if ( sieve_ast_argument_type(*arg) != SAAT_STRING ) 
64543
 
+       {
64544
 
+               sieve_argument_validate_error(valdtr, *arg, 
64545
 
+                       "the MATCH-TYPE argument (:%s) for the denotify command requires "
64546
 
+                       "an additional key-string parameter, but %s was found", 
64547
 
+                       sieve_ast_argument_tag(tag), sieve_ast_argument_name(*arg));
64548
 
+               return FALSE;
64549
 
+       }
64550
 
+
64551
 
+       if ( !sieve_validator_argument_activate(valdtr, cmd, *arg, FALSE) ) 
64552
 
+               return FALSE;
64553
 
+
64554
 
+       if ( !sieve_match_type_validate
64555
 
+               (valdtr, cmd, *arg, &is_match_type, &i_octet_comparator) )
64556
 
+               return FALSE;
64557
 
+
64558
 
+       tag->argument = &match_type_tag;
64559
 
+
64560
 
+       (*arg)->arg_id_code = OPT_MATCH_KEY;
64561
 
+
64562
 
+       *arg = sieve_ast_argument_next(*arg);
64563
 
+
64564
 
+       return TRUE;
64565
 
+}
64566
 
+
64567
 
+/*
64568
 
+ * Command registration
64569
 
+ */
64570
 
+
64571
 
+static bool cmd_denotify_registered
64572
 
+(struct sieve_validator *valdtr, struct sieve_command_registration *cmd_reg)
64573
 
+{
64574
 
+       sieve_validator_register_tag
64575
 
+               (valdtr, cmd_reg, &denotify_match_tag, OPT_MATCH_TYPE);
64576
 
+
64577
 
+       ext_notify_register_importance_tags(valdtr, cmd_reg, OPT_IMPORTANCE);
64578
 
+
64579
 
+       return TRUE;
64580
 
+}
64581
 
+
64582
 
+/*
64583
 
+ * Code generation
64584
 
+ */
64585
 
+
64586
 
+static bool cmd_denotify_generate
64587
 
+(const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx)
64588
 
+{
64589
 
+       sieve_operation_emit_code(cgenv->sbin, &denotify_operation);
64590
 
+
64591
 
+       /* Emit source line */
64592
 
+       sieve_code_source_line_emit(cgenv->sbin, sieve_command_source_line(ctx));
64593
 
+
64594
 
+       /* Generate arguments */
64595
 
+       return sieve_generate_arguments(cgenv, ctx, NULL);
64596
 
+}
64597
 
+
64598
 
+/* 
64599
 
+ * Code dump
64600
 
+ */
64601
 
64602
 
+static bool cmd_denotify_operation_dump
64603
 
+(const struct sieve_operation *op ATTR_UNUSED,
64604
 
+       const struct sieve_dumptime_env *denv, sieve_size_t *address)
64605
 
+{      
64606
 
+       int opt_code = 1;
64607
 
+       
64608
 
+       sieve_code_dumpf(denv, "%s", op->mnemonic);
64609
 
+       sieve_code_descend(denv);       
64610
 
+
64611
 
+       /* Source line */
64612
 
+       if ( !sieve_code_source_line_dump(denv, address) )
64613
 
+               return FALSE;
64614
 
+
64615
 
+       /* Dump optional operands */
64616
 
+       if ( sieve_operand_optional_present(denv->sbin, address) ) {
64617
 
+               while ( opt_code != 0 ) {
64618
 
+                       sieve_code_mark(denv);
64619
 
+                       
64620
 
+                       if ( !sieve_operand_optional_read(denv->sbin, address, &opt_code) ) 
64621
 
+                               return FALSE;
64622
 
+
64623
 
+                       switch ( opt_code ) {
64624
 
+                       case 0:
64625
 
+                               break;
64626
 
+                       case OPT_MATCH_KEY:
64627
 
+                               if ( !sieve_opr_string_dump(denv, address, "key-string") )
64628
 
+                                       return FALSE;
64629
 
+                               break;
64630
 
+                       case OPT_MATCH_TYPE:
64631
 
+                               if ( !sieve_opr_match_type_dump(denv, address) )
64632
 
+                                       return FALSE;
64633
 
+                               break;
64634
 
+                       case OPT_IMPORTANCE:
64635
 
+                               if ( !sieve_opr_number_dump(denv, address, "importance") )
64636
 
+                                       return FALSE;
64637
 
+                               break;
64638
 
+                       default:
64639
 
+                               return FALSE;
64640
 
+                       }
64641
 
+               }
64642
 
+       }
64643
 
+       
64644
 
+       return TRUE;
64645
 
+}
64646
 
+
64647
 
+/* 
64648
 
+ * Code execution
64649
 
+ */
64650
 
+
64651
 
+static int cmd_denotify_operation_execute
64652
 
+(const struct sieve_operation *op ATTR_UNUSED,
64653
 
+       const struct sieve_runtime_env *renv, sieve_size_t *address)
64654
 
+{      
64655
 
+       int opt_code = 1;
64656
 
+       sieve_number_t importance = 1;
64657
 
+       const struct sieve_match_type *match_type = NULL;
64658
 
+       string_t *match_key = NULL; 
64659
 
+       unsigned int source_line;
64660
 
+
64661
 
+       /*
64662
 
+        * Read operands
64663
 
+        */
64664
 
+               
64665
 
+       /* Source line */
64666
 
+       if ( !sieve_code_source_line_read(renv, address, &source_line) ) {
64667
 
+               sieve_runtime_trace_error(renv, "invalid source line");
64668
 
+               return SIEVE_EXEC_BIN_CORRUPT;
64669
 
+       }
64670
 
+       
64671
 
+       /* Optional operands */ 
64672
 
+       if ( sieve_operand_optional_present(renv->sbin, address) ) {
64673
 
+               while ( opt_code != 0 ) {
64674
 
+                       if ( !sieve_operand_optional_read(renv->sbin, address, &opt_code) ) {
64675
 
+                               sieve_runtime_trace_error(renv, "invalid optional operand");
64676
 
+                               return SIEVE_EXEC_BIN_CORRUPT;
64677
 
+                       }
64678
 
+
64679
 
+                       switch ( opt_code ) {
64680
 
+                       case 0:
64681
 
+                               break;
64682
 
+                       case OPT_MATCH_TYPE:
64683
 
+                               if ( (match_type = sieve_opr_match_type_read(renv, address)) == NULL ) {
64684
 
+                                       sieve_runtime_trace_error(renv, "invalid match type operand");
64685
 
+                                       return SIEVE_EXEC_BIN_CORRUPT;
64686
 
+                               }
64687
 
+                               break;
64688
 
+                       case OPT_MATCH_KEY:
64689
 
+                               if ( !sieve_opr_string_read(renv, address, &match_key) ) {
64690
 
+                                       sieve_runtime_trace_error(renv, "invalid from operand");
64691
 
+                                       return SIEVE_EXEC_BIN_CORRUPT;
64692
 
+                               }
64693
 
+                               break;
64694
 
+                       case OPT_IMPORTANCE:
64695
 
+                               if ( !sieve_opr_number_read(renv, address, &importance) ) {
64696
 
+                                       sieve_runtime_trace_error(renv, "invalid importance operand");
64697
 
+                                       return SIEVE_EXEC_BIN_CORRUPT;
64698
 
+                               }
64699
 
+       
64700
 
+                               /* Enforce 0 < importance < 4 (just to be sure) */
64701
 
+                               if ( importance < 1 ) 
64702
 
+                                       importance = 1;
64703
 
+                               else if ( importance > 3 )
64704
 
+                                       importance = 3;
64705
 
+                               break;
64706
 
+                       default:
64707
 
+                               sieve_runtime_trace_error(renv, "unknown optional operand: %d", 
64708
 
+                                       opt_code);
64709
 
+                               return SIEVE_EXEC_BIN_CORRUPT;
64710
 
+                       }
64711
 
+               }
64712
 
+       }
64713
 
+               
64714
 
+       /*
64715
 
+        * Perform operation
64716
 
+        */
64717
 
+
64718
 
+       sieve_runtime_trace(renv, "DENOTIFY action");   
64719
 
+
64720
 
+       return SIEVE_EXEC_OK;
64721
 
+}
64722
 
+
64723
 
+
64724
 
+
64725
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/notify/cmd-notify.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/notify/cmd-notify.c
64726
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/notify/cmd-notify.c    1970-01-01 01:00:00.000000000 +0100
64727
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/notify/cmd-notify.c     2009-07-27 13:30:18.000000000 +0200
64728
 
@@ -0,0 +1,915 @@
64729
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
64730
 
+ */
64731
 
+
64732
 
+#include "lib.h"
64733
 
+#include "array.h"
64734
 
+#include "str.h"
64735
 
+#include "ioloop.h"
64736
 
+#include "str-sanitize.h"
64737
 
+#include "message-date.h"
64738
 
+#include "mail-storage.h"
64739
 
+
64740
 
+#include "rfc2822.h"
64741
 
+
64742
 
+#include "sieve-common.h"
64743
 
+#include "sieve-code.h"
64744
 
+#include "sieve-extensions.h"
64745
 
+#include "sieve-commands.h"
64746
 
+#include "sieve-actions.h"
64747
 
+#include "sieve-validator.h"
64748
 
+#include "sieve-generator.h"
64749
 
+#include "sieve-interpreter.h"
64750
 
+#include "sieve-dump.h"
64751
 
+#include "sieve-result.h"
64752
 
+#include "sieve-address.h"
64753
 
+#include "sieve-message.h"
64754
 
+
64755
 
+#include "ext-notify-common.h"
64756
 
+#include "ext-notify-limits.h"
64757
 
+
64758
 
+#include <ctype.h>
64759
 
+
64760
 
+/* Notify command (DEPRECATED)
64761
 
+ *
64762
 
+ * Syntax:
64763
 
+ *   notify [":method" string] [":id" string] [":options" string-list]
64764
 
+ *          [<":low" / ":normal" / ":high">] ["message:" string]
64765
 
+ *
64766
 
+ */
64767
 
+
64768
 
+static bool cmd_notify_registered
64769
 
+       (struct sieve_validator *valdtr,
64770
 
+               struct sieve_command_registration *cmd_reg);
64771
 
+static bool cmd_notify_pre_validate
64772
 
+       (struct sieve_validator *valdtr, struct sieve_command_context *cmd);
64773
 
+static bool cmd_notify_validate
64774
 
+       (struct sieve_validator *valdtr, struct sieve_command_context *cmd);
64775
 
+static bool cmd_notify_generate
64776
 
+       (const struct sieve_codegen_env *cgenv, 
64777
 
+               struct sieve_command_context *ctx);
64778
 
+
64779
 
+const struct sieve_command cmd_notify_old = {
64780
 
+       "notify",
64781
 
+       SCT_COMMAND,
64782
 
+       0, 0, FALSE, FALSE,
64783
 
+       cmd_notify_registered,
64784
 
+       cmd_notify_pre_validate,
64785
 
+       cmd_notify_validate,
64786
 
+       cmd_notify_generate, 
64787
 
+       NULL,
64788
 
+};
64789
 
+
64790
 
+/*
64791
 
+ * Tagged arguments
64792
 
+ */
64793
 
+
64794
 
+/* Forward declarations */
64795
 
+
64796
 
+static bool cmd_notify_validate_string_tag
64797
 
+       (struct sieve_validator *valdtr, struct sieve_ast_argument **arg,
64798
 
+               struct sieve_command_context *cmd);
64799
 
+static bool cmd_notify_validate_stringlist_tag
64800
 
+       (struct sieve_validator *valdtr, struct sieve_ast_argument **arg, 
64801
 
+               struct sieve_command_context *cmd);
64802
 
+
64803
 
+/* Argument objects */
64804
 
+
64805
 
+static const struct sieve_argument notify_method_tag = {
64806
 
+       "method",
64807
 
+       NULL, NULL,
64808
 
+       cmd_notify_validate_string_tag,
64809
 
+       NULL, NULL
64810
 
+};
64811
 
+
64812
 
+static const struct sieve_argument notify_options_tag = { 
64813
 
+       "options", 
64814
 
+       NULL, NULL,
64815
 
+       cmd_notify_validate_stringlist_tag, 
64816
 
+       NULL, NULL 
64817
 
+};
64818
 
+
64819
 
+static const struct sieve_argument notify_id_tag = {
64820
 
+       "id",
64821
 
+       NULL, NULL,
64822
 
+       cmd_notify_validate_string_tag,
64823
 
+       NULL, NULL
64824
 
+};
64825
 
+
64826
 
+static const struct sieve_argument notify_message_tag = {
64827
 
+       "message",
64828
 
+       NULL, NULL,
64829
 
+       cmd_notify_validate_string_tag,
64830
 
+       NULL, NULL
64831
 
+};
64832
 
+
64833
 
+/* 
64834
 
+ * Notify operation 
64835
 
+ */
64836
 
+
64837
 
+static bool cmd_notify_operation_dump
64838
 
+       (const struct sieve_operation *op,      
64839
 
+               const struct sieve_dumptime_env *denv, sieve_size_t *address);
64840
 
+static int cmd_notify_operation_execute
64841
 
+       (const struct sieve_operation *op, 
64842
 
+               const struct sieve_runtime_env *renv, sieve_size_t *address);
64843
 
+
64844
 
+const struct sieve_operation notify_old_operation = { 
64845
 
+       "NOTIFY",
64846
 
+       &notify_extension,
64847
 
+       EXT_NOTIFY_OPERATION_NOTIFY,
64848
 
+       cmd_notify_operation_dump, 
64849
 
+       cmd_notify_operation_execute
64850
 
+};
64851
 
+
64852
 
+/* Codes for optional operands */
64853
 
+
64854
 
+enum cmd_notify_optional {
64855
 
+  OPT_END,
64856
 
+  OPT_MESSAGE,
64857
 
+  OPT_IMPORTANCE,
64858
 
+  OPT_OPTIONS,
64859
 
+  OPT_ID
64860
 
+};
64861
 
+
64862
 
+/* 
64863
 
+ * Notify action 
64864
 
+ */
64865
 
+
64866
 
+/* Forward declarations */
64867
 
+
64868
 
+static int act_notify_check_duplicate
64869
 
+       (const struct sieve_runtime_env *renv, 
64870
 
+               const struct sieve_action_data *act,
64871
 
+               const struct sieve_action_data *act_other);
64872
 
+static void act_notify_print
64873
 
+       (const struct sieve_action *action, const struct sieve_result_print_env *rpenv,
64874
 
+               void *context, bool *keep);     
64875
 
+static bool act_notify_commit
64876
 
+       (const struct sieve_action *action,     const struct sieve_action_exec_env *aenv, 
64877
 
+               void *tr_context, bool *keep);
64878
 
+
64879
 
+/* Action object */
64880
 
+
64881
 
+const struct sieve_action act_notify_old = {
64882
 
+       "notify",
64883
 
+       0,
64884
 
+       NULL,
64885
 
+       act_notify_check_duplicate, 
64886
 
+       NULL,
64887
 
+       act_notify_print,
64888
 
+       NULL, NULL,
64889
 
+       act_notify_commit,
64890
 
+       NULL
64891
 
+};
64892
 
+
64893
 
+/*
64894
 
+ * Command validation context
64895
 
+ */
64896
 
+
64897
 
+struct cmd_notify_context_data {
64898
 
+       struct sieve_ast_argument *id;
64899
 
+       struct sieve_ast_argument *method;
64900
 
+       struct sieve_ast_argument *options;
64901
 
+       struct sieve_ast_argument *message;
64902
 
+};
64903
 
+
64904
 
+/*
64905
 
+ * Tag validation
64906
 
+ */
64907
 
+
64908
 
+static bool cmd_notify_validate_string_tag
64909
 
+(struct sieve_validator *valdtr, struct sieve_ast_argument **arg,
64910
 
+    struct sieve_command_context *cmd)
64911
 
+{
64912
 
+       struct sieve_ast_argument *tag = *arg;
64913
 
+       struct cmd_notify_context_data *ctx_data =
64914
 
+               (struct cmd_notify_context_data *) cmd->data;
64915
 
+
64916
 
+       /* Detach the tag itself */
64917
 
+       *arg = sieve_ast_arguments_detach(*arg, 1);
64918
 
+
64919
 
+       /* Check syntax:
64920
 
+        *   :id <string>
64921
 
+        *   :method <string>
64922
 
+        *   :message <string>
64923
 
+        */
64924
 
+       if ( !sieve_validate_tag_parameter(valdtr, cmd, tag, *arg, SAAT_STRING) )
64925
 
+               return FALSE;
64926
 
+
64927
 
+       if ( tag->argument == &notify_method_tag ) {
64928
 
+               ctx_data->method = *arg;
64929
 
+       
64930
 
+               /* Removed */
64931
 
+               *arg = sieve_ast_arguments_detach(*arg, 1);
64932
 
+
64933
 
+       } else if ( tag->argument == &notify_id_tag ) {
64934
 
+               ctx_data->id = *arg;
64935
 
+
64936
 
+               /* Skip parameter */
64937
 
+               *arg = sieve_ast_argument_next(*arg);
64938
 
+
64939
 
+       } else if ( tag->argument == &notify_message_tag ) {
64940
 
+               ctx_data->message = *arg;
64941
 
+
64942
 
+               /* Skip parameter */
64943
 
+               *arg = sieve_ast_argument_next(*arg);
64944
 
+       }
64945
 
+
64946
 
+       return TRUE;
64947
 
+}
64948
 
+
64949
 
+static bool cmd_notify_validate_stringlist_tag
64950
 
+(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, 
64951
 
+       struct sieve_command_context *cmd)
64952
 
+{
64953
 
+       struct sieve_ast_argument *tag = *arg;
64954
 
+       struct cmd_notify_context_data *ctx_data = 
64955
 
+               (struct cmd_notify_context_data *) cmd->data; 
64956
 
+
64957
 
+       /* Detach the tag itself */
64958
 
+       *arg = sieve_ast_arguments_detach(*arg,1);
64959
 
+       
64960
 
+       /* Check syntax:
64961
 
+        *   :options string-list
64962
 
+        */
64963
 
+       if ( !sieve_validate_tag_parameter(valdtr, cmd, tag, *arg, SAAT_STRING_LIST) ) 
64964
 
+               return FALSE;
64965
 
+               
64966
 
+       /* Assign context */
64967
 
+       ctx_data->options = *arg;       
64968
 
+       
64969
 
+       /* Skip parameter */
64970
 
+       *arg = sieve_ast_argument_next(*arg);
64971
 
+
64972
 
+       return TRUE;
64973
 
+}
64974
 
+
64975
 
+/*
64976
 
+ * Command registration
64977
 
+ */
64978
 
+
64979
 
+static bool cmd_notify_registered
64980
 
+(struct sieve_validator *valdtr, struct sieve_command_registration *cmd_reg)
64981
 
+{
64982
 
+       sieve_validator_register_tag
64983
 
+               (valdtr, cmd_reg, &notify_method_tag, 0);
64984
 
+       sieve_validator_register_tag
64985
 
+               (valdtr, cmd_reg, &notify_id_tag, OPT_ID);
64986
 
+       sieve_validator_register_tag
64987
 
+               (valdtr, cmd_reg, &notify_message_tag, OPT_MESSAGE);
64988
 
+       sieve_validator_register_tag
64989
 
+               (valdtr, cmd_reg, &notify_options_tag, OPT_OPTIONS);
64990
 
+
64991
 
+       ext_notify_register_importance_tags(valdtr, cmd_reg, OPT_IMPORTANCE);
64992
 
+
64993
 
+       return TRUE;
64994
 
+}
64995
 
+
64996
 
+/*
64997
 
+ * Command validation
64998
 
+ */
64999
 
+
65000
 
+static bool cmd_notify_pre_validate
65001
 
+(struct sieve_validator *valdtr ATTR_UNUSED,
65002
 
+       struct sieve_command_context *cmd)
65003
 
+{
65004
 
+       struct cmd_notify_context_data *ctx_data;
65005
 
+       
65006
 
+       /* Create context */
65007
 
+       ctx_data = p_new(sieve_command_pool(cmd),       struct cmd_notify_context_data, 1);
65008
 
+       cmd->data = ctx_data;
65009
 
+
65010
 
+       return TRUE;
65011
 
+}
65012
 
+
65013
 
+static int cmd_notify_address_validate
65014
 
+(void *context, struct sieve_ast_argument *arg)
65015
 
+{
65016
 
+       struct sieve_validator *valdtr = (struct sieve_validator *) context;
65017
 
+
65018
 
+       if ( sieve_argument_is_string_literal(arg) ) {
65019
 
+               string_t *address = sieve_ast_argument_str(arg);
65020
 
+               const char *error;
65021
 
+               bool result = FALSE;
65022
 
+
65023
 
+               T_BEGIN {
65024
 
+                       result = sieve_address_validate(address, &error);
65025
 
+
65026
 
+                       if ( !result ) {
65027
 
+                               sieve_argument_validate_error(valdtr, arg,
65028
 
+                                       "specified :options address '%s' is invalid for "
65029
 
+                                       "the mailto notify method: %s",
65030
 
+                                       str_sanitize(str_c(address), 128), error);
65031
 
+                       }
65032
 
+               } T_END;
65033
 
+
65034
 
+               return result;
65035
 
+       }
65036
 
+
65037
 
+       return TRUE;
65038
 
+}
65039
 
+
65040
 
+static bool cmd_notify_validate
65041
 
+(struct sieve_validator *valdtr, struct sieve_command_context *cmd)
65042
 
+{
65043
 
+       struct cmd_notify_context_data *ctx_data =
65044
 
+               (struct cmd_notify_context_data *) cmd->data;
65045
 
+
65046
 
+       /* Check :method argument */
65047
 
+       if ( ctx_data->method != NULL ) {
65048
 
+               const char *method = sieve_ast_argument_strc(ctx_data->method);
65049
 
+               
65050
 
+               if ( strcasecmp(method, "mailto") != 0 ) {
65051
 
+                       sieve_command_validate_error(valdtr, cmd,
65052
 
+                               "the notify command of the deprecated notify extension "
65053
 
+                               "only supports the 'mailto' notification method");
65054
 
+                       return FALSE;
65055
 
+               }
65056
 
+       }
65057
 
+
65058
 
+       /* Check :options argument */
65059
 
+       if ( ctx_data->options != NULL ) {
65060
 
+               struct sieve_ast_argument *option = ctx_data->options;
65061
 
+               
65062
 
+               /* Parse and check options */
65063
 
+               if ( sieve_ast_stringlist_map
65064
 
+                       (&option, (void *) valdtr, cmd_notify_address_validate) <= 0 ) {
65065
 
+                       return FALSE;
65066
 
+               }
65067
 
+       } else {
65068
 
+               sieve_command_validate_warning(valdtr, cmd,
65069
 
+                       "no :options (and hence recipients) specified for the notify command");
65070
 
+       }
65071
 
+
65072
 
+       return TRUE;
65073
 
+}
65074
 
+
65075
 
+/*
65076
 
+ * Code generation
65077
 
+ */
65078
 
+
65079
 
+static bool cmd_notify_generate
65080
 
+(const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx)
65081
 
+{
65082
 
+       sieve_operation_emit_code(cgenv->sbin, &notify_old_operation);
65083
 
+
65084
 
+       /* Emit source line */
65085
 
+       sieve_code_source_line_emit(cgenv->sbin, sieve_command_source_line(ctx));
65086
 
+
65087
 
+       /* Generate arguments */
65088
 
+       return sieve_generate_arguments(cgenv, ctx, NULL);
65089
 
+}
65090
 
+
65091
 
+/* 
65092
 
+ * Code dump
65093
 
+ */
65094
 
65095
 
+static bool cmd_notify_operation_dump
65096
 
+(const struct sieve_operation *op ATTR_UNUSED,
65097
 
+       const struct sieve_dumptime_env *denv, sieve_size_t *address)
65098
 
+{      
65099
 
+       int opt_code = 1;
65100
 
+       
65101
 
+       sieve_code_dumpf(denv, "NOTIFY");
65102
 
+       sieve_code_descend(denv);       
65103
 
+
65104
 
+       /* Source line */
65105
 
+       if ( !sieve_code_source_line_dump(denv, address) )
65106
 
+               return FALSE;
65107
 
+
65108
 
+       /* Dump optional operands */
65109
 
+       if ( sieve_operand_optional_present(denv->sbin, address) ) {
65110
 
+               while ( opt_code != 0 ) {
65111
 
+                       sieve_code_mark(denv);
65112
 
+                       
65113
 
+                       if ( !sieve_operand_optional_read(denv->sbin, address, &opt_code) ) 
65114
 
+                               return FALSE;
65115
 
+
65116
 
+                       switch ( opt_code ) {
65117
 
+                       case 0:
65118
 
+                               break;
65119
 
+                       case OPT_IMPORTANCE:
65120
 
+                               if ( !sieve_opr_number_dump(denv, address, "importance") )
65121
 
+                                       return FALSE;
65122
 
+                               break;
65123
 
+                       case OPT_ID:
65124
 
+                               if ( !sieve_opr_string_dump(denv, address, "id") )
65125
 
+                                       return FALSE;
65126
 
+                               break;
65127
 
+                       case OPT_OPTIONS:
65128
 
+                               if ( !sieve_opr_stringlist_dump(denv, address, "options") )
65129
 
+                                       return FALSE;
65130
 
+                               break;
65131
 
+                       case OPT_MESSAGE:
65132
 
+                               if ( !sieve_opr_string_dump(denv, address, "message") )
65133
 
+                                       return FALSE;
65134
 
+                               break;
65135
 
+                       default:
65136
 
+                               return FALSE;
65137
 
+                       }
65138
 
+               }
65139
 
+       }
65140
 
+       
65141
 
+       return TRUE;
65142
 
+}
65143
 
+
65144
 
+/* 
65145
 
+ * Code execution
65146
 
+ */
65147
 
+
65148
 
+static void cmd_notify_construct_message
65149
 
+(const struct sieve_runtime_env *renv, const char *msg_format, 
65150
 
+       string_t *out_msg)
65151
 
+{
65152
 
+       const struct sieve_message_data *msgdata = renv->msgdata;
65153
 
+  const char *p;
65154
 
+
65155
 
+  if ( msg_format == NULL )
65156
 
+               msg_format = "$from$: $subject$";
65157
 
65158
 
+       /* Scan message for substitutions */
65159
 
+       p = msg_format;
65160
 
+  while ( *p != '\0' ) {
65161
 
+               const char *const *header;
65162
 
+
65163
 
+               if ( strncasecmp(p, "$from$", 6) == 0 ) {
65164
 
+                       p += 6;
65165
 
+               
65166
 
+                       /* Fetch sender from oriinal message */
65167
 
+                       if ( mail_get_headers_utf8(msgdata->mail, "from", &header) >= 0 )
65168
 
+                                str_append(out_msg, header[0]); 
65169
 
+
65170
 
+               } else if ( strncasecmp(p, "$env-from$", 10) == 0 ) {
65171
 
+                       p += 10;
65172
 
+
65173
 
+                       if ( msgdata->return_path != NULL ) 
65174
 
+                               str_append(out_msg, msgdata->return_path);
65175
 
+
65176
 
+               } else if ( strncasecmp(p, "$subject$", 9) == 0 ) {     
65177
 
+                       p += 9;
65178
 
+
65179
 
+                       /* Fetch sender from oriinal message */
65180
 
+                       if ( mail_get_headers_utf8(msgdata->mail, "subject", &header) >= 0 )
65181
 
+                                str_append(out_msg, header[0]); 
65182
 
+                       
65183
 
+               } else if ( strncasecmp(p, "$text", 5) == 0 
65184
 
+                       && (p[5] == '[' || p[5] == '$') ) {
65185
 
+                       size_t num = 0;
65186
 
+                       const char *begin = p;
65187
 
+                       bool valid = TRUE;
65188
 
+
65189
 
+       p += 5;
65190
 
+                       if ( *p == '[' ) {
65191
 
+                               p += 1;
65192
 
+
65193
 
+                               while ( i_isdigit(*p) ) {
65194
 
+                                       num = num * 10 + (*p - '0');
65195
 
+                                       p++;
65196
 
+                               }
65197
 
+
65198
 
+                               if ( *p++ != ']' || *p++ != '$' ) {
65199
 
+                                       str_append_n(out_msg, begin, p-begin);
65200
 
+                                       valid = FALSE;                                                                          
65201
 
+                               }               
65202
 
+                       } else {
65203
 
+                               p += 1;                 
65204
 
+                       }
65205
 
+
65206
 
+                       if ( valid ) {
65207
 
+                               str_append(out_msg, "<body extraction not supported>");
65208
 
+                       }
65209
 
+               } else {
65210
 
+                       size_t len;
65211
 
+
65212
 
+       /* Find next substitution */
65213
 
+       len = strcspn(p + 1, "$") + 1; 
65214
 
+
65215
 
+           /* Copy normal text */
65216
 
+           str_append_n(out_msg, p, len);
65217
 
+           p += len;
65218
 
+               }
65219
 
+  }
65220
 
+}
65221
 
65222
 
+static int cmd_notify_operation_execute
65223
 
+(const struct sieve_operation *op ATTR_UNUSED,
65224
 
+       const struct sieve_runtime_env *renv, sieve_size_t *address)
65225
 
+{      
65226
 
+       struct ext_notify_action *act;
65227
 
+       pool_t pool;
65228
 
+       int opt_code = 1;
65229
 
+       sieve_number_t importance = 1;
65230
 
+       struct sieve_coded_stringlist *options = NULL;
65231
 
+       string_t *message = NULL, *id = NULL; 
65232
 
+       unsigned int source_line;
65233
 
+
65234
 
+       /*
65235
 
+        * Read operands
65236
 
+        */
65237
 
+               
65238
 
+       /* Source line */
65239
 
+       if ( !sieve_code_source_line_read(renv, address, &source_line) ) {
65240
 
+               sieve_runtime_trace_error(renv, "invalid source line");
65241
 
+               return SIEVE_EXEC_BIN_CORRUPT;
65242
 
+       }
65243
 
+       
65244
 
+       /* Optional operands */ 
65245
 
+       if ( sieve_operand_optional_present(renv->sbin, address) ) {
65246
 
+               while ( opt_code != 0 ) {
65247
 
+                       if ( !sieve_operand_optional_read(renv->sbin, address, &opt_code) ) {
65248
 
+                               sieve_runtime_trace_error(renv, "invalid optional operand");
65249
 
+                               return SIEVE_EXEC_BIN_CORRUPT;
65250
 
+                       }
65251
 
+
65252
 
+                       switch ( opt_code ) {
65253
 
+                       case 0:
65254
 
+                               break;
65255
 
+                       case OPT_IMPORTANCE:
65256
 
+                               if ( !sieve_opr_number_read(renv, address, &importance) ) {
65257
 
+                                       sieve_runtime_trace_error(renv, "invalid importance operand");
65258
 
+                                       return SIEVE_EXEC_BIN_CORRUPT;
65259
 
+                               }
65260
 
+       
65261
 
+                               /* Enforce 0 < importance < 4 (just to be sure) */
65262
 
+                               if ( importance < 1 ) 
65263
 
+                                       importance = 1;
65264
 
+                               else if ( importance > 3 )
65265
 
+                                       importance = 3;
65266
 
+                               break;
65267
 
+                       case OPT_ID:
65268
 
+                               if ( !sieve_opr_string_read(renv, address, &id) ) {
65269
 
+                                       sieve_runtime_trace_error(renv, "invalid id operand");
65270
 
+                                       return SIEVE_EXEC_BIN_CORRUPT;
65271
 
+                               }
65272
 
+                               break;
65273
 
+                       case OPT_MESSAGE:
65274
 
+                               if ( !sieve_opr_string_read(renv, address, &message) ) {
65275
 
+                                       sieve_runtime_trace_error(renv, "invalid from operand");
65276
 
+                                       return SIEVE_EXEC_BIN_CORRUPT;
65277
 
+                               }
65278
 
+                               break;
65279
 
+                       case OPT_OPTIONS:
65280
 
+                               if ( (options=sieve_opr_stringlist_read(renv, address)) == NULL ) {
65281
 
+                                       sieve_runtime_trace_error(renv, "invalid options operand");
65282
 
+                                       return SIEVE_EXEC_BIN_CORRUPT;
65283
 
+                               }
65284
 
+                               break;
65285
 
+                       default:
65286
 
+                               sieve_runtime_trace_error(renv, "unknown optional operand: %d", 
65287
 
+                                       opt_code);
65288
 
+                               return SIEVE_EXEC_BIN_CORRUPT;
65289
 
+                       }
65290
 
+               }
65291
 
+       }
65292
 
+               
65293
 
+       /*
65294
 
+        * Perform operation
65295
 
+        */
65296
 
+
65297
 
+       sieve_runtime_trace(renv, "NOTIFY action");     
65298
 
+
65299
 
+       /* Compose action */
65300
 
+       if ( options != NULL ) {
65301
 
+               string_t *raw_address;
65302
 
+               string_t *out_message;
65303
 
+               bool result;    
65304
 
+
65305
 
+               pool = sieve_result_pool(renv->result);
65306
 
+               act = p_new(pool, struct ext_notify_action, 1);
65307
 
+               if ( id != NULL )
65308
 
+                               act->id = p_strdup(pool, str_c(id));
65309
 
+               act->importance = importance;           
65310
 
+       
65311
 
+               /* Process message */
65312
 
+
65313
 
+               out_message = t_str_new(1024);
65314
 
+               cmd_notify_construct_message
65315
 
+                       (renv, (message == NULL ? NULL : str_c(message)), out_message);
65316
 
+               act->message = p_strdup(pool, str_c(out_message));
65317
 
+               
65318
 
+               /* Normalize and verify all :options addresses */                                       
65319
 
+
65320
 
+               sieve_coded_stringlist_reset(options);
65321
 
+                       
65322
 
+               p_array_init(&act->recipients, pool, 4);
65323
 
+               
65324
 
+               raw_address = NULL;
65325
 
+               while ( (result=sieve_coded_stringlist_next_item(options, &raw_address))
65326
 
+                       && raw_address != NULL ) {
65327
 
+                       const char *error = NULL;
65328
 
+                       const char *addr_norm = sieve_address_normalize(raw_address, &error);
65329
 
+                       
65330
 
+                       /* Add if valid address */
65331
 
+                       if ( addr_norm != NULL ) {
65332
 
+                               const struct ext_notify_recipient *rcpts;
65333
 
+                               unsigned int rcpt_count, i;
65334
 
+
65335
 
+                               /* Prevent duplicates */
65336
 
+                               rcpts = array_get(&act->recipients, &rcpt_count);
65337
 
+                               
65338
 
+                               for ( i = 0; i < rcpt_count; i++ ) {
65339
 
+                                       if ( sieve_address_compare
65340
 
+                                               (rcpts[i].normalized, addr_norm, TRUE) == 0 )
65341
 
+                                               break;
65342
 
+                               }
65343
 
+       
65344
 
+                               /* Add only if unique */
65345
 
+                               if ( i != rcpt_count ) {
65346
 
+                                       sieve_runtime_warning(renv, 
65347
 
+                                               sieve_error_script_location(renv->script, source_line),
65348
 
+                                               "duplicate recipient '%s' specified in the :options argument of "
65349
 
+                                               "the deprecated notify command", 
65350
 
+                                               str_sanitize(str_c(raw_address), 128));
65351
 
+
65352
 
+                               }       else if 
65353
 
+                                       ( array_count(&act->recipients) >= EXT_NOTIFY_MAX_RECIPIENTS ) {
65354
 
+                                       sieve_runtime_warning(renv, 
65355
 
+                                               sieve_error_script_location(renv->script, source_line),
65356
 
+                                               "more than the maximum %u recipients are specified "
65357
 
+                                               "for the deprecated notify command; "
65358
 
+                                               "the rest is discarded", EXT_NOTIFY_MAX_RECIPIENTS);
65359
 
+                                       break;
65360
 
+
65361
 
+                               } else {                                                
65362
 
+                                       struct ext_notify_recipient recipient;                  
65363
 
+
65364
 
+                                       recipient.full = p_strdup(pool, str_c(raw_address));
65365
 
+                                       recipient.normalized = p_strdup(pool, addr_norm);
65366
 
+               
65367
 
+                                       array_append(&act->recipients, &recipient, 1);
65368
 
+                               }               
65369
 
+                       } else {
65370
 
+                               sieve_runtime_error(renv, 
65371
 
+                                       sieve_error_script_location(renv->script, source_line),
65372
 
+                                       "specified :options address '%s' is invalid for "
65373
 
+                                       "the deprecated notify command: %s", 
65374
 
+                                       str_sanitize(str_c(raw_address), 128), error);
65375
 
+                               return SIEVE_EXEC_FAILURE;
65376
 
+                       }
65377
 
+               }
65378
 
+               
65379
 
+               if ( !result ) {
65380
 
+                       sieve_runtime_trace_error(renv, "invalid options stringlist");
65381
 
+                       return SIEVE_EXEC_BIN_CORRUPT;
65382
 
+               }
65383
 
+               
65384
 
+               return ( sieve_result_add_action
65385
 
+                       (renv, &act_notify_old, NULL, source_line, (void *) act, 0) >= 0 );
65386
 
+       }
65387
 
+
65388
 
+       return SIEVE_EXEC_OK;
65389
 
+}
65390
 
+
65391
 
+/*
65392
 
+ * Action
65393
 
+ */
65394
 
+
65395
 
+/* Runtime verification */
65396
 
+
65397
 
+static int act_notify_check_duplicate
65398
 
+(const struct sieve_runtime_env *renv ATTR_UNUSED, 
65399
 
+       const struct sieve_action_data *act ATTR_UNUSED,
65400
 
+       const struct sieve_action_data *act_other ATTR_UNUSED)
65401
 
+{
65402
 
+       struct ext_notify_action *new_nact, *old_nact;
65403
 
+       const struct ext_notify_recipient *new_rcpts;
65404
 
+       const struct ext_notify_recipient *old_rcpts;
65405
 
+       unsigned int new_count, old_count, i, j;
65406
 
+       unsigned int del_start = 0, del_len = 0;
65407
 
+               
65408
 
+       if ( act->context == NULL || act_other->context == NULL )
65409
 
+               return 0;
65410
 
+
65411
 
+       new_nact = (struct ext_notify_action *) act->context;
65412
 
+       old_nact = (struct ext_notify_action *) act_other->context;
65413
 
+
65414
 
+       new_rcpts = array_get(&new_nact->recipients, &new_count);
65415
 
+       old_rcpts = array_get(&old_nact->recipients, &old_count);
65416
 
+
65417
 
+       for ( i = 0; i < new_count; i++ ) {
65418
 
+               for ( j = 0; j < old_count; j++ ) {
65419
 
+                       if ( sieve_address_compare
65420
 
+                               (new_rcpts[i].normalized, old_rcpts[j].normalized, TRUE) == 0 )
65421
 
+                               break;                          
65422
 
+               }
65423
 
+
65424
 
+               if ( j == old_count ) {
65425
 
+                       /* Not duplicate */
65426
 
+                       if ( del_len > 0 ) {
65427
 
+                               /* Perform pending deletion */
65428
 
+                               array_delete(&new_nact->recipients, del_start, del_len);
65429
 
+
65430
 
+                               /* Make sure the loop integrity is maintained */
65431
 
+                               i -= del_len;
65432
 
+                               new_rcpts = array_get(&new_nact->recipients, &new_count);
65433
 
+                       }
65434
 
+
65435
 
+                       del_len = 0;            
65436
 
+               } else {
65437
 
+                       /* Mark deletion */
65438
 
+                       if ( del_len == 0 )
65439
 
+                               del_start = i;
65440
 
+                       del_len++;
65441
 
+               }
65442
 
+       }
65443
 
+
65444
 
+       /* Perform pending deletion */
65445
 
+       if ( del_len > 0 ) {
65446
 
+               array_delete(&new_nact->recipients, del_start, del_len);                        
65447
 
+       }
65448
 
+
65449
 
+       return ( array_count(&new_nact->recipients) > 0 ? 0 : 1 );
65450
 
+}
65451
 
+
65452
 
+/* Result printing */
65453
 
65454
 
+static void act_notify_print
65455
 
+(const struct sieve_action *action ATTR_UNUSED, 
65456
 
+       const struct sieve_result_print_env *rpenv, void *context, 
65457
 
+       bool *keep ATTR_UNUSED) 
65458
 
+{
65459
 
+       const struct ext_notify_action *act = 
65460
 
+               (const struct ext_notify_action *) context;
65461
 
+       const struct ext_notify_recipient *recipients;
65462
 
+       unsigned int count, i;
65463
 
+
65464
 
+       sieve_result_action_printf
65465
 
+               ( rpenv, "send (depricated) notification with method 'mailto':");
65466
 
+       
65467
 
+       /* Print main method parameters */
65468
 
+
65469
 
+       sieve_result_printf
65470
 
+               ( rpenv, "    => importance    : %d\n", act->importance);
65471
 
+
65472
 
+       if ( act->message != NULL )
65473
 
+               sieve_result_printf
65474
 
+                       ( rpenv, "    => message       : %s\n", act->message);
65475
 
+
65476
 
+       if ( act->id != NULL )
65477
 
+               sieve_result_printf
65478
 
+                       ( rpenv, "    => id            : %s \n", act->id);
65479
 
+
65480
 
+       /* Print mailto: recipients */
65481
 
+
65482
 
+       sieve_result_printf
65483
 
+               ( rpenv, "    => recipients    :\n" );
65484
 
+
65485
 
+       recipients = array_get(&act->recipients, &count);
65486
 
+       if ( count == 0 ) {
65487
 
+               sieve_result_printf(rpenv, "       NONE, action has no effect\n");
65488
 
+       } else {
65489
 
+               for ( i = 0; i < count; i++ ) {
65490
 
+                       sieve_result_printf
65491
 
+                               ( rpenv, "       + To: %s\n", recipients[i].full);
65492
 
+               }
65493
 
+       }
65494
 
+
65495
 
+       /* Finish output with an empty line */
65496
 
+
65497
 
+       sieve_result_printf(rpenv, "\n");
65498
 
+}
65499
 
+
65500
 
+/* Result execution */
65501
 
+
65502
 
+static bool contains_8bit(const char *msg)
65503
 
+{
65504
 
+       const unsigned char *s = (const unsigned char *)msg;
65505
 
+
65506
 
+       for (; *s != '\0'; s++) {
65507
 
+               if ((*s & 0x80) != 0)
65508
 
+                       return TRUE;
65509
 
+       }
65510
 
+       return FALSE;
65511
 
+}
65512
 
+
65513
 
+static bool act_notify_send
65514
 
+(const struct sieve_action_exec_env *aenv, 
65515
 
+       const struct ext_notify_action *act)
65516
 
+{ 
65517
 
+       const struct sieve_message_data *msgdata = aenv->msgdata;
65518
 
+       const struct sieve_script_env *senv = aenv->scriptenv;
65519
 
+       const struct ext_notify_recipient *recipients;
65520
 
+       void *smtp_handle;
65521
 
+       unsigned int count, i;
65522
 
+       FILE *f;
65523
 
+       const char *outmsgid;
65524
 
+
65525
 
+       /* Get recipients */
65526
 
+       recipients = array_get(&act->recipients, &count);
65527
 
+       if ( count == 0  ) {
65528
 
+               sieve_result_warning(aenv, 
65529
 
+                       "notify action specifies no recipients; action has no effect");
65530
 
+               return TRUE;
65531
 
+       }
65532
 
+
65533
 
+       /* Just to be sure */
65534
 
+       if ( senv->smtp_open == NULL || senv->smtp_close == NULL ) {
65535
 
+               sieve_result_warning(aenv, 
65536
 
+                       "notify action has no means to send mail");
65537
 
+               return TRUE;
65538
 
+       }
65539
 
+       
65540
 
+       /* Send message to all recipients */
65541
 
+       for ( i = 0; i < count; i++ ) {
65542
 
+
65543
 
+               if ( msgdata->return_path != NULL )
65544
 
+                       smtp_handle = senv->smtp_open(recipients[i].normalized, 
65545
 
+                               senv->postmaster_address, &f);
65546
 
+               else            
65547
 
+                       smtp_handle = senv->smtp_open(recipients[i].normalized, NULL, &f);
65548
 
+
65549
 
+               outmsgid = sieve_message_get_new_id(senv);
65550
 
+       
65551
 
+               rfc2822_header_field_write(f, "X-Sieve", SIEVE_IMPLEMENTATION);
65552
 
+               rfc2822_header_field_write(f, "Message-ID", outmsgid);
65553
 
+               rfc2822_header_field_write(f, "Date", message_date_create(ioloop_time));
65554
 
+
65555
 
+               /* Set importance */
65556
 
+               switch ( act->importance ) {
65557
 
+               case 1:
65558
 
+                       rfc2822_header_field_write(f, "X-Priority", "1 (Highest)");
65559
 
+                       rfc2822_header_field_write(f, "Importance", "High");
65560
 
+                       break;
65561
 
+               case 3:
65562
 
+                       rfc2822_header_field_write(f, "X-Priority", "5 (Lowest)");
65563
 
+                       rfc2822_header_field_write(f, "Importance", "Low");
65564
 
+                       break;
65565
 
+               case 2:
65566
 
+               default:
65567
 
+                       rfc2822_header_field_write(f, "X-Priority", "3 (Normal)");
65568
 
+                       rfc2822_header_field_write(f, "Importance", "Normal");
65569
 
+                       break;
65570
 
+               }
65571
 
+
65572
 
+               rfc2822_header_field_printf(f, "From", "%s", 
65573
 
+                       t_strdup_printf("Postmaster <%s>", senv->postmaster_address));
65574
 
+
65575
 
+               rfc2822_header_field_printf(f, "To", "%s", recipients[i].full);
65576
 
+
65577
 
+               rfc2822_header_field_write(f, "Subject", "[SIEVE] New mail notification");
65578
 
+
65579
 
+               rfc2822_header_field_write(f, "Auto-Submitted", "auto-generated (notify)");
65580
 
+               rfc2822_header_field_write(f, "Precedence", "bulk");
65581
 
+
65582
 
+               if (contains_8bit(act->message)) {
65583
 
+                       rfc2822_header_field_write(f, "MIME-Version", "1.0");
65584
 
+                       rfc2822_header_field_write(f, 
65585
 
+                               "Content-Type", "text/plain; charset=UTF-8");
65586
 
+                       rfc2822_header_field_write(f, "Content-Transfer-Encoding", "8bit");
65587
 
+               }
65588
 
+
65589
 
+               /* Generate message body */
65590
 
+               fprintf(f, "\r\n");
65591
 
+               fprintf(f, "%s\r\n", act->message);
65592
 
+                       
65593
 
+               if ( senv->smtp_close(smtp_handle) ) {
65594
 
+                       sieve_result_log(aenv, 
65595
 
+                               "sent mail notification to <%s>", 
65596
 
+                               str_sanitize(recipients[i].normalized, 80));
65597
 
+               } else {
65598
 
+                       sieve_result_error(aenv,
65599
 
+                               "failed to send mail notification to <%s> "
65600
 
+                               "(refer to system log for more information)", 
65601
 
+                               str_sanitize(recipients[i].normalized, 80));
65602
 
+               }
65603
 
+       }
65604
 
+
65605
 
+       return TRUE;
65606
 
+}
65607
 
+
65608
 
+static bool act_notify_commit
65609
 
+(const struct sieve_action *action ATTR_UNUSED, 
65610
 
+       const struct sieve_action_exec_env *aenv, void *tr_context, 
65611
 
+       bool *keep ATTR_UNUSED)
65612
 
+{
65613
 
+       const struct ext_notify_action *act = 
65614
 
+               (const struct ext_notify_action *) tr_context;
65615
 
+       const struct sieve_message_data *msgdata = aenv->msgdata;
65616
 
+       const char *const *headers;
65617
 
+
65618
 
+       /* Is the message an automatic reply ? */
65619
 
+       if ( mail_get_headers
65620
 
+               (msgdata->mail, "auto-submitted", &headers) >= 0 ) {
65621
 
+               const char *const *hdsp = headers;
65622
 
+
65623
 
+               /* Theoretically multiple headers could exist, so lets make sure */
65624
 
+               while ( *hdsp != NULL ) {
65625
 
+                       if ( strcasecmp(*hdsp, "no") != 0 ) {
65626
 
+                               sieve_result_log(aenv, 
65627
 
+                                       "not sending notification for auto-submitted message from <%s>", 
65628
 
+                                       str_sanitize(msgdata->return_path, 128));       
65629
 
+                                       return TRUE;                             
65630
 
+                       }
65631
 
+                       hdsp++;
65632
 
+               }
65633
 
+       }
65634
 
+
65635
 
+       return act_notify_send(aenv, act);
65636
 
+}
65637
 
+
65638
 
+
65639
 
+
65640
 
+
65641
 
+
65642
 
+
65643
 
+
65644
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/notify/ext-notify.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/notify/ext-notify.c
65645
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/notify/ext-notify.c    1970-01-01 01:00:00.000000000 +0100
65646
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/notify/ext-notify.c     2009-07-27 13:30:18.000000000 +0200
65647
 
@@ -0,0 +1,109 @@
65648
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
65649
 
+ */
65650
 
+
65651
 
+/* Extension notify
65652
 
+ * ----------------
65653
 
+ *
65654
 
+ * Authors: Stephan Bosch
65655
 
+ * Specification: draft-ietf-sieve-notify-00.txt
65656
 
+ * Implementation: deprecated; provided for backwards compatibility
65657
 
+ * Status: deprecated
65658
 
+ * 
65659
 
+ */
65660
 
+
65661
 
+/* FIXME: Currently the following CMUSieve features are not supported:
65662
 
+ * 
65663
 
+ * (*) The $text$ substitution is not available for the :message argument.
65664
 
+ */
65665
 
+       
65666
 
+#include <stdio.h>
65667
 
+
65668
 
+#include "sieve-common.h"
65669
 
+
65670
 
+#include "sieve-code.h"
65671
 
+#include "sieve-extensions.h"
65672
 
+#include "sieve-actions.h"
65673
 
+#include "sieve-commands.h"
65674
 
+#include "sieve-validator.h"
65675
 
+#include "sieve-generator.h"
65676
 
+#include "sieve-interpreter.h"
65677
 
+#include "sieve-result.h"
65678
 
+
65679
 
+#include "ext-notify-common.h"
65680
 
+
65681
 
+/*
65682
 
+ * Operations
65683
 
+ */
65684
 
+
65685
 
+const struct sieve_operation *ext_notify_operations[] = {
65686
 
+       &notify_old_operation,
65687
 
+       &denotify_operation
65688
 
+};
65689
 
+
65690
 
+/* 
65691
 
+ * Extension
65692
 
+ */
65693
 
+
65694
 
+static bool ext_notify_validator_load(struct sieve_validator *valdtr);
65695
 
+
65696
 
+static int ext_notify_my_id = -1;
65697
 
+
65698
 
+const struct sieve_extension notify_extension = { 
65699
 
+       "notify", 
65700
 
+       &ext_notify_my_id,
65701
 
+       NULL,
65702
 
+       NULL,
65703
 
+       ext_notify_validator_load, 
65704
 
+       NULL, NULL, NULL, NULL, NULL,
65705
 
+       SIEVE_EXT_DEFINE_OPERATIONS(ext_notify_operations),
65706
 
+       SIEVE_EXT_DEFINE_NO_OPERANDS,
65707
 
+};
65708
 
+
65709
 
+/*
65710
 
+ * Extension validation
65711
 
+ */
65712
 
+
65713
 
+static bool ext_notify_validator_extension_validate
65714
 
+       (struct sieve_validator *valdtr, void *context, 
65715
 
+               struct sieve_ast_argument *require_arg);
65716
 
+
65717
 
+const struct sieve_validator_extension notify_validator_extension = {
65718
 
+       &notify_extension,
65719
 
+       ext_notify_validator_extension_validate,
65720
 
+       NULL
65721
 
+};
65722
 
+
65723
 
+static bool ext_notify_validator_load(struct sieve_validator *valdtr)
65724
 
+{
65725
 
+       /* Register validator extension to check for conflict with enotify */
65726
 
+       sieve_validator_extension_register
65727
 
+               (valdtr, &notify_validator_extension, NULL);
65728
 
+
65729
 
+       /* Register new commands */
65730
 
+       sieve_validator_register_command(valdtr, &cmd_notify_old);
65731
 
+       sieve_validator_register_command(valdtr, &cmd_denotify);
65732
 
+       
65733
 
+       return TRUE;
65734
 
+}
65735
 
+
65736
 
+static bool ext_notify_validator_extension_validate
65737
 
+(struct sieve_validator *valdtr, void *context ATTR_UNUSED,
65738
 
+    struct sieve_ast_argument *require_arg)
65739
 
+{
65740
 
+       const struct sieve_extension *ext;
65741
 
+
65742
 
+       if ( (ext=sieve_extension_get_by_name("enotify")) != NULL ) {
65743
 
+
65744
 
+               /* Check for conflict with enotify */
65745
 
+               if ( sieve_validator_extension_loaded(valdtr, ext) ) {
65746
 
+                       sieve_argument_validate_error(valdtr, require_arg,
65747
 
+                               "the (deprecated) notify extension cannot be used "
65748
 
+                               "together with the enotify extension");
65749
 
+                       return FALSE;
65750
 
+               }
65751
 
+       }
65752
 
+
65753
 
+       return TRUE;
65754
 
+}
65755
 
+
65756
 
+
65757
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/notify/ext-notify-common.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/notify/ext-notify-common.c
65758
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/notify/ext-notify-common.c     1970-01-01 01:00:00.000000000 +0100
65759
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/notify/ext-notify-common.c      2009-07-27 13:30:18.000000000 +0200
65760
 
@@ -0,0 +1,77 @@
65761
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
65762
 
+ */
65763
 
+
65764
 
+#include "lib.h"
65765
 
+
65766
 
+#include "sieve-common.h"
65767
 
+#include "sieve-code.h"
65768
 
+#include "sieve-extensions.h"
65769
 
+#include "sieve-commands.h"
65770
 
+#include "sieve-actions.h"
65771
 
+#include "sieve-validator.h"
65772
 
+#include "sieve-generator.h"
65773
 
+#include "sieve-interpreter.h"
65774
 
+#include "sieve-dump.h"
65775
 
+#include "sieve-result.h"
65776
 
+
65777
 
+#include "ext-notify-common.h"
65778
 
+
65779
 
+/*
65780
 
+ * Importance argument
65781
 
+ */
65782
 
+
65783
 
+static bool tag_importance_validate
65784
 
+       (struct sieve_validator *valdtr, struct sieve_ast_argument **arg,
65785
 
+               struct sieve_command_context *cmd);
65786
 
+
65787
 
+static const struct sieve_argument importance_low_tag = {
65788
 
+       "low",
65789
 
+       NULL, NULL,
65790
 
+       tag_importance_validate,
65791
 
+       NULL, NULL
65792
 
+};
65793
 
+
65794
 
+static const struct sieve_argument importance_normal_tag = {
65795
 
+       "normal",
65796
 
+       NULL, NULL,
65797
 
+       tag_importance_validate,
65798
 
+       NULL, NULL
65799
 
+};
65800
 
+
65801
 
+static const struct sieve_argument importance_high_tag = {
65802
 
+       "high",
65803
 
+       NULL, NULL,
65804
 
+       tag_importance_validate,
65805
 
+       NULL, NULL
65806
 
+};
65807
 
+
65808
 
+static bool tag_importance_validate
65809
 
+(struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_ast_argument **arg,
65810
 
+       struct sieve_command_context *cmd ATTR_UNUSED)
65811
 
+{
65812
 
+       struct sieve_ast_argument *tag = *arg;
65813
 
+
65814
 
+       if ( tag->argument == &importance_low_tag )
65815
 
+               sieve_ast_argument_number_substitute(tag, 3);
65816
 
+       else if ( tag->argument == &importance_normal_tag )
65817
 
+               sieve_ast_argument_number_substitute(tag, 2);
65818
 
+       else
65819
 
+               sieve_ast_argument_number_substitute(tag, 1);
65820
 
+
65821
 
+       tag->argument = &number_argument;
65822
 
+
65823
 
+       /* Skip parameter */
65824
 
+       *arg = sieve_ast_argument_next(*arg);
65825
 
+
65826
 
+       return TRUE;
65827
 
+}
65828
 
+
65829
 
+void ext_notify_register_importance_tags
65830
 
+(struct sieve_validator *valdtr, struct sieve_command_registration *cmd_reg,
65831
 
+       unsigned int id_code)
65832
 
+{
65833
 
+       sieve_validator_register_tag(valdtr, cmd_reg, &importance_low_tag, id_code);
65834
 
+       sieve_validator_register_tag(valdtr, cmd_reg, &importance_normal_tag, id_code);
65835
 
+       sieve_validator_register_tag(valdtr, cmd_reg, &importance_high_tag, id_code);
65836
 
+}
65837
 
+
65838
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/notify/ext-notify-common.h dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/notify/ext-notify-common.h
65839
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/notify/ext-notify-common.h     1970-01-01 01:00:00.000000000 +0100
65840
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/notify/ext-notify-common.h      2009-07-27 13:30:18.000000000 +0200
65841
 
@@ -0,0 +1,57 @@
65842
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
65843
 
+ */
65844
 
+
65845
 
+#ifndef __EXT_NOTIFY_COMMON_H
65846
 
+#define __EXT_NOTIFY_COMMON_H
65847
 
+
65848
 
+/*
65849
 
+ * Extension
65850
 
+ */
65851
 
+
65852
 
+extern const struct sieve_extension notify_extension;
65853
 
+
65854
 
+/*
65855
 
+ * Commands
65856
 
+ */
65857
 
+
65858
 
+extern const struct sieve_command cmd_notify_old;
65859
 
+extern const struct sieve_command cmd_denotify;
65860
 
+
65861
 
+/*
65862
 
+ * Arguments
65863
 
+ */
65864
 
+
65865
 
+void ext_notify_register_importance_tags
65866
 
+       (struct sieve_validator *valdtr, struct sieve_command_registration *cmd_reg,
65867
 
+               unsigned int id_code);
65868
 
+
65869
 
+/*
65870
 
+ * Operations
65871
 
+ */
65872
 
+
65873
 
+extern const struct sieve_operation notify_old_operation;
65874
 
+extern const struct sieve_operation denotify_operation;
65875
 
+
65876
 
+enum ext_notify_opcode {
65877
 
+       EXT_NOTIFY_OPERATION_NOTIFY,
65878
 
+       EXT_NOTIFY_OPERATION_DENOTIFY,
65879
 
+};
65880
 
+
65881
 
+/* Action context */
65882
 
+
65883
 
+struct ext_notify_recipient {
65884
 
+       const char *full;
65885
 
+       const char *normalized;
65886
 
+};
65887
 
+
65888
 
+ARRAY_DEFINE_TYPE(recipients, struct ext_notify_recipient);
65889
 
+               
65890
 
+struct ext_notify_action {
65891
 
+       const char *id;
65892
 
+       const char *message;
65893
 
+       sieve_number_t importance;
65894
 
+
65895
 
+       ARRAY_TYPE(recipients) recipients;
65896
 
+};
65897
 
+
65898
 
+#endif /* __EXT_NOTIFY_COMMON_H */
65899
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/notify/ext-notify-limits.h dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/notify/ext-notify-limits.h
65900
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/notify/ext-notify-limits.h     1970-01-01 01:00:00.000000000 +0100
65901
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/notify/ext-notify-limits.h      2009-07-19 15:54:39.000000000 +0200
65902
 
@@ -0,0 +1,10 @@
65903
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
65904
 
+ */
65905
 
65906
 
+#ifndef __EXT_NOTIFY_LIMITS_H
65907
 
+#define __EXT_NOTIFY_LIMITS_H
65908
 
+
65909
 
+#define EXT_NOTIFY_MAX_RECIPIENTS  8
65910
 
+#define EXT_NOTIFY_MAX_MESSAGE     256
65911
 
+
65912
 
+#endif /* __EXT_NOTIFY_LIMITS_H */
65913
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/notify/Makefile.am dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/notify/Makefile.am
65914
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/notify/Makefile.am     1970-01-01 01:00:00.000000000 +0100
65915
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/notify/Makefile.am      2009-07-27 13:30:18.000000000 +0200
65916
 
@@ -0,0 +1,23 @@
65917
 
+noinst_LTLIBRARIES = libsieve_ext_notify.la
65918
 
+
65919
 
+AM_CPPFLAGS = \
65920
 
+       -I../../ \
65921
 
+       -I../variables \
65922
 
+       -I$(dovecot_incdir) \
65923
 
+       -I$(dovecot_incdir)/src/lib \
65924
 
+       -I$(dovecot_incdir)/src/lib-mail \
65925
 
+       -I$(dovecot_incdir)/src/lib-storage 
65926
 
+
65927
 
+commands = \
65928
 
+       cmd-notify.c \
65929
 
+       cmd-denotify.c
65930
 
+
65931
 
+libsieve_ext_notify_la_SOURCES = \
65932
 
+       ext-notify.c \
65933
 
+       ext-notify-common.c \
65934
 
+       $(commands)
65935
 
+
65936
 
+noinst_HEADERS = \
65937
 
+       ext-notify-common.h \
65938
 
+       ext-notify-limits.h
65939
 
+
65940
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/notify/Makefile.in dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/notify/Makefile.in
65941
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/notify/Makefile.in     1970-01-01 01:00:00.000000000 +0100
65942
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/notify/Makefile.in      2009-08-21 00:55:43.000000000 +0200
65943
 
@@ -0,0 +1,472 @@
65944
 
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
65945
 
+# @configure_input@
65946
 
+
65947
 
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
65948
 
+# 2003, 2004, 2005, 2006, 2007, 2008  Free Software Foundation, Inc.
65949
 
+# This Makefile.in is free software; the Free Software Foundation
65950
 
+# gives unlimited permission to copy and/or distribute it,
65951
 
+# with or without modifications, as long as this notice is preserved.
65952
 
+
65953
 
+# This program is distributed in the hope that it will be useful,
65954
 
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
65955
 
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
65956
 
+# PARTICULAR PURPOSE.
65957
 
+
65958
 
+@SET_MAKE@
65959
 
+
65960
 
+
65961
 
+VPATH = @srcdir@
65962
 
+pkgdatadir = $(datadir)/@PACKAGE@
65963
 
+pkglibdir = $(libdir)/@PACKAGE@
65964
 
+pkgincludedir = $(includedir)/@PACKAGE@
65965
 
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
65966
 
+install_sh_DATA = $(install_sh) -c -m 644
65967
 
+install_sh_PROGRAM = $(install_sh) -c
65968
 
+install_sh_SCRIPT = $(install_sh) -c
65969
 
+INSTALL_HEADER = $(INSTALL_DATA)
65970
 
+transform = $(program_transform_name)
65971
 
+NORMAL_INSTALL = :
65972
 
+PRE_INSTALL = :
65973
 
+POST_INSTALL = :
65974
 
+NORMAL_UNINSTALL = :
65975
 
+PRE_UNINSTALL = :
65976
 
+POST_UNINSTALL = :
65977
 
+build_triplet = @build@
65978
 
+host_triplet = @host@
65979
 
+subdir = src/lib-sieve/plugins/notify
65980
 
+DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
65981
 
+       $(srcdir)/Makefile.in
65982
 
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
65983
 
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
65984
 
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
65985
 
+       $(ACLOCAL_M4)
65986
 
+mkinstalldirs = $(install_sh) -d
65987
 
+CONFIG_HEADER = $(top_builddir)/dummy-config.h \
65988
 
+       $(top_builddir)/dsieve-config.h
65989
 
+CONFIG_CLEAN_FILES =
65990
 
+LTLIBRARIES = $(noinst_LTLIBRARIES)
65991
 
+libsieve_ext_notify_la_LIBADD =
65992
 
+am__objects_1 = cmd-notify.lo cmd-denotify.lo
65993
 
+am_libsieve_ext_notify_la_OBJECTS = ext-notify.lo ext-notify-common.lo \
65994
 
+       $(am__objects_1)
65995
 
+libsieve_ext_notify_la_OBJECTS = $(am_libsieve_ext_notify_la_OBJECTS)
65996
 
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
65997
 
+depcomp = $(SHELL) $(top_srcdir)/depcomp
65998
 
+am__depfiles_maybe = depfiles
65999
 
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
66000
 
+       $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
66001
 
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
66002
 
+       --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
66003
 
+       $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
66004
 
+CCLD = $(CC)
66005
 
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
66006
 
+       --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
66007
 
+       $(LDFLAGS) -o $@
66008
 
+SOURCES = $(libsieve_ext_notify_la_SOURCES)
66009
 
+DIST_SOURCES = $(libsieve_ext_notify_la_SOURCES)
66010
 
+HEADERS = $(noinst_HEADERS)
66011
 
+ETAGS = etags
66012
 
+CTAGS = ctags
66013
 
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
66014
 
+ACLOCAL = @ACLOCAL@
66015
 
+AMTAR = @AMTAR@
66016
 
+AR = @AR@
66017
 
+AUTOCONF = @AUTOCONF@
66018
 
+AUTOHEADER = @AUTOHEADER@
66019
 
+AUTOMAKE = @AUTOMAKE@
66020
 
+AWK = @AWK@
66021
 
+CC = @CC@
66022
 
+CCDEPMODE = @CCDEPMODE@
66023
 
+CFLAGS = @CFLAGS@
66024
 
+CPP = @CPP@
66025
 
+CPPFLAGS = @CPPFLAGS@
66026
 
+CYGPATH_W = @CYGPATH_W@
66027
 
+DEFS = @DEFS@
66028
 
+DEPDIR = @DEPDIR@
66029
 
+DSYMUTIL = @DSYMUTIL@
66030
 
+DUMPBIN = @DUMPBIN@
66031
 
+ECHO_C = @ECHO_C@
66032
 
+ECHO_N = @ECHO_N@
66033
 
+ECHO_T = @ECHO_T@
66034
 
+EGREP = @EGREP@
66035
 
+EXEEXT = @EXEEXT@
66036
 
+FGREP = @FGREP@
66037
 
+GREP = @GREP@
66038
 
+INSTALL = @INSTALL@
66039
 
+INSTALL_DATA = @INSTALL_DATA@
66040
 
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
66041
 
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
66042
 
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
66043
 
+LD = @LD@
66044
 
+LDFLAGS = @LDFLAGS@
66045
 
+LIBICONV = @LIBICONV@
66046
 
+LIBOBJS = @LIBOBJS@
66047
 
+LIBS = @LIBS@
66048
 
+LIBTOOL = @LIBTOOL@
66049
 
+LIPO = @LIPO@
66050
 
+LN_S = @LN_S@
66051
 
+LTLIBOBJS = @LTLIBOBJS@
66052
 
+MAINT = @MAINT@
66053
 
+MAKEINFO = @MAKEINFO@
66054
 
+MKDIR_P = @MKDIR_P@
66055
 
+MODULE_LIBS = @MODULE_LIBS@
66056
 
+NM = @NM@
66057
 
+NMEDIT = @NMEDIT@
66058
 
+OBJDUMP = @OBJDUMP@
66059
 
+OBJEXT = @OBJEXT@
66060
 
+OTOOL = @OTOOL@
66061
 
+OTOOL64 = @OTOOL64@
66062
 
+PACKAGE = @PACKAGE@
66063
 
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
66064
 
+PACKAGE_NAME = @PACKAGE_NAME@
66065
 
+PACKAGE_STRING = @PACKAGE_STRING@
66066
 
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
66067
 
+PACKAGE_URL = @PACKAGE_URL@
66068
 
+PACKAGE_VERSION = @PACKAGE_VERSION@
66069
 
+PATH_SEPARATOR = @PATH_SEPARATOR@
66070
 
+RAND_LIBS = @RAND_LIBS@
66071
 
+RANLIB = @RANLIB@
66072
 
+SED = @SED@
66073
 
+SET_MAKE = @SET_MAKE@
66074
 
+SHELL = @SHELL@
66075
 
+STORAGE_LIBS = @STORAGE_LIBS@
66076
 
+STRIP = @STRIP@
66077
 
+VERSION = @VERSION@
66078
 
+abs_builddir = @abs_builddir@
66079
 
+abs_srcdir = @abs_srcdir@
66080
 
+abs_top_builddir = @abs_top_builddir@
66081
 
+abs_top_srcdir = @abs_top_srcdir@
66082
 
+ac_ct_CC = @ac_ct_CC@
66083
 
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
66084
 
+am__include = @am__include@
66085
 
+am__leading_dot = @am__leading_dot@
66086
 
+am__quote = @am__quote@
66087
 
+am__tar = @am__tar@
66088
 
+am__untar = @am__untar@
66089
 
+bindir = @bindir@
66090
 
+build = @build@
66091
 
+build_alias = @build_alias@
66092
 
+build_cpu = @build_cpu@
66093
 
+build_os = @build_os@
66094
 
+build_vendor = @build_vendor@
66095
 
+builddir = @builddir@
66096
 
+datadir = @datadir@
66097
 
+datarootdir = @datarootdir@
66098
 
+docdir = @docdir@
66099
 
+dovecot_incdir = @dovecot_incdir@
66100
 
+dovecotdir = @dovecotdir@
66101
 
+dvidir = @dvidir@
66102
 
+exec_prefix = @exec_prefix@
66103
 
+host = @host@
66104
 
+host_alias = @host_alias@
66105
 
+host_cpu = @host_cpu@
66106
 
+host_os = @host_os@
66107
 
+host_vendor = @host_vendor@
66108
 
+htmldir = @htmldir@
66109
 
+includedir = @includedir@
66110
 
+infodir = @infodir@
66111
 
+install_sh = @install_sh@
66112
 
+libdir = @libdir@
66113
 
+libexecdir = @libexecdir@
66114
 
+localedir = @localedir@
66115
 
+localstatedir = @localstatedir@
66116
 
+lt_ECHO = @lt_ECHO@
66117
 
+mandir = @mandir@
66118
 
+mkdir_p = @mkdir_p@
66119
 
+moduledir = @moduledir@
66120
 
+oldincludedir = @oldincludedir@
66121
 
+pdfdir = @pdfdir@
66122
 
+prefix = @prefix@
66123
 
+program_transform_name = @program_transform_name@
66124
 
+psdir = @psdir@
66125
 
+sbindir = @sbindir@
66126
 
+sharedstatedir = @sharedstatedir@
66127
 
+srcdir = @srcdir@
66128
 
+sysconfdir = @sysconfdir@
66129
 
+target_alias = @target_alias@
66130
 
+top_build_prefix = @top_build_prefix@
66131
 
+top_builddir = @top_builddir@
66132
 
+top_srcdir = @top_srcdir@
66133
 
+noinst_LTLIBRARIES = libsieve_ext_notify.la
66134
 
+AM_CPPFLAGS = \
66135
 
+       -I../../ \
66136
 
+       -I../variables \
66137
 
+       -I$(dovecot_incdir) \
66138
 
+       -I$(dovecot_incdir)/src/lib \
66139
 
+       -I$(dovecot_incdir)/src/lib-mail \
66140
 
+       -I$(dovecot_incdir)/src/lib-storage 
66141
 
+
66142
 
+commands = \
66143
 
+       cmd-notify.c \
66144
 
+       cmd-denotify.c
66145
 
+
66146
 
+libsieve_ext_notify_la_SOURCES = \
66147
 
+       ext-notify.c \
66148
 
+       ext-notify-common.c \
66149
 
+       $(commands)
66150
 
+
66151
 
+noinst_HEADERS = \
66152
 
+       ext-notify-common.h \
66153
 
+       ext-notify-limits.h
66154
 
+
66155
 
+all: all-am
66156
 
+
66157
 
+.SUFFIXES:
66158
 
+.SUFFIXES: .c .lo .o .obj
66159
 
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
66160
 
+       @for dep in $?; do \
66161
 
+         case '$(am__configure_deps)' in \
66162
 
+           *$$dep*) \
66163
 
+             ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
66164
 
+               && { if test -f $@; then exit 0; else break; fi; }; \
66165
 
+             exit 1;; \
66166
 
+         esac; \
66167
 
+       done; \
66168
 
+       echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign  src/lib-sieve/plugins/notify/Makefile'; \
66169
 
+       cd $(top_srcdir) && \
66170
 
+         $(AUTOMAKE) --foreign  src/lib-sieve/plugins/notify/Makefile
66171
 
+.PRECIOUS: Makefile
66172
 
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
66173
 
+       @case '$?' in \
66174
 
+         *config.status*) \
66175
 
+           cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
66176
 
+         *) \
66177
 
+           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
66178
 
+           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
66179
 
+       esac;
66180
 
+
66181
 
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
66182
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
66183
 
+
66184
 
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
66185
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
66186
 
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
66187
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
66188
 
+
66189
 
+clean-noinstLTLIBRARIES:
66190
 
+       -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
66191
 
+       @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
66192
 
+         dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
66193
 
+         test "$$dir" != "$$p" || dir=.; \
66194
 
+         echo "rm -f \"$${dir}/so_locations\""; \
66195
 
+         rm -f "$${dir}/so_locations"; \
66196
 
+       done
66197
 
+libsieve_ext_notify.la: $(libsieve_ext_notify_la_OBJECTS) $(libsieve_ext_notify_la_DEPENDENCIES) 
66198
 
+       $(LINK)  $(libsieve_ext_notify_la_OBJECTS) $(libsieve_ext_notify_la_LIBADD) $(LIBS)
66199
 
+
66200
 
+mostlyclean-compile:
66201
 
+       -rm -f *.$(OBJEXT)
66202
 
+
66203
 
+distclean-compile:
66204
 
+       -rm -f *.tab.c
66205
 
+
66206
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd-denotify.Plo@am__quote@
66207
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd-notify.Plo@am__quote@
66208
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-notify-common.Plo@am__quote@
66209
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-notify.Plo@am__quote@
66210
 
+
66211
 
+.c.o:
66212
 
+@am__fastdepCC_TRUE@   $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
66213
 
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
66214
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
66215
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
66216
 
+@am__fastdepCC_FALSE@  $(COMPILE) -c $<
66217
 
+
66218
 
+.c.obj:
66219
 
+@am__fastdepCC_TRUE@   $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
66220
 
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
66221
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
66222
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
66223
 
+@am__fastdepCC_FALSE@  $(COMPILE) -c `$(CYGPATH_W) '$<'`
66224
 
+
66225
 
+.c.lo:
66226
 
+@am__fastdepCC_TRUE@   $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
66227
 
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
66228
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
66229
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
66230
 
+@am__fastdepCC_FALSE@  $(LTCOMPILE) -c -o $@ $<
66231
 
+
66232
 
+mostlyclean-libtool:
66233
 
+       -rm -f *.lo
66234
 
+
66235
 
+clean-libtool:
66236
 
+       -rm -rf .libs _libs
66237
 
+
66238
 
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
66239
 
+       list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
66240
 
+       unique=`for i in $$list; do \
66241
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
66242
 
+         done | \
66243
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
66244
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
66245
 
+       mkid -fID $$unique
66246
 
+tags: TAGS
66247
 
+
66248
 
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
66249
 
+               $(TAGS_FILES) $(LISP)
66250
 
+       tags=; \
66251
 
+       here=`pwd`; \
66252
 
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
66253
 
+       unique=`for i in $$list; do \
66254
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
66255
 
+         done | \
66256
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
66257
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
66258
 
+       if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
66259
 
+         test -n "$$unique" || unique=$$empty_fix; \
66260
 
+         $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
66261
 
+           $$tags $$unique; \
66262
 
+       fi
66263
 
+ctags: CTAGS
66264
 
+CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
66265
 
+               $(TAGS_FILES) $(LISP)
66266
 
+       tags=; \
66267
 
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
66268
 
+       unique=`for i in $$list; do \
66269
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
66270
 
+         done | \
66271
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
66272
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
66273
 
+       test -z "$(CTAGS_ARGS)$$tags$$unique" \
66274
 
+         || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
66275
 
+            $$tags $$unique
66276
 
+
66277
 
+GTAGS:
66278
 
+       here=`$(am__cd) $(top_builddir) && pwd` \
66279
 
+         && cd $(top_srcdir) \
66280
 
+         && gtags -i $(GTAGS_ARGS) $$here
66281
 
+
66282
 
+distclean-tags:
66283
 
+       -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
66284
 
+
66285
 
+distdir: $(DISTFILES)
66286
 
+       @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
66287
 
+       topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
66288
 
+       list='$(DISTFILES)'; \
66289
 
+         dist_files=`for file in $$list; do echo $$file; done | \
66290
 
+         sed -e "s|^$$srcdirstrip/||;t" \
66291
 
+             -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
66292
 
+       case $$dist_files in \
66293
 
+         */*) $(MKDIR_P) `echo "$$dist_files" | \
66294
 
+                          sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
66295
 
+                          sort -u` ;; \
66296
 
+       esac; \
66297
 
+       for file in $$dist_files; do \
66298
 
+         if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
66299
 
+         if test -d $$d/$$file; then \
66300
 
+           dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
66301
 
+           if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
66302
 
+             cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
66303
 
+           fi; \
66304
 
+           cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
66305
 
+         else \
66306
 
+           test -f $(distdir)/$$file \
66307
 
+           || cp -p $$d/$$file $(distdir)/$$file \
66308
 
+           || exit 1; \
66309
 
+         fi; \
66310
 
+       done
66311
 
+check-am: all-am
66312
 
+check: check-am
66313
 
+all-am: Makefile $(LTLIBRARIES) $(HEADERS)
66314
 
+installdirs:
66315
 
+install: install-am
66316
 
+install-exec: install-exec-am
66317
 
+install-data: install-data-am
66318
 
+uninstall: uninstall-am
66319
 
+
66320
 
+install-am: all-am
66321
 
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
66322
 
+
66323
 
+installcheck: installcheck-am
66324
 
+install-strip:
66325
 
+       $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
66326
 
+         install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
66327
 
+         `test -z '$(STRIP)' || \
66328
 
+           echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
66329
 
+mostlyclean-generic:
66330
 
+
66331
 
+clean-generic:
66332
 
+
66333
 
+distclean-generic:
66334
 
+       -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
66335
 
+
66336
 
+maintainer-clean-generic:
66337
 
+       @echo "This command is intended for maintainers to use"
66338
 
+       @echo "it deletes files that may require special tools to rebuild."
66339
 
+clean: clean-am
66340
 
+
66341
 
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
66342
 
+       mostlyclean-am
66343
 
+
66344
 
+distclean: distclean-am
66345
 
+       -rm -rf ./$(DEPDIR)
66346
 
+       -rm -f Makefile
66347
 
+distclean-am: clean-am distclean-compile distclean-generic \
66348
 
+       distclean-tags
66349
 
+
66350
 
+dvi: dvi-am
66351
 
+
66352
 
+dvi-am:
66353
 
+
66354
 
+html: html-am
66355
 
+
66356
 
+info: info-am
66357
 
+
66358
 
+info-am:
66359
 
+
66360
 
+install-data-am:
66361
 
+
66362
 
+install-dvi: install-dvi-am
66363
 
+
66364
 
+install-exec-am:
66365
 
+
66366
 
+install-html: install-html-am
66367
 
+
66368
 
+install-info: install-info-am
66369
 
+
66370
 
+install-man:
66371
 
+
66372
 
+install-pdf: install-pdf-am
66373
 
+
66374
 
+install-ps: install-ps-am
66375
 
+
66376
 
+installcheck-am:
66377
 
+
66378
 
+maintainer-clean: maintainer-clean-am
66379
 
+       -rm -rf ./$(DEPDIR)
66380
 
+       -rm -f Makefile
66381
 
+maintainer-clean-am: distclean-am maintainer-clean-generic
66382
 
+
66383
 
+mostlyclean: mostlyclean-am
66384
 
+
66385
 
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
66386
 
+       mostlyclean-libtool
66387
 
+
66388
 
+pdf: pdf-am
66389
 
+
66390
 
+pdf-am:
66391
 
+
66392
 
+ps: ps-am
66393
 
+
66394
 
+ps-am:
66395
 
+
66396
 
+uninstall-am:
66397
 
+
66398
 
+.MAKE: install-am install-strip
66399
 
+
66400
 
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
66401
 
+       clean-libtool clean-noinstLTLIBRARIES ctags distclean \
66402
 
+       distclean-compile distclean-generic distclean-libtool \
66403
 
+       distclean-tags distdir dvi dvi-am html html-am info info-am \
66404
 
+       install install-am install-data install-data-am install-dvi \
66405
 
+       install-dvi-am install-exec install-exec-am install-html \
66406
 
+       install-html-am install-info install-info-am install-man \
66407
 
+       install-pdf install-pdf-am install-ps install-ps-am \
66408
 
+       install-strip installcheck installcheck-am installdirs \
66409
 
+       maintainer-clean maintainer-clean-generic mostlyclean \
66410
 
+       mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
66411
 
+       pdf pdf-am ps ps-am tags uninstall uninstall-am
66412
 
+
66413
 
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
66414
 
+# Otherwise a system limit (for SysV at least) may be exceeded.
66415
 
+.NOEXPORT:
66416
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/regex/ext-regex.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/regex/ext-regex.c
66417
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/regex/ext-regex.c      1970-01-01 01:00:00.000000000 +0100
66418
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/regex/ext-regex.c       2009-01-06 00:15:52.000000000 +0100
66419
 
@@ -0,0 +1,67 @@
66420
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
66421
 
+ */
66422
 
+
66423
 
+/* Extension regex 
66424
 
+ * ---------------
66425
 
+ *
66426
 
+ * Authors: Stephan Bosch
66427
 
+ * Specification: draft-murchison-sieve-regex-07
66428
 
+ * Implementation: full, but suboptimal
66429
 
+ * Status: experimental, largely untested
66430
 
+ *
66431
 
+ * FIXME: Regular expressions are compiled during compilation and 
66432
 
+ * again during interpretation. This is suboptimal and should be 
66433
 
+ * changed. This requires dumping the compiled regex to the binary. 
66434
 
+ * Most likely, this will only be possible when we implement regular
66435
 
+ * expressions ourselves. 
66436
 
+ * 
66437
 
+ */
66438
 
+
66439
 
+#include "lib.h"
66440
 
+#include "mempool.h"
66441
 
+#include "buffer.h"
66442
 
+
66443
 
+#include "sieve-common.h"
66444
 
+
66445
 
+#include "sieve-code.h"
66446
 
+#include "sieve-extensions.h"
66447
 
+#include "sieve-commands.h"
66448
 
+
66449
 
+#include "sieve-comparators.h"
66450
 
+#include "sieve-match-types.h"
66451
 
+
66452
 
+#include "sieve-validator.h"
66453
 
+#include "sieve-generator.h"
66454
 
+#include "sieve-interpreter.h"
66455
 
+
66456
 
+#include "ext-regex-common.h"
66457
 
+
66458
 
+#include <sys/types.h>
66459
 
+#include <regex.h>
66460
 
+
66461
 
+/* 
66462
 
+ * Extension
66463
 
+ */
66464
 
+
66465
 
+static bool ext_regex_validator_load(struct sieve_validator *validator);
66466
 
+
66467
 
+static int ext_my_id = -1;
66468
 
+
66469
 
+const struct sieve_extension regex_extension = { 
66470
 
+       "regex", 
66471
 
+       &ext_my_id,
66472
 
+       NULL, NULL,
66473
 
+       ext_regex_validator_load,
66474
 
+       NULL, NULL, NULL, NULL, NULL,
66475
 
+       SIEVE_EXT_DEFINE_NO_OPERATIONS, 
66476
 
+       SIEVE_EXT_DEFINE_OPERAND(regex_match_type_operand)
66477
 
+};
66478
 
+
66479
 
+static bool ext_regex_validator_load(struct sieve_validator *validator)
66480
 
+{
66481
 
+       sieve_match_type_register(validator, &regex_match_type); 
66482
 
+
66483
 
+       return TRUE;
66484
 
+}
66485
 
+
66486
 
+
66487
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/regex/ext-regex-common.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/regex/ext-regex-common.c
66488
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/regex/ext-regex-common.c       1970-01-01 01:00:00.000000000 +0100
66489
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/regex/ext-regex-common.c        2009-01-06 00:15:52.000000000 +0100
66490
 
@@ -0,0 +1,23 @@
66491
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
66492
 
+ */
66493
 
+
66494
 
+#include "sieve-common.h"
66495
 
+#include "sieve-match-types.h"
66496
 
+
66497
 
+#include "ext-regex-common.h"
66498
 
+
66499
 
+/* 
66500
 
+ * Regex match type operand
66501
 
+ */
66502
 
+
66503
 
+static const struct sieve_extension_objects ext_match_types =
66504
 
+    SIEVE_EXT_DEFINE_MATCH_TYPE(regex_match_type);
66505
 
+
66506
 
+const struct sieve_operand regex_match_type_operand = {
66507
 
+    "regex match",
66508
 
+    &regex_extension,
66509
 
+    0,
66510
 
+    &sieve_match_type_operand_class,
66511
 
+    &ext_match_types
66512
 
+};
66513
 
+
66514
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/regex/ext-regex-common.h dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/regex/ext-regex-common.h
66515
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/regex/ext-regex-common.h       1970-01-01 01:00:00.000000000 +0100
66516
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/regex/ext-regex-common.h        2009-02-24 13:42:43.000000000 +0100
66517
 
@@ -0,0 +1,27 @@
66518
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
66519
 
+ */
66520
 
+
66521
 
+#ifndef __EXT_REGEX_COMMON_H
66522
 
+#define __EXT_REGEX_COMMON_H
66523
 
+
66524
 
+/*
66525
 
+ * Extension
66526
 
+ */
66527
 
+
66528
 
+extern const struct sieve_extension regex_extension;
66529
 
+
66530
 
+/*
66531
 
+ * Operand
66532
 
+ */
66533
 
+
66534
 
+extern const struct sieve_operand regex_match_type_operand;
66535
 
+
66536
 
+/*
66537
 
+ * Match type
66538
 
+ */
66539
 
+
66540
 
+extern const struct sieve_match_type regex_match_type;
66541
 
+
66542
 
+#endif /* __EXT_REGEX_COMMON_H */
66543
 
+
66544
 
+
66545
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/regex/Makefile.am dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/regex/Makefile.am
66546
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/regex/Makefile.am      1970-01-01 01:00:00.000000000 +0100
66547
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/regex/Makefile.am       2008-10-20 01:35:49.000000000 +0200
66548
 
@@ -0,0 +1,16 @@
66549
 
+noinst_LTLIBRARIES = libsieve_ext_regex.la
66550
 
+
66551
 
+AM_CPPFLAGS = \
66552
 
+       -I../../ \
66553
 
+       -I$(dovecot_incdir) \
66554
 
+       -I$(dovecot_incdir)/src/lib \
66555
 
+       -I$(dovecot_incdir)/src/lib-mail \
66556
 
+       -I$(dovecot_incdir)/src/lib-storage 
66557
 
+
66558
 
+libsieve_ext_regex_la_SOURCES = \
66559
 
+       mcht-regex.c \
66560
 
+       ext-regex-common.c \
66561
 
+       ext-regex.c
66562
 
+
66563
 
+noinst_HEADERS = \
66564
 
+       ext-regex-common.h
66565
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/regex/Makefile.in dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/regex/Makefile.in
66566
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/regex/Makefile.in      1970-01-01 01:00:00.000000000 +0100
66567
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/regex/Makefile.in       2009-08-21 00:55:43.000000000 +0200
66568
 
@@ -0,0 +1,464 @@
66569
 
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
66570
 
+# @configure_input@
66571
 
+
66572
 
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
66573
 
+# 2003, 2004, 2005, 2006, 2007, 2008  Free Software Foundation, Inc.
66574
 
+# This Makefile.in is free software; the Free Software Foundation
66575
 
+# gives unlimited permission to copy and/or distribute it,
66576
 
+# with or without modifications, as long as this notice is preserved.
66577
 
+
66578
 
+# This program is distributed in the hope that it will be useful,
66579
 
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
66580
 
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
66581
 
+# PARTICULAR PURPOSE.
66582
 
+
66583
 
+@SET_MAKE@
66584
 
+
66585
 
+
66586
 
+VPATH = @srcdir@
66587
 
+pkgdatadir = $(datadir)/@PACKAGE@
66588
 
+pkglibdir = $(libdir)/@PACKAGE@
66589
 
+pkgincludedir = $(includedir)/@PACKAGE@
66590
 
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
66591
 
+install_sh_DATA = $(install_sh) -c -m 644
66592
 
+install_sh_PROGRAM = $(install_sh) -c
66593
 
+install_sh_SCRIPT = $(install_sh) -c
66594
 
+INSTALL_HEADER = $(INSTALL_DATA)
66595
 
+transform = $(program_transform_name)
66596
 
+NORMAL_INSTALL = :
66597
 
+PRE_INSTALL = :
66598
 
+POST_INSTALL = :
66599
 
+NORMAL_UNINSTALL = :
66600
 
+PRE_UNINSTALL = :
66601
 
+POST_UNINSTALL = :
66602
 
+build_triplet = @build@
66603
 
+host_triplet = @host@
66604
 
+subdir = src/lib-sieve/plugins/regex
66605
 
+DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
66606
 
+       $(srcdir)/Makefile.in
66607
 
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
66608
 
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
66609
 
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
66610
 
+       $(ACLOCAL_M4)
66611
 
+mkinstalldirs = $(install_sh) -d
66612
 
+CONFIG_HEADER = $(top_builddir)/dummy-config.h \
66613
 
+       $(top_builddir)/dsieve-config.h
66614
 
+CONFIG_CLEAN_FILES =
66615
 
+LTLIBRARIES = $(noinst_LTLIBRARIES)
66616
 
+libsieve_ext_regex_la_LIBADD =
66617
 
+am_libsieve_ext_regex_la_OBJECTS = mcht-regex.lo ext-regex-common.lo \
66618
 
+       ext-regex.lo
66619
 
+libsieve_ext_regex_la_OBJECTS = $(am_libsieve_ext_regex_la_OBJECTS)
66620
 
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
66621
 
+depcomp = $(SHELL) $(top_srcdir)/depcomp
66622
 
+am__depfiles_maybe = depfiles
66623
 
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
66624
 
+       $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
66625
 
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
66626
 
+       --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
66627
 
+       $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
66628
 
+CCLD = $(CC)
66629
 
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
66630
 
+       --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
66631
 
+       $(LDFLAGS) -o $@
66632
 
+SOURCES = $(libsieve_ext_regex_la_SOURCES)
66633
 
+DIST_SOURCES = $(libsieve_ext_regex_la_SOURCES)
66634
 
+HEADERS = $(noinst_HEADERS)
66635
 
+ETAGS = etags
66636
 
+CTAGS = ctags
66637
 
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
66638
 
+ACLOCAL = @ACLOCAL@
66639
 
+AMTAR = @AMTAR@
66640
 
+AR = @AR@
66641
 
+AUTOCONF = @AUTOCONF@
66642
 
+AUTOHEADER = @AUTOHEADER@
66643
 
+AUTOMAKE = @AUTOMAKE@
66644
 
+AWK = @AWK@
66645
 
+CC = @CC@
66646
 
+CCDEPMODE = @CCDEPMODE@
66647
 
+CFLAGS = @CFLAGS@
66648
 
+CPP = @CPP@
66649
 
+CPPFLAGS = @CPPFLAGS@
66650
 
+CYGPATH_W = @CYGPATH_W@
66651
 
+DEFS = @DEFS@
66652
 
+DEPDIR = @DEPDIR@
66653
 
+DSYMUTIL = @DSYMUTIL@
66654
 
+DUMPBIN = @DUMPBIN@
66655
 
+ECHO_C = @ECHO_C@
66656
 
+ECHO_N = @ECHO_N@
66657
 
+ECHO_T = @ECHO_T@
66658
 
+EGREP = @EGREP@
66659
 
+EXEEXT = @EXEEXT@
66660
 
+FGREP = @FGREP@
66661
 
+GREP = @GREP@
66662
 
+INSTALL = @INSTALL@
66663
 
+INSTALL_DATA = @INSTALL_DATA@
66664
 
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
66665
 
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
66666
 
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
66667
 
+LD = @LD@
66668
 
+LDFLAGS = @LDFLAGS@
66669
 
+LIBICONV = @LIBICONV@
66670
 
+LIBOBJS = @LIBOBJS@
66671
 
+LIBS = @LIBS@
66672
 
+LIBTOOL = @LIBTOOL@
66673
 
+LIPO = @LIPO@
66674
 
+LN_S = @LN_S@
66675
 
+LTLIBOBJS = @LTLIBOBJS@
66676
 
+MAINT = @MAINT@
66677
 
+MAKEINFO = @MAKEINFO@
66678
 
+MKDIR_P = @MKDIR_P@
66679
 
+MODULE_LIBS = @MODULE_LIBS@
66680
 
+NM = @NM@
66681
 
+NMEDIT = @NMEDIT@
66682
 
+OBJDUMP = @OBJDUMP@
66683
 
+OBJEXT = @OBJEXT@
66684
 
+OTOOL = @OTOOL@
66685
 
+OTOOL64 = @OTOOL64@
66686
 
+PACKAGE = @PACKAGE@
66687
 
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
66688
 
+PACKAGE_NAME = @PACKAGE_NAME@
66689
 
+PACKAGE_STRING = @PACKAGE_STRING@
66690
 
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
66691
 
+PACKAGE_URL = @PACKAGE_URL@
66692
 
+PACKAGE_VERSION = @PACKAGE_VERSION@
66693
 
+PATH_SEPARATOR = @PATH_SEPARATOR@
66694
 
+RAND_LIBS = @RAND_LIBS@
66695
 
+RANLIB = @RANLIB@
66696
 
+SED = @SED@
66697
 
+SET_MAKE = @SET_MAKE@
66698
 
+SHELL = @SHELL@
66699
 
+STORAGE_LIBS = @STORAGE_LIBS@
66700
 
+STRIP = @STRIP@
66701
 
+VERSION = @VERSION@
66702
 
+abs_builddir = @abs_builddir@
66703
 
+abs_srcdir = @abs_srcdir@
66704
 
+abs_top_builddir = @abs_top_builddir@
66705
 
+abs_top_srcdir = @abs_top_srcdir@
66706
 
+ac_ct_CC = @ac_ct_CC@
66707
 
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
66708
 
+am__include = @am__include@
66709
 
+am__leading_dot = @am__leading_dot@
66710
 
+am__quote = @am__quote@
66711
 
+am__tar = @am__tar@
66712
 
+am__untar = @am__untar@
66713
 
+bindir = @bindir@
66714
 
+build = @build@
66715
 
+build_alias = @build_alias@
66716
 
+build_cpu = @build_cpu@
66717
 
+build_os = @build_os@
66718
 
+build_vendor = @build_vendor@
66719
 
+builddir = @builddir@
66720
 
+datadir = @datadir@
66721
 
+datarootdir = @datarootdir@
66722
 
+docdir = @docdir@
66723
 
+dovecot_incdir = @dovecot_incdir@
66724
 
+dovecotdir = @dovecotdir@
66725
 
+dvidir = @dvidir@
66726
 
+exec_prefix = @exec_prefix@
66727
 
+host = @host@
66728
 
+host_alias = @host_alias@
66729
 
+host_cpu = @host_cpu@
66730
 
+host_os = @host_os@
66731
 
+host_vendor = @host_vendor@
66732
 
+htmldir = @htmldir@
66733
 
+includedir = @includedir@
66734
 
+infodir = @infodir@
66735
 
+install_sh = @install_sh@
66736
 
+libdir = @libdir@
66737
 
+libexecdir = @libexecdir@
66738
 
+localedir = @localedir@
66739
 
+localstatedir = @localstatedir@
66740
 
+lt_ECHO = @lt_ECHO@
66741
 
+mandir = @mandir@
66742
 
+mkdir_p = @mkdir_p@
66743
 
+moduledir = @moduledir@
66744
 
+oldincludedir = @oldincludedir@
66745
 
+pdfdir = @pdfdir@
66746
 
+prefix = @prefix@
66747
 
+program_transform_name = @program_transform_name@
66748
 
+psdir = @psdir@
66749
 
+sbindir = @sbindir@
66750
 
+sharedstatedir = @sharedstatedir@
66751
 
+srcdir = @srcdir@
66752
 
+sysconfdir = @sysconfdir@
66753
 
+target_alias = @target_alias@
66754
 
+top_build_prefix = @top_build_prefix@
66755
 
+top_builddir = @top_builddir@
66756
 
+top_srcdir = @top_srcdir@
66757
 
+noinst_LTLIBRARIES = libsieve_ext_regex.la
66758
 
+AM_CPPFLAGS = \
66759
 
+       -I../../ \
66760
 
+       -I$(dovecot_incdir) \
66761
 
+       -I$(dovecot_incdir)/src/lib \
66762
 
+       -I$(dovecot_incdir)/src/lib-mail \
66763
 
+       -I$(dovecot_incdir)/src/lib-storage 
66764
 
+
66765
 
+libsieve_ext_regex_la_SOURCES = \
66766
 
+       mcht-regex.c \
66767
 
+       ext-regex-common.c \
66768
 
+       ext-regex.c
66769
 
+
66770
 
+noinst_HEADERS = \
66771
 
+       ext-regex-common.h
66772
 
+
66773
 
+all: all-am
66774
 
+
66775
 
+.SUFFIXES:
66776
 
+.SUFFIXES: .c .lo .o .obj
66777
 
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
66778
 
+       @for dep in $?; do \
66779
 
+         case '$(am__configure_deps)' in \
66780
 
+           *$$dep*) \
66781
 
+             ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
66782
 
+               && { if test -f $@; then exit 0; else break; fi; }; \
66783
 
+             exit 1;; \
66784
 
+         esac; \
66785
 
+       done; \
66786
 
+       echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign  src/lib-sieve/plugins/regex/Makefile'; \
66787
 
+       cd $(top_srcdir) && \
66788
 
+         $(AUTOMAKE) --foreign  src/lib-sieve/plugins/regex/Makefile
66789
 
+.PRECIOUS: Makefile
66790
 
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
66791
 
+       @case '$?' in \
66792
 
+         *config.status*) \
66793
 
+           cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
66794
 
+         *) \
66795
 
+           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
66796
 
+           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
66797
 
+       esac;
66798
 
+
66799
 
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
66800
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
66801
 
+
66802
 
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
66803
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
66804
 
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
66805
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
66806
 
+
66807
 
+clean-noinstLTLIBRARIES:
66808
 
+       -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
66809
 
+       @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
66810
 
+         dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
66811
 
+         test "$$dir" != "$$p" || dir=.; \
66812
 
+         echo "rm -f \"$${dir}/so_locations\""; \
66813
 
+         rm -f "$${dir}/so_locations"; \
66814
 
+       done
66815
 
+libsieve_ext_regex.la: $(libsieve_ext_regex_la_OBJECTS) $(libsieve_ext_regex_la_DEPENDENCIES) 
66816
 
+       $(LINK)  $(libsieve_ext_regex_la_OBJECTS) $(libsieve_ext_regex_la_LIBADD) $(LIBS)
66817
 
+
66818
 
+mostlyclean-compile:
66819
 
+       -rm -f *.$(OBJEXT)
66820
 
+
66821
 
+distclean-compile:
66822
 
+       -rm -f *.tab.c
66823
 
+
66824
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-regex-common.Plo@am__quote@
66825
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-regex.Plo@am__quote@
66826
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mcht-regex.Plo@am__quote@
66827
 
+
66828
 
+.c.o:
66829
 
+@am__fastdepCC_TRUE@   $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
66830
 
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
66831
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
66832
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
66833
 
+@am__fastdepCC_FALSE@  $(COMPILE) -c $<
66834
 
+
66835
 
+.c.obj:
66836
 
+@am__fastdepCC_TRUE@   $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
66837
 
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
66838
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
66839
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
66840
 
+@am__fastdepCC_FALSE@  $(COMPILE) -c `$(CYGPATH_W) '$<'`
66841
 
+
66842
 
+.c.lo:
66843
 
+@am__fastdepCC_TRUE@   $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
66844
 
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
66845
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
66846
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
66847
 
+@am__fastdepCC_FALSE@  $(LTCOMPILE) -c -o $@ $<
66848
 
+
66849
 
+mostlyclean-libtool:
66850
 
+       -rm -f *.lo
66851
 
+
66852
 
+clean-libtool:
66853
 
+       -rm -rf .libs _libs
66854
 
+
66855
 
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
66856
 
+       list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
66857
 
+       unique=`for i in $$list; do \
66858
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
66859
 
+         done | \
66860
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
66861
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
66862
 
+       mkid -fID $$unique
66863
 
+tags: TAGS
66864
 
+
66865
 
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
66866
 
+               $(TAGS_FILES) $(LISP)
66867
 
+       tags=; \
66868
 
+       here=`pwd`; \
66869
 
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
66870
 
+       unique=`for i in $$list; do \
66871
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
66872
 
+         done | \
66873
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
66874
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
66875
 
+       if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
66876
 
+         test -n "$$unique" || unique=$$empty_fix; \
66877
 
+         $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
66878
 
+           $$tags $$unique; \
66879
 
+       fi
66880
 
+ctags: CTAGS
66881
 
+CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
66882
 
+               $(TAGS_FILES) $(LISP)
66883
 
+       tags=; \
66884
 
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
66885
 
+       unique=`for i in $$list; do \
66886
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
66887
 
+         done | \
66888
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
66889
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
66890
 
+       test -z "$(CTAGS_ARGS)$$tags$$unique" \
66891
 
+         || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
66892
 
+            $$tags $$unique
66893
 
+
66894
 
+GTAGS:
66895
 
+       here=`$(am__cd) $(top_builddir) && pwd` \
66896
 
+         && cd $(top_srcdir) \
66897
 
+         && gtags -i $(GTAGS_ARGS) $$here
66898
 
+
66899
 
+distclean-tags:
66900
 
+       -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
66901
 
+
66902
 
+distdir: $(DISTFILES)
66903
 
+       @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
66904
 
+       topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
66905
 
+       list='$(DISTFILES)'; \
66906
 
+         dist_files=`for file in $$list; do echo $$file; done | \
66907
 
+         sed -e "s|^$$srcdirstrip/||;t" \
66908
 
+             -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
66909
 
+       case $$dist_files in \
66910
 
+         */*) $(MKDIR_P) `echo "$$dist_files" | \
66911
 
+                          sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
66912
 
+                          sort -u` ;; \
66913
 
+       esac; \
66914
 
+       for file in $$dist_files; do \
66915
 
+         if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
66916
 
+         if test -d $$d/$$file; then \
66917
 
+           dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
66918
 
+           if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
66919
 
+             cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
66920
 
+           fi; \
66921
 
+           cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
66922
 
+         else \
66923
 
+           test -f $(distdir)/$$file \
66924
 
+           || cp -p $$d/$$file $(distdir)/$$file \
66925
 
+           || exit 1; \
66926
 
+         fi; \
66927
 
+       done
66928
 
+check-am: all-am
66929
 
+check: check-am
66930
 
+all-am: Makefile $(LTLIBRARIES) $(HEADERS)
66931
 
+installdirs:
66932
 
+install: install-am
66933
 
+install-exec: install-exec-am
66934
 
+install-data: install-data-am
66935
 
+uninstall: uninstall-am
66936
 
+
66937
 
+install-am: all-am
66938
 
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
66939
 
+
66940
 
+installcheck: installcheck-am
66941
 
+install-strip:
66942
 
+       $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
66943
 
+         install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
66944
 
+         `test -z '$(STRIP)' || \
66945
 
+           echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
66946
 
+mostlyclean-generic:
66947
 
+
66948
 
+clean-generic:
66949
 
+
66950
 
+distclean-generic:
66951
 
+       -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
66952
 
+
66953
 
+maintainer-clean-generic:
66954
 
+       @echo "This command is intended for maintainers to use"
66955
 
+       @echo "it deletes files that may require special tools to rebuild."
66956
 
+clean: clean-am
66957
 
+
66958
 
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
66959
 
+       mostlyclean-am
66960
 
+
66961
 
+distclean: distclean-am
66962
 
+       -rm -rf ./$(DEPDIR)
66963
 
+       -rm -f Makefile
66964
 
+distclean-am: clean-am distclean-compile distclean-generic \
66965
 
+       distclean-tags
66966
 
+
66967
 
+dvi: dvi-am
66968
 
+
66969
 
+dvi-am:
66970
 
+
66971
 
+html: html-am
66972
 
+
66973
 
+info: info-am
66974
 
+
66975
 
+info-am:
66976
 
+
66977
 
+install-data-am:
66978
 
+
66979
 
+install-dvi: install-dvi-am
66980
 
+
66981
 
+install-exec-am:
66982
 
+
66983
 
+install-html: install-html-am
66984
 
+
66985
 
+install-info: install-info-am
66986
 
+
66987
 
+install-man:
66988
 
+
66989
 
+install-pdf: install-pdf-am
66990
 
+
66991
 
+install-ps: install-ps-am
66992
 
+
66993
 
+installcheck-am:
66994
 
+
66995
 
+maintainer-clean: maintainer-clean-am
66996
 
+       -rm -rf ./$(DEPDIR)
66997
 
+       -rm -f Makefile
66998
 
+maintainer-clean-am: distclean-am maintainer-clean-generic
66999
 
+
67000
 
+mostlyclean: mostlyclean-am
67001
 
+
67002
 
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
67003
 
+       mostlyclean-libtool
67004
 
+
67005
 
+pdf: pdf-am
67006
 
+
67007
 
+pdf-am:
67008
 
+
67009
 
+ps: ps-am
67010
 
+
67011
 
+ps-am:
67012
 
+
67013
 
+uninstall-am:
67014
 
+
67015
 
+.MAKE: install-am install-strip
67016
 
+
67017
 
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
67018
 
+       clean-libtool clean-noinstLTLIBRARIES ctags distclean \
67019
 
+       distclean-compile distclean-generic distclean-libtool \
67020
 
+       distclean-tags distdir dvi dvi-am html html-am info info-am \
67021
 
+       install install-am install-data install-data-am install-dvi \
67022
 
+       install-dvi-am install-exec install-exec-am install-html \
67023
 
+       install-html-am install-info install-info-am install-man \
67024
 
+       install-pdf install-pdf-am install-ps install-ps-am \
67025
 
+       install-strip installcheck installcheck-am installdirs \
67026
 
+       maintainer-clean maintainer-clean-generic mostlyclean \
67027
 
+       mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
67028
 
+       pdf pdf-am ps ps-am tags uninstall uninstall-am
67029
 
+
67030
 
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
67031
 
+# Otherwise a system limit (for SysV at least) may be exceeded.
67032
 
+.NOEXPORT:
67033
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/regex/mcht-regex.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/regex/mcht-regex.c
67034
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/regex/mcht-regex.c     1970-01-01 01:00:00.000000000 +0100
67035
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/regex/mcht-regex.c      2009-07-30 01:14:02.000000000 +0200
67036
 
@@ -0,0 +1,323 @@
67037
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
67038
 
+ */
67039
 
+
67040
 
+/* Match-type ':regex'
67041
 
+ */
67042
 
+
67043
 
+#include "lib.h"
67044
 
+#include "mempool.h"
67045
 
+#include "buffer.h"
67046
 
+#include "array.h"
67047
 
+#include "str.h"
67048
 
+
67049
 
+#include "sieve-common.h"
67050
 
+#include "sieve-limits.h"
67051
 
+#include "sieve-ast.h"
67052
 
+#include "sieve-commands.h"
67053
 
+#include "sieve-validator.h"
67054
 
+#include "sieve-comparators.h"
67055
 
+#include "sieve-match-types.h"
67056
 
+#include "sieve-match.h"
67057
 
+
67058
 
+#include "ext-regex-common.h"
67059
 
+
67060
 
+#include <sys/types.h>
67061
 
+#include <regex.h>
67062
 
+#include <ctype.h>
67063
 
+
67064
 
+/*
67065
 
+ * Configuration
67066
 
+ */
67067
 
+
67068
 
+#define MCHT_REGEX_MAX_SUBSTITUTIONS SIEVE_MAX_MATCH_VALUES
67069
 
+
67070
 
+/* 
67071
 
+ * Match type
67072
 
+ */
67073
 
67074
 
+bool mcht_regex_validate_context
67075
 
+(struct sieve_validator *validator, struct sieve_ast_argument *arg,
67076
 
+    struct sieve_match_type_context *ctx, struct sieve_ast_argument *key_arg);
67077
 
+
67078
 
+static void mcht_regex_match_init(struct sieve_match_context *mctx);
67079
 
+static int mcht_regex_match
67080
 
+       (struct sieve_match_context *mctx, const char *val, size_t val_size,
67081
 
+       const char *key, size_t key_size, int key_index);
67082
 
+static int mcht_regex_match_deinit(struct sieve_match_context *mctx);
67083
 
+
67084
 
+const struct sieve_match_type regex_match_type = {
67085
 
+       SIEVE_OBJECT("regex", &regex_match_type_operand, 0),
67086
 
+       TRUE, FALSE,
67087
 
+       NULL,
67088
 
+       mcht_regex_validate_context,
67089
 
+       mcht_regex_match_init,
67090
 
+       mcht_regex_match,
67091
 
+       mcht_regex_match_deinit
67092
 
+};
67093
 
+
67094
 
+/* 
67095
 
+ * Match type validation 
67096
 
+ */
67097
 
+
67098
 
+/* Wrapper around the regerror function for easy access */
67099
 
+static const char *_regexp_error(regex_t *regexp, int errorcode)
67100
 
+{
67101
 
+       size_t errsize = regerror(errorcode, regexp, NULL, 0); 
67102
 
+
67103
 
+       if ( errsize > 0 ) {
67104
 
+               char *errbuf;
67105
 
+
67106
 
+               buffer_t *error_buf = 
67107
 
+                       buffer_create_dynamic(pool_datastack_create(), errsize);
67108
 
+               errbuf = buffer_get_space_unsafe(error_buf, 0, errsize);
67109
 
+
67110
 
+               errsize = regerror(errorcode, regexp, errbuf, errsize);
67111
 
+        
67112
 
+               /* We don't want the error to start with a capital letter */
67113
 
+               errbuf[0] = i_tolower(errbuf[0]);
67114
 
+
67115
 
+               buffer_append_space_unsafe(error_buf, errsize);
67116
 
+
67117
 
+               return str_c(error_buf);
67118
 
+       }
67119
 
+
67120
 
+       return "";
67121
 
+}
67122
 
+
67123
 
+static int mcht_regex_validate_regexp
67124
 
+(struct sieve_validator *validator, 
67125
 
+       struct sieve_match_type_context *ctx ATTR_UNUSED,
67126
 
+       struct sieve_ast_argument *key, int cflags) 
67127
 
+{
67128
 
+       int ret;
67129
 
+       regex_t regexp;
67130
 
+
67131
 
+       if ( (ret=regcomp(&regexp, sieve_ast_argument_strc(key), cflags)) != 0 ) {
67132
 
+               sieve_argument_validate_error(validator, key,
67133
 
+                       "invalid regular expression for regex match: %s", 
67134
 
+                       _regexp_error(&regexp, ret));
67135
 
+
67136
 
+               regfree(&regexp);       
67137
 
+               return FALSE;
67138
 
+       }
67139
 
+
67140
 
+       regfree(&regexp);
67141
 
+       return TRUE;
67142
 
+}
67143
 
+
67144
 
+struct _regex_key_context {
67145
 
+       struct sieve_validator *valdtr;
67146
 
+       struct sieve_match_type_context *mctx;
67147
 
+       int cflags;
67148
 
+};
67149
 
+
67150
 
+static int mcht_regex_validate_key_argument
67151
 
+(void *context, struct sieve_ast_argument *key)
67152
 
+{
67153
 
+       struct _regex_key_context *keyctx = (struct _regex_key_context *) context;
67154
 
+
67155
 
+       /* FIXME: We can currently only handle string literal argument, so
67156
 
+        * variables are not allowed.
67157
 
+        */
67158
 
+       if ( !sieve_argument_is_string_literal(key) ) {
67159
 
+               sieve_argument_validate_error(keyctx->valdtr, key,
67160
 
+                       "this Sieve implementation currently only accepts a literal string "
67161
 
+                       "for a regular expression");
67162
 
+               return FALSE;
67163
 
+       }
67164
 
+
67165
 
+       return mcht_regex_validate_regexp
67166
 
+               (keyctx->valdtr, keyctx->mctx, key, keyctx->cflags);
67167
 
+}
67168
 
+       
67169
 
+bool mcht_regex_validate_context
67170
 
+(struct sieve_validator *validator, struct sieve_ast_argument *arg ATTR_UNUSED,
67171
 
+       struct sieve_match_type_context *ctx, struct sieve_ast_argument *key_arg)
67172
 
+{
67173
 
+       const struct sieve_comparator *cmp = ctx->comparator;
67174
 
+       int cflags = REG_EXTENDED | REG_NOSUB;
67175
 
+       struct _regex_key_context keyctx;
67176
 
+       struct sieve_ast_argument *kitem;
67177
 
+
67178
 
+       if ( cmp != NULL ) { 
67179
 
+               if ( cmp == &i_ascii_casemap_comparator )
67180
 
+                       cflags =  REG_EXTENDED | REG_NOSUB | REG_ICASE;
67181
 
+               else if ( cmp == &i_octet_comparator )
67182
 
+                       cflags =  REG_EXTENDED | REG_NOSUB;
67183
 
+               else {
67184
 
+                       sieve_argument_validate_error(validator, ctx->match_type_arg, 
67185
 
+                               "regex match type only supports "
67186
 
+                               "i;octet and i;ascii-casemap comparators" );
67187
 
+                       return FALSE;   
67188
 
+               }
67189
 
+       }
67190
 
+
67191
 
+       /* Validate regular expression keys */
67192
 
+
67193
 
+       keyctx.valdtr = validator;
67194
 
+       keyctx.mctx = ctx;
67195
 
+       keyctx.cflags = cflags;
67196
 
+
67197
 
+       kitem = key_arg;
67198
 
+       if ( !sieve_ast_stringlist_map(&kitem, (void *) &keyctx,
67199
 
+               mcht_regex_validate_key_argument) )
67200
 
+               return FALSE;
67201
 
+
67202
 
+       return TRUE;
67203
 
+}
67204
 
+
67205
 
+/* 
67206
 
+ * Match type implementation 
67207
 
+ */
67208
 
+
67209
 
+struct mcht_regex_context {
67210
 
+       ARRAY_DEFINE(reg_expressions, regex_t);
67211
 
+       int value_index;
67212
 
+       regmatch_t *pmatch;
67213
 
+       size_t nmatch;
67214
 
+};
67215
 
+
67216
 
+static void mcht_regex_match_init
67217
 
+(struct sieve_match_context *mctx)
67218
 
+{
67219
 
+       pool_t pool = mctx->pool;
67220
 
+       struct mcht_regex_context *ctx;
67221
 
+
67222
 
+       /* Create context */    
67223
 
+       ctx = p_new(pool, struct mcht_regex_context, 1);
67224
 
+       p_array_init(&ctx->reg_expressions, pool, 4);
67225
 
+       ctx->value_index = -1;
67226
 
+
67227
 
+       /* Create storage for match values if match values are requested */
67228
 
+       if ( sieve_match_values_are_enabled(mctx->interp) ) {
67229
 
+               ctx->pmatch = p_new(pool, regmatch_t, MCHT_REGEX_MAX_SUBSTITUTIONS);
67230
 
+               ctx->nmatch = MCHT_REGEX_MAX_SUBSTITUTIONS;
67231
 
+       } else {
67232
 
+               ctx->pmatch = NULL;
67233
 
+               ctx->nmatch = 0;
67234
 
+       }
67235
 
+       
67236
 
+       /* Assign context */
67237
 
+       mctx->data = (void *) ctx;
67238
 
+}
67239
 
+
67240
 
+static regex_t *mcht_regex_get
67241
 
+(struct mcht_regex_context *ctx,
67242
 
+       const struct sieve_comparator *cmp, 
67243
 
+       const char *key, unsigned int key_index)
67244
 
+{
67245
 
+       int ret;
67246
 
+       int cflags;
67247
 
+       regex_t *regexp;
67248
 
+       
67249
 
+       /* If this is the first matched value, the regexes are not compiled
67250
 
+        * yet.
67251
 
+        */
67252
 
+       if ( ctx->value_index <= 0 ) {
67253
 
+               /* Allocate space */
67254
 
+               array_idx_clear(&ctx->reg_expressions, key_index);
67255
 
+               regexp = array_idx_modifiable(&ctx->reg_expressions, key_index);
67256
 
+
67257
 
+               /* Configure case-sensitivity according to comparator */
67258
 
+               if ( cmp == &i_octet_comparator ) 
67259
 
+                       cflags =  REG_EXTENDED;
67260
 
+               else if ( cmp ==  &i_ascii_casemap_comparator )
67261
 
+                       cflags =  REG_EXTENDED | REG_ICASE;
67262
 
+               else
67263
 
+                       return NULL; /* Not supported */
67264
 
+                       
67265
 
+               /* Indicate whether match values need to be produced */
67266
 
+               if ( ctx->nmatch == 0 ) cflags |= REG_NOSUB;
67267
 
+
67268
 
+               /* Compile regular expression */
67269
 
+               if ( (ret=regcomp(regexp, key, cflags)) != 0 ) {
67270
 
+                       /* FIXME: Do something useful, i.e. report error somewhere */
67271
 
+                       return NULL;
67272
 
+               }
67273
 
+       } else {
67274
 
+               /* Get compiled regex from cache */
67275
 
+               regexp = array_idx_modifiable(&ctx->reg_expressions, key_index);
67276
 
+       }
67277
 
+
67278
 
+       return regexp;
67279
 
+}
67280
 
+
67281
 
+static int mcht_regex_match
67282
 
+(struct sieve_match_context *mctx, 
67283
 
+       const char *val, size_t val_size ATTR_UNUSED, 
67284
 
+       const char *key, size_t key_size ATTR_UNUSED, int key_index)
67285
 
+{
67286
 
+       struct mcht_regex_context *ctx = (struct mcht_regex_context *) mctx->data;
67287
 
+       regex_t *regexp;
67288
 
+
67289
 
+       if ( val == NULL ) {
67290
 
+               val = "";
67291
 
+               val_size = 0;
67292
 
+       }
67293
 
+
67294
 
+       if ( key_index < 0 ) return FALSE;
67295
 
+
67296
 
+       if ( key_index == 0 ) ctx->value_index++;
67297
 
+
67298
 
+       /* Get compiled regex */
67299
 
+       if ( (regexp=mcht_regex_get(ctx, mctx->comparator, key, key_index)) == NULL )
67300
 
+               return FALSE;
67301
 
+
67302
 
+       /* Execute regex */
67303
 
+       if ( regexec(regexp, val, ctx->nmatch, ctx->pmatch, 0) == 0 ) {
67304
 
+
67305
 
+               /* Handle match values if necessary */
67306
 
+               if ( ctx->nmatch > 0 ) {
67307
 
+                       struct sieve_match_values *mvalues;
67308
 
+                       size_t i;
67309
 
+                       int skipped = 0;
67310
 
+                       string_t *subst = t_str_new(32);
67311
 
+
67312
 
+                       /* Start new list of match values */
67313
 
+                       mvalues = sieve_match_values_start(mctx->interp);
67314
 
+
67315
 
+                       i_assert( mvalues != NULL );
67316
 
+
67317
 
+                       /* Add match values from regular expression */
67318
 
+                       for ( i = 0; i < ctx->nmatch; i++ ) {
67319
 
+                               str_truncate(subst, 0);
67320
 
+                       
67321
 
+                               if ( ctx->pmatch[i].rm_so != -1 ) {
67322
 
+                                       if ( skipped > 0 ) {
67323
 
+                                               sieve_match_values_skip(mvalues, skipped);
67324
 
+                                               skipped = 0;
67325
 
+                                       }
67326
 
+                                       
67327
 
+                                       str_append_n(subst, val + ctx->pmatch[i].rm_so, 
67328
 
+                                               ctx->pmatch[i].rm_eo - ctx->pmatch[i].rm_so);
67329
 
+                                       sieve_match_values_add(mvalues, subst);
67330
 
+                               } else 
67331
 
+                                       skipped++;
67332
 
+                       }
67333
 
+
67334
 
+                       /* Substitute the new match values */
67335
 
+                       sieve_match_values_commit(mctx->interp, &mvalues);
67336
 
+               }
67337
 
+
67338
 
+               return TRUE;
67339
 
+       }
67340
 
+       
67341
 
+       return FALSE;
67342
 
+}
67343
 
+
67344
 
+int mcht_regex_match_deinit
67345
 
+(struct sieve_match_context *mctx)
67346
 
+{
67347
 
+       struct mcht_regex_context *ctx = (struct mcht_regex_context *) mctx->data;
67348
 
+       regex_t *regexps;
67349
 
+       unsigned int count, i;
67350
 
+
67351
 
+       /* Clean up compiled regular expressions */
67352
 
+       regexps = array_get_modifiable(&ctx->reg_expressions, &count);
67353
 
+       for ( i = 0; i < count; i++ ) {
67354
 
+               regfree(&regexps[i]);
67355
 
+       }
67356
 
+
67357
 
+       return FALSE;
67358
 
+}
67359
 
+
67360
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/relational/ext-relational.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/relational/ext-relational.c
67361
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/relational/ext-relational.c    1970-01-01 01:00:00.000000000 +0100
67362
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/relational/ext-relational.c     2009-01-06 00:15:52.000000000 +0100
67363
 
@@ -0,0 +1,57 @@
67364
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
67365
 
+ */
67366
 
+
67367
 
+/* Extension relational 
67368
 
+ * --------------------
67369
 
+ *
67370
 
+ * Author: Stephan Bosch
67371
 
+ * Specification: RFC 3431
67372
 
+ * Implementation: full
67373
 
+ * Status: experimental, largely untested
67374
 
+ * 
67375
 
+ */
67376
 
+
67377
 
+#include "lib.h"
67378
 
+#include "str.h"
67379
 
+
67380
 
+#include "sieve-common.h"
67381
 
+
67382
 
+#include "sieve-ast.h"
67383
 
+#include "sieve-code.h"
67384
 
+#include "sieve-extensions.h"
67385
 
+#include "sieve-commands.h"
67386
 
+#include "sieve-comparators.h"
67387
 
+#include "sieve-match-types.h"
67388
 
+#include "sieve-validator.h"
67389
 
+#include "sieve-generator.h"
67390
 
+#include "sieve-interpreter.h"
67391
 
+
67392
 
+#include "ext-relational-common.h"
67393
 
+
67394
 
+/* 
67395
 
+ * Extension
67396
 
+ */
67397
 
+
67398
 
+static bool ext_relational_validator_load(struct sieve_validator *validator);
67399
 
+
67400
 
+int ext_relational_my_id = -1;
67401
 
+
67402
 
+const struct sieve_extension relational_extension = { 
67403
 
+       "relational", 
67404
 
+       &ext_relational_my_id,
67405
 
+       NULL, NULL,
67406
 
+       ext_relational_validator_load,
67407
 
+       NULL, NULL, NULL, NULL, NULL,
67408
 
+       SIEVE_EXT_DEFINE_NO_OPERATIONS, 
67409
 
+       SIEVE_EXT_DEFINE_OPERAND(rel_match_type_operand)
67410
 
+};
67411
 
+
67412
 
+static bool ext_relational_validator_load(struct sieve_validator *validator)
67413
 
+{
67414
 
+       sieve_match_type_register(validator, &value_match_type); 
67415
 
+       sieve_match_type_register(validator, &count_match_type); 
67416
 
+
67417
 
+       return TRUE;
67418
 
+}
67419
 
+
67420
 
+
67421
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/relational/ext-relational-common.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/relational/ext-relational-common.c
67422
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/relational/ext-relational-common.c     1970-01-01 01:00:00.000000000 +0100
67423
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/relational/ext-relational-common.c      2009-01-06 00:15:52.000000000 +0100
67424
 
@@ -0,0 +1,160 @@
67425
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
67426
 
+ */
67427
 
+
67428
 
+/* Syntax:
67429
 
+ *   MATCH-TYPE =/ COUNT / VALUE
67430
 
+ *   COUNT = ":count" relational-match
67431
 
+ *   VALUE = ":value" relational-match
67432
 
+ *   relational-match = DQUOTE ( "gt" / "ge" / "lt"
67433
 
+ *                             / "le" / "eq" / "ne" ) DQUOTE
67434
 
+ */ 
67435
 
+
67436
 
+#include "lib.h"
67437
 
+#include "str.h"
67438
 
+#include "str-sanitize.h"
67439
 
+
67440
 
+#include "sieve-common.h"
67441
 
+#include "sieve-ast.h"
67442
 
+#include "sieve-code.h"
67443
 
+#include "sieve-extensions.h"
67444
 
+#include "sieve-commands.h"
67445
 
+#include "sieve-comparators.h"
67446
 
+#include "sieve-match-types.h"
67447
 
+#include "sieve-validator.h"
67448
 
+#include "sieve-generator.h"
67449
 
+#include "sieve-interpreter.h"
67450
 
+
67451
 
+#include "ext-relational-common.h"
67452
 
+
67453
 
+/*
67454
 
+ * Forward declarations
67455
 
+ */
67456
 
+
67457
 
+const struct sieve_match_type *rel_match_types[];
67458
 
+
67459
 
+/* 
67460
 
+ * Validation 
67461
 
+ */
67462
 
+
67463
 
+bool mcht_relational_validate
67464
 
+(struct sieve_validator *validator, struct sieve_ast_argument **arg, 
67465
 
+       struct sieve_match_type_context *ctx)
67466
 
+{      
67467
 
+       enum relational_match rel_match = REL_MATCH_INVALID;
67468
 
+       string_t *rel_match_ident;
67469
 
+
67470
 
+       /* Check syntax:
67471
 
+        *   relational-match = DQUOTE ( "gt" / "ge" / "lt"     
67472
 
+        *                             / "le" / "eq" / "ne" ) DQUOTE
67473
 
+        *
67474
 
+        * So, actually this must be a constant string and it is implemented as such 
67475
 
+        */
67476
 
+        
67477
 
+       /* Did we get a string in the first place ? */ 
67478
 
+       if ( (*arg)->type != SAAT_STRING ) {
67479
 
+               sieve_argument_validate_error(validator, *arg, 
67480
 
+                       "the :%s match-type requires a constant string argument being "
67481
 
+                       "one of \"gt\", \"ge\", \"lt\", \"le\", \"eq\" or \"ne\", "
67482
 
+                       "but %s was found", 
67483
 
+                       ctx->match_type->object.identifier, sieve_ast_argument_name(*arg));
67484
 
+               return FALSE;
67485
 
+       }
67486
 
+       
67487
 
+       /* Check the relational match id */
67488
 
+       
67489
 
+       rel_match_ident = sieve_ast_argument_str(*arg);
67490
 
+       if ( str_len(rel_match_ident) == 2 ) {
67491
 
+               const char *rel_match_id = str_c(rel_match_ident);
67492
 
+
67493
 
+               switch ( rel_match_id[0] ) {
67494
 
+               /* "gt" or "ge" */
67495
 
+               case 'g':
67496
 
+                       switch ( rel_match_id[1] ) {
67497
 
+                       case 't': 
67498
 
+                               rel_match = REL_MATCH_GREATER; 
67499
 
+                               break;
67500
 
+                       case 'e': 
67501
 
+                               rel_match = REL_MATCH_GREATER_EQUAL; 
67502
 
+                               break;
67503
 
+                       default: 
67504
 
+                               rel_match = REL_MATCH_INVALID;
67505
 
+                       }
67506
 
+                       break;
67507
 
+               /* "lt" or "le" */
67508
 
+               case 'l':
67509
 
+                       switch ( rel_match_id[1] ) {
67510
 
+                       case 't': 
67511
 
+                               rel_match = REL_MATCH_LESS; 
67512
 
+                               break;
67513
 
+                       case 'e': 
67514
 
+                               rel_match = REL_MATCH_LESS_EQUAL; 
67515
 
+                               break;
67516
 
+                       default: 
67517
 
+                               rel_match = REL_MATCH_INVALID;
67518
 
+                       }
67519
 
+                       break;
67520
 
+               /* "eq" */
67521
 
+               case 'e':
67522
 
+                       if ( rel_match_id[1] == 'q' )
67523
 
+                               rel_match = REL_MATCH_EQUAL;
67524
 
+                       else    
67525
 
+                               rel_match = REL_MATCH_INVALID;          
67526
 
+                       break;
67527
 
+               /* "ne" */
67528
 
+               case 'n':
67529
 
+                       if ( rel_match_id[1] == 'e' )
67530
 
+                               rel_match = REL_MATCH_NOT_EQUAL;
67531
 
+                       else    
67532
 
+                               rel_match = REL_MATCH_INVALID;
67533
 
+                       break;
67534
 
+               /* invalid */
67535
 
+               default:
67536
 
+                       rel_match = REL_MATCH_INVALID;
67537
 
+               }
67538
 
+       }
67539
 
+       
67540
 
+       if ( rel_match >= REL_MATCH_INVALID ) {
67541
 
+               sieve_argument_validate_error(validator, *arg, 
67542
 
+                       "the :%s match-type requires a constant string argument being "
67543
 
+                       "one of \"gt\", \"ge\", \"lt\", \"le\", \"eq\" or \"ne\", "
67544
 
+                       "but \"%s\" was found", 
67545
 
+                       ctx->match_type->object.identifier, 
67546
 
+                       str_sanitize(str_c(rel_match_ident), 32));
67547
 
+               return FALSE;
67548
 
+       }
67549
 
+       
67550
 
+       /* Delete argument */
67551
 
+       *arg = sieve_ast_arguments_detach(*arg, 1);
67552
 
+
67553
 
+       /* Not used just yet */
67554
 
+       ctx->ctx_data = (void *) rel_match;
67555
 
+
67556
 
+       /* Override the actual match type with a parameter-specific one */
67557
 
+       ctx->match_type = rel_match_types
67558
 
+               [REL_MATCH_INDEX(ctx->match_type->object.code, rel_match)];
67559
 
+
67560
 
+       return TRUE;
67561
 
+}
67562
 
+
67563
 
+/*
67564
 
+ * Relational match-type operand
67565
 
+ */
67566
 
+
67567
 
+const const struct sieve_match_type *rel_match_types[] = {
67568
 
+    &rel_match_value_gt, &rel_match_value_ge, &rel_match_value_lt,
67569
 
+    &rel_match_value_le, &rel_match_value_eq, &rel_match_value_ne,
67570
 
+    &rel_match_count_gt, &rel_match_count_ge, &rel_match_count_lt,
67571
 
+    &rel_match_count_le, &rel_match_count_eq, &rel_match_count_ne
67572
 
+};
67573
 
+
67574
 
+static const struct sieve_extension_objects ext_match_types =
67575
 
+       SIEVE_EXT_DEFINE_MATCH_TYPES(rel_match_types);
67576
 
+
67577
 
+const struct sieve_operand rel_match_type_operand = {
67578
 
+    "relational match",
67579
 
+    &relational_extension,
67580
 
+    0,
67581
 
+    &sieve_match_type_operand_class,
67582
 
+    &ext_match_types
67583
 
+};
67584
 
+
67585
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/relational/ext-relational-common.h dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/relational/ext-relational-common.h
67586
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/relational/ext-relational-common.h     1970-01-01 01:00:00.000000000 +0100
67587
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/relational/ext-relational-common.h      2009-02-24 13:42:08.000000000 +0100
67588
 
@@ -0,0 +1,96 @@
67589
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
67590
 
+ */
67591
 
67592
 
+#ifndef __EXT_RELATIONAL_COMMON_H
67593
 
+#define __EXT_RELATIONAL_COMMON_H
67594
 
+
67595
 
+#include "lib.h"
67596
 
+#include "str.h"
67597
 
+
67598
 
+#include "sieve-common.h"
67599
 
+
67600
 
+/* 
67601
 
+ * Types 
67602
 
+ */
67603
 
+
67604
 
+enum ext_relational_match_type {
67605
 
+       RELATIONAL_VALUE,
67606
 
+       RELATIONAL_COUNT
67607
 
+};
67608
 
+
67609
 
+enum relational_match {
67610
 
+       REL_MATCH_GREATER,
67611
 
+       REL_MATCH_GREATER_EQUAL,
67612
 
+       REL_MATCH_LESS,
67613
 
+       REL_MATCH_LESS_EQUAL,
67614
 
+       REL_MATCH_EQUAL,
67615
 
+       REL_MATCH_NOT_EQUAL,
67616
 
+       REL_MATCH_INVALID
67617
 
+};
67618
 
+
67619
 
+#define REL_MATCH_INDEX(type, match) \
67620
 
+       (type * REL_MATCH_INVALID + match)
67621
 
+#define REL_MATCH_TYPE(index) \
67622
 
+       (index / REL_MATCH_INVALID)
67623
 
+#define REL_MATCH(index) \
67624
 
+       (index % REL_MATCH_INVALID)
67625
 
+
67626
 
+/* 
67627
 
+ * Extension definitions 
67628
 
+ */
67629
 
+
67630
 
+extern int ext_relational_my_id;
67631
 
+
67632
 
+extern const struct sieve_extension relational_extension;
67633
 
+extern const struct sieve_match_type_extension relational_match_extension;
67634
 
+
67635
 
+/*
67636
 
+ * Match types
67637
 
+ */
67638
 
67639
 
+/* Registered for validation */ 
67640
 
+
67641
 
+extern const struct sieve_match_type value_match_type;
67642
 
+extern const struct sieve_match_type count_match_type;
67643
 
+
67644
 
+/* Used in byte code */
67645
 
+
67646
 
+extern const struct sieve_match_type rel_match_count_gt;
67647
 
+extern const struct sieve_match_type rel_match_count_ge;
67648
 
+extern const struct sieve_match_type rel_match_count_lt;
67649
 
+extern const struct sieve_match_type rel_match_count_le;
67650
 
+extern const struct sieve_match_type rel_match_count_eq;
67651
 
+extern const struct sieve_match_type rel_match_count_ne;
67652
 
+
67653
 
+extern const struct sieve_match_type rel_match_value_gt;
67654
 
+extern const struct sieve_match_type rel_match_value_ge;
67655
 
+extern const struct sieve_match_type rel_match_value_lt;
67656
 
+extern const struct sieve_match_type rel_match_value_le;
67657
 
+extern const struct sieve_match_type rel_match_value_eq;
67658
 
+extern const struct sieve_match_type rel_match_value_ne;
67659
 
+
67660
 
+/*
67661
 
+ * Operand
67662
 
+ */
67663
 
67664
 
+extern const struct sieve_operand rel_match_type_operand;
67665
 
+
67666
 
+
67667
 
+/*
67668
 
+ * Match type validation
67669
 
+ */
67670
 
+
67671
 
+bool mcht_relational_validate
67672
 
+       (struct sieve_validator *validator, struct sieve_ast_argument **arg, 
67673
 
+               struct sieve_match_type_context *ctx);
67674
 
+               
67675
 
+/*
67676
 
+ * Value match function (also used by :count)
67677
 
+ */
67678
 
67679
 
+int mcht_value_match
67680
 
+    (struct sieve_match_context *mctx, const char *val, size_t val_size,
67681
 
+        const char *key, size_t key_size, int key_index);
67682
 
+
67683
 
+
67684
 
+#endif /* __EXT_RELATIONAL_COMMON_H */
67685
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/relational/Makefile.am dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/relational/Makefile.am
67686
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/relational/Makefile.am 1970-01-01 01:00:00.000000000 +0100
67687
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/relational/Makefile.am  2008-10-20 01:35:49.000000000 +0200
67688
 
@@ -0,0 +1,17 @@
67689
 
+noinst_LTLIBRARIES = libsieve_ext_relational.la
67690
 
+
67691
 
+AM_CPPFLAGS = \
67692
 
+       -I../../ \
67693
 
+       -I$(dovecot_incdir) \
67694
 
+       -I$(dovecot_incdir)/src/lib \
67695
 
+       -I$(dovecot_incdir)/src/lib-mail \
67696
 
+       -I$(dovecot_incdir)/src/lib-storage 
67697
 
+
67698
 
+libsieve_ext_relational_la_SOURCES = \
67699
 
+       ext-relational-common.c \
67700
 
+       mcht-value.c \
67701
 
+       mcht-count.c \
67702
 
+       ext-relational.c 
67703
 
+
67704
 
+noinst_HEADERS = \
67705
 
+       ext-relational-common.h
67706
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/relational/Makefile.in dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/relational/Makefile.in
67707
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/relational/Makefile.in 1970-01-01 01:00:00.000000000 +0100
67708
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/relational/Makefile.in  2009-08-21 00:55:43.000000000 +0200
67709
 
@@ -0,0 +1,467 @@
67710
 
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
67711
 
+# @configure_input@
67712
 
+
67713
 
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
67714
 
+# 2003, 2004, 2005, 2006, 2007, 2008  Free Software Foundation, Inc.
67715
 
+# This Makefile.in is free software; the Free Software Foundation
67716
 
+# gives unlimited permission to copy and/or distribute it,
67717
 
+# with or without modifications, as long as this notice is preserved.
67718
 
+
67719
 
+# This program is distributed in the hope that it will be useful,
67720
 
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
67721
 
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
67722
 
+# PARTICULAR PURPOSE.
67723
 
+
67724
 
+@SET_MAKE@
67725
 
+
67726
 
+
67727
 
+VPATH = @srcdir@
67728
 
+pkgdatadir = $(datadir)/@PACKAGE@
67729
 
+pkglibdir = $(libdir)/@PACKAGE@
67730
 
+pkgincludedir = $(includedir)/@PACKAGE@
67731
 
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
67732
 
+install_sh_DATA = $(install_sh) -c -m 644
67733
 
+install_sh_PROGRAM = $(install_sh) -c
67734
 
+install_sh_SCRIPT = $(install_sh) -c
67735
 
+INSTALL_HEADER = $(INSTALL_DATA)
67736
 
+transform = $(program_transform_name)
67737
 
+NORMAL_INSTALL = :
67738
 
+PRE_INSTALL = :
67739
 
+POST_INSTALL = :
67740
 
+NORMAL_UNINSTALL = :
67741
 
+PRE_UNINSTALL = :
67742
 
+POST_UNINSTALL = :
67743
 
+build_triplet = @build@
67744
 
+host_triplet = @host@
67745
 
+subdir = src/lib-sieve/plugins/relational
67746
 
+DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
67747
 
+       $(srcdir)/Makefile.in
67748
 
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
67749
 
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
67750
 
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
67751
 
+       $(ACLOCAL_M4)
67752
 
+mkinstalldirs = $(install_sh) -d
67753
 
+CONFIG_HEADER = $(top_builddir)/dummy-config.h \
67754
 
+       $(top_builddir)/dsieve-config.h
67755
 
+CONFIG_CLEAN_FILES =
67756
 
+LTLIBRARIES = $(noinst_LTLIBRARIES)
67757
 
+libsieve_ext_relational_la_LIBADD =
67758
 
+am_libsieve_ext_relational_la_OBJECTS = ext-relational-common.lo \
67759
 
+       mcht-value.lo mcht-count.lo ext-relational.lo
67760
 
+libsieve_ext_relational_la_OBJECTS =  \
67761
 
+       $(am_libsieve_ext_relational_la_OBJECTS)
67762
 
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
67763
 
+depcomp = $(SHELL) $(top_srcdir)/depcomp
67764
 
+am__depfiles_maybe = depfiles
67765
 
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
67766
 
+       $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
67767
 
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
67768
 
+       --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
67769
 
+       $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
67770
 
+CCLD = $(CC)
67771
 
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
67772
 
+       --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
67773
 
+       $(LDFLAGS) -o $@
67774
 
+SOURCES = $(libsieve_ext_relational_la_SOURCES)
67775
 
+DIST_SOURCES = $(libsieve_ext_relational_la_SOURCES)
67776
 
+HEADERS = $(noinst_HEADERS)
67777
 
+ETAGS = etags
67778
 
+CTAGS = ctags
67779
 
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
67780
 
+ACLOCAL = @ACLOCAL@
67781
 
+AMTAR = @AMTAR@
67782
 
+AR = @AR@
67783
 
+AUTOCONF = @AUTOCONF@
67784
 
+AUTOHEADER = @AUTOHEADER@
67785
 
+AUTOMAKE = @AUTOMAKE@
67786
 
+AWK = @AWK@
67787
 
+CC = @CC@
67788
 
+CCDEPMODE = @CCDEPMODE@
67789
 
+CFLAGS = @CFLAGS@
67790
 
+CPP = @CPP@
67791
 
+CPPFLAGS = @CPPFLAGS@
67792
 
+CYGPATH_W = @CYGPATH_W@
67793
 
+DEFS = @DEFS@
67794
 
+DEPDIR = @DEPDIR@
67795
 
+DSYMUTIL = @DSYMUTIL@
67796
 
+DUMPBIN = @DUMPBIN@
67797
 
+ECHO_C = @ECHO_C@
67798
 
+ECHO_N = @ECHO_N@
67799
 
+ECHO_T = @ECHO_T@
67800
 
+EGREP = @EGREP@
67801
 
+EXEEXT = @EXEEXT@
67802
 
+FGREP = @FGREP@
67803
 
+GREP = @GREP@
67804
 
+INSTALL = @INSTALL@
67805
 
+INSTALL_DATA = @INSTALL_DATA@
67806
 
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
67807
 
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
67808
 
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
67809
 
+LD = @LD@
67810
 
+LDFLAGS = @LDFLAGS@
67811
 
+LIBICONV = @LIBICONV@
67812
 
+LIBOBJS = @LIBOBJS@
67813
 
+LIBS = @LIBS@
67814
 
+LIBTOOL = @LIBTOOL@
67815
 
+LIPO = @LIPO@
67816
 
+LN_S = @LN_S@
67817
 
+LTLIBOBJS = @LTLIBOBJS@
67818
 
+MAINT = @MAINT@
67819
 
+MAKEINFO = @MAKEINFO@
67820
 
+MKDIR_P = @MKDIR_P@
67821
 
+MODULE_LIBS = @MODULE_LIBS@
67822
 
+NM = @NM@
67823
 
+NMEDIT = @NMEDIT@
67824
 
+OBJDUMP = @OBJDUMP@
67825
 
+OBJEXT = @OBJEXT@
67826
 
+OTOOL = @OTOOL@
67827
 
+OTOOL64 = @OTOOL64@
67828
 
+PACKAGE = @PACKAGE@
67829
 
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
67830
 
+PACKAGE_NAME = @PACKAGE_NAME@
67831
 
+PACKAGE_STRING = @PACKAGE_STRING@
67832
 
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
67833
 
+PACKAGE_URL = @PACKAGE_URL@
67834
 
+PACKAGE_VERSION = @PACKAGE_VERSION@
67835
 
+PATH_SEPARATOR = @PATH_SEPARATOR@
67836
 
+RAND_LIBS = @RAND_LIBS@
67837
 
+RANLIB = @RANLIB@
67838
 
+SED = @SED@
67839
 
+SET_MAKE = @SET_MAKE@
67840
 
+SHELL = @SHELL@
67841
 
+STORAGE_LIBS = @STORAGE_LIBS@
67842
 
+STRIP = @STRIP@
67843
 
+VERSION = @VERSION@
67844
 
+abs_builddir = @abs_builddir@
67845
 
+abs_srcdir = @abs_srcdir@
67846
 
+abs_top_builddir = @abs_top_builddir@
67847
 
+abs_top_srcdir = @abs_top_srcdir@
67848
 
+ac_ct_CC = @ac_ct_CC@
67849
 
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
67850
 
+am__include = @am__include@
67851
 
+am__leading_dot = @am__leading_dot@
67852
 
+am__quote = @am__quote@
67853
 
+am__tar = @am__tar@
67854
 
+am__untar = @am__untar@
67855
 
+bindir = @bindir@
67856
 
+build = @build@
67857
 
+build_alias = @build_alias@
67858
 
+build_cpu = @build_cpu@
67859
 
+build_os = @build_os@
67860
 
+build_vendor = @build_vendor@
67861
 
+builddir = @builddir@
67862
 
+datadir = @datadir@
67863
 
+datarootdir = @datarootdir@
67864
 
+docdir = @docdir@
67865
 
+dovecot_incdir = @dovecot_incdir@
67866
 
+dovecotdir = @dovecotdir@
67867
 
+dvidir = @dvidir@
67868
 
+exec_prefix = @exec_prefix@
67869
 
+host = @host@
67870
 
+host_alias = @host_alias@
67871
 
+host_cpu = @host_cpu@
67872
 
+host_os = @host_os@
67873
 
+host_vendor = @host_vendor@
67874
 
+htmldir = @htmldir@
67875
 
+includedir = @includedir@
67876
 
+infodir = @infodir@
67877
 
+install_sh = @install_sh@
67878
 
+libdir = @libdir@
67879
 
+libexecdir = @libexecdir@
67880
 
+localedir = @localedir@
67881
 
+localstatedir = @localstatedir@
67882
 
+lt_ECHO = @lt_ECHO@
67883
 
+mandir = @mandir@
67884
 
+mkdir_p = @mkdir_p@
67885
 
+moduledir = @moduledir@
67886
 
+oldincludedir = @oldincludedir@
67887
 
+pdfdir = @pdfdir@
67888
 
+prefix = @prefix@
67889
 
+program_transform_name = @program_transform_name@
67890
 
+psdir = @psdir@
67891
 
+sbindir = @sbindir@
67892
 
+sharedstatedir = @sharedstatedir@
67893
 
+srcdir = @srcdir@
67894
 
+sysconfdir = @sysconfdir@
67895
 
+target_alias = @target_alias@
67896
 
+top_build_prefix = @top_build_prefix@
67897
 
+top_builddir = @top_builddir@
67898
 
+top_srcdir = @top_srcdir@
67899
 
+noinst_LTLIBRARIES = libsieve_ext_relational.la
67900
 
+AM_CPPFLAGS = \
67901
 
+       -I../../ \
67902
 
+       -I$(dovecot_incdir) \
67903
 
+       -I$(dovecot_incdir)/src/lib \
67904
 
+       -I$(dovecot_incdir)/src/lib-mail \
67905
 
+       -I$(dovecot_incdir)/src/lib-storage 
67906
 
+
67907
 
+libsieve_ext_relational_la_SOURCES = \
67908
 
+       ext-relational-common.c \
67909
 
+       mcht-value.c \
67910
 
+       mcht-count.c \
67911
 
+       ext-relational.c 
67912
 
+
67913
 
+noinst_HEADERS = \
67914
 
+       ext-relational-common.h
67915
 
+
67916
 
+all: all-am
67917
 
+
67918
 
+.SUFFIXES:
67919
 
+.SUFFIXES: .c .lo .o .obj
67920
 
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
67921
 
+       @for dep in $?; do \
67922
 
+         case '$(am__configure_deps)' in \
67923
 
+           *$$dep*) \
67924
 
+             ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
67925
 
+               && { if test -f $@; then exit 0; else break; fi; }; \
67926
 
+             exit 1;; \
67927
 
+         esac; \
67928
 
+       done; \
67929
 
+       echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign  src/lib-sieve/plugins/relational/Makefile'; \
67930
 
+       cd $(top_srcdir) && \
67931
 
+         $(AUTOMAKE) --foreign  src/lib-sieve/plugins/relational/Makefile
67932
 
+.PRECIOUS: Makefile
67933
 
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
67934
 
+       @case '$?' in \
67935
 
+         *config.status*) \
67936
 
+           cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
67937
 
+         *) \
67938
 
+           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
67939
 
+           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
67940
 
+       esac;
67941
 
+
67942
 
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
67943
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
67944
 
+
67945
 
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
67946
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
67947
 
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
67948
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
67949
 
+
67950
 
+clean-noinstLTLIBRARIES:
67951
 
+       -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
67952
 
+       @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
67953
 
+         dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
67954
 
+         test "$$dir" != "$$p" || dir=.; \
67955
 
+         echo "rm -f \"$${dir}/so_locations\""; \
67956
 
+         rm -f "$${dir}/so_locations"; \
67957
 
+       done
67958
 
+libsieve_ext_relational.la: $(libsieve_ext_relational_la_OBJECTS) $(libsieve_ext_relational_la_DEPENDENCIES) 
67959
 
+       $(LINK)  $(libsieve_ext_relational_la_OBJECTS) $(libsieve_ext_relational_la_LIBADD) $(LIBS)
67960
 
+
67961
 
+mostlyclean-compile:
67962
 
+       -rm -f *.$(OBJEXT)
67963
 
+
67964
 
+distclean-compile:
67965
 
+       -rm -f *.tab.c
67966
 
+
67967
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-relational-common.Plo@am__quote@
67968
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-relational.Plo@am__quote@
67969
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mcht-count.Plo@am__quote@
67970
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mcht-value.Plo@am__quote@
67971
 
+
67972
 
+.c.o:
67973
 
+@am__fastdepCC_TRUE@   $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
67974
 
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
67975
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
67976
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
67977
 
+@am__fastdepCC_FALSE@  $(COMPILE) -c $<
67978
 
+
67979
 
+.c.obj:
67980
 
+@am__fastdepCC_TRUE@   $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
67981
 
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
67982
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
67983
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
67984
 
+@am__fastdepCC_FALSE@  $(COMPILE) -c `$(CYGPATH_W) '$<'`
67985
 
+
67986
 
+.c.lo:
67987
 
+@am__fastdepCC_TRUE@   $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
67988
 
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
67989
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
67990
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
67991
 
+@am__fastdepCC_FALSE@  $(LTCOMPILE) -c -o $@ $<
67992
 
+
67993
 
+mostlyclean-libtool:
67994
 
+       -rm -f *.lo
67995
 
+
67996
 
+clean-libtool:
67997
 
+       -rm -rf .libs _libs
67998
 
+
67999
 
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
68000
 
+       list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
68001
 
+       unique=`for i in $$list; do \
68002
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
68003
 
+         done | \
68004
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
68005
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
68006
 
+       mkid -fID $$unique
68007
 
+tags: TAGS
68008
 
+
68009
 
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
68010
 
+               $(TAGS_FILES) $(LISP)
68011
 
+       tags=; \
68012
 
+       here=`pwd`; \
68013
 
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
68014
 
+       unique=`for i in $$list; do \
68015
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
68016
 
+         done | \
68017
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
68018
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
68019
 
+       if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
68020
 
+         test -n "$$unique" || unique=$$empty_fix; \
68021
 
+         $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
68022
 
+           $$tags $$unique; \
68023
 
+       fi
68024
 
+ctags: CTAGS
68025
 
+CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
68026
 
+               $(TAGS_FILES) $(LISP)
68027
 
+       tags=; \
68028
 
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
68029
 
+       unique=`for i in $$list; do \
68030
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
68031
 
+         done | \
68032
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
68033
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
68034
 
+       test -z "$(CTAGS_ARGS)$$tags$$unique" \
68035
 
+         || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
68036
 
+            $$tags $$unique
68037
 
+
68038
 
+GTAGS:
68039
 
+       here=`$(am__cd) $(top_builddir) && pwd` \
68040
 
+         && cd $(top_srcdir) \
68041
 
+         && gtags -i $(GTAGS_ARGS) $$here
68042
 
+
68043
 
+distclean-tags:
68044
 
+       -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
68045
 
+
68046
 
+distdir: $(DISTFILES)
68047
 
+       @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
68048
 
+       topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
68049
 
+       list='$(DISTFILES)'; \
68050
 
+         dist_files=`for file in $$list; do echo $$file; done | \
68051
 
+         sed -e "s|^$$srcdirstrip/||;t" \
68052
 
+             -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
68053
 
+       case $$dist_files in \
68054
 
+         */*) $(MKDIR_P) `echo "$$dist_files" | \
68055
 
+                          sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
68056
 
+                          sort -u` ;; \
68057
 
+       esac; \
68058
 
+       for file in $$dist_files; do \
68059
 
+         if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
68060
 
+         if test -d $$d/$$file; then \
68061
 
+           dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
68062
 
+           if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
68063
 
+             cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
68064
 
+           fi; \
68065
 
+           cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
68066
 
+         else \
68067
 
+           test -f $(distdir)/$$file \
68068
 
+           || cp -p $$d/$$file $(distdir)/$$file \
68069
 
+           || exit 1; \
68070
 
+         fi; \
68071
 
+       done
68072
 
+check-am: all-am
68073
 
+check: check-am
68074
 
+all-am: Makefile $(LTLIBRARIES) $(HEADERS)
68075
 
+installdirs:
68076
 
+install: install-am
68077
 
+install-exec: install-exec-am
68078
 
+install-data: install-data-am
68079
 
+uninstall: uninstall-am
68080
 
+
68081
 
+install-am: all-am
68082
 
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
68083
 
+
68084
 
+installcheck: installcheck-am
68085
 
+install-strip:
68086
 
+       $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
68087
 
+         install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
68088
 
+         `test -z '$(STRIP)' || \
68089
 
+           echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
68090
 
+mostlyclean-generic:
68091
 
+
68092
 
+clean-generic:
68093
 
+
68094
 
+distclean-generic:
68095
 
+       -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
68096
 
+
68097
 
+maintainer-clean-generic:
68098
 
+       @echo "This command is intended for maintainers to use"
68099
 
+       @echo "it deletes files that may require special tools to rebuild."
68100
 
+clean: clean-am
68101
 
+
68102
 
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
68103
 
+       mostlyclean-am
68104
 
+
68105
 
+distclean: distclean-am
68106
 
+       -rm -rf ./$(DEPDIR)
68107
 
+       -rm -f Makefile
68108
 
+distclean-am: clean-am distclean-compile distclean-generic \
68109
 
+       distclean-tags
68110
 
+
68111
 
+dvi: dvi-am
68112
 
+
68113
 
+dvi-am:
68114
 
+
68115
 
+html: html-am
68116
 
+
68117
 
+info: info-am
68118
 
+
68119
 
+info-am:
68120
 
+
68121
 
+install-data-am:
68122
 
+
68123
 
+install-dvi: install-dvi-am
68124
 
+
68125
 
+install-exec-am:
68126
 
+
68127
 
+install-html: install-html-am
68128
 
+
68129
 
+install-info: install-info-am
68130
 
+
68131
 
+install-man:
68132
 
+
68133
 
+install-pdf: install-pdf-am
68134
 
+
68135
 
+install-ps: install-ps-am
68136
 
+
68137
 
+installcheck-am:
68138
 
+
68139
 
+maintainer-clean: maintainer-clean-am
68140
 
+       -rm -rf ./$(DEPDIR)
68141
 
+       -rm -f Makefile
68142
 
+maintainer-clean-am: distclean-am maintainer-clean-generic
68143
 
+
68144
 
+mostlyclean: mostlyclean-am
68145
 
+
68146
 
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
68147
 
+       mostlyclean-libtool
68148
 
+
68149
 
+pdf: pdf-am
68150
 
+
68151
 
+pdf-am:
68152
 
+
68153
 
+ps: ps-am
68154
 
+
68155
 
+ps-am:
68156
 
+
68157
 
+uninstall-am:
68158
 
+
68159
 
+.MAKE: install-am install-strip
68160
 
+
68161
 
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
68162
 
+       clean-libtool clean-noinstLTLIBRARIES ctags distclean \
68163
 
+       distclean-compile distclean-generic distclean-libtool \
68164
 
+       distclean-tags distdir dvi dvi-am html html-am info info-am \
68165
 
+       install install-am install-data install-data-am install-dvi \
68166
 
+       install-dvi-am install-exec install-exec-am install-html \
68167
 
+       install-html-am install-info install-info-am install-man \
68168
 
+       install-pdf install-pdf-am install-ps install-ps-am \
68169
 
+       install-strip installcheck installcheck-am installdirs \
68170
 
+       maintainer-clean maintainer-clean-generic mostlyclean \
68171
 
+       mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
68172
 
+       pdf pdf-am ps ps-am tags uninstall uninstall-am
68173
 
+
68174
 
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
68175
 
+# Otherwise a system limit (for SysV at least) may be exceeded.
68176
 
+.NOEXPORT:
68177
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/relational/mcht-count.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/relational/mcht-count.c
68178
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/relational/mcht-count.c        1970-01-01 01:00:00.000000000 +0100
68179
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/relational/mcht-count.c 2009-07-30 00:39:12.000000000 +0200
68180
 
@@ -0,0 +1,136 @@
68181
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
68182
 
+ */
68183
 
68184
 
+/* Match-type ':count' 
68185
 
+ */
68186
 
+
68187
 
+#include "lib.h"
68188
 
+#include "str.h"
68189
 
+
68190
 
+#include "sieve-common.h"
68191
 
+#include "sieve-ast.h"
68192
 
+#include "sieve-code.h"
68193
 
+#include "sieve-extensions.h"
68194
 
+#include "sieve-commands.h"
68195
 
+#include "sieve-comparators.h"
68196
 
+#include "sieve-match-types.h"
68197
 
+#include "sieve-validator.h"
68198
 
+#include "sieve-generator.h"
68199
 
+#include "sieve-interpreter.h"
68200
 
+#include "sieve-match.h"
68201
 
+
68202
 
+#include "ext-relational-common.h"
68203
 
+
68204
 
+/* 
68205
 
+ * Forward declarations
68206
 
+ */
68207
 
+
68208
 
+static void mcht_count_match_init(struct sieve_match_context *mctx);
68209
 
+static int mcht_count_match
68210
 
+       (struct sieve_match_context *mctx, const char *val, size_t val_size, 
68211
 
+               const char *key, size_t key_size, int key_index);
68212
 
+static int mcht_count_match_deinit(struct sieve_match_context *mctx);
68213
 
+
68214
 
+/* 
68215
 
+ * Match-type objects
68216
 
+ */
68217
 
68218
 
+const struct sieve_match_type count_match_type = {
68219
 
+       SIEVE_OBJECT("count", &rel_match_type_operand, RELATIONAL_COUNT),
68220
 
+       FALSE, FALSE,
68221
 
+       mcht_relational_validate,
68222
 
+       NULL, NULL, NULL, NULL
68223
 
+};
68224
 
+
68225
 
+#define COUNT_MATCH_TYPE(name, rel_match)                     \
68226
 
+const struct sieve_match_type rel_match_count_ ## name = {    \
68227
 
+       SIEVE_OBJECT(                                             \
68228
 
+               "count-" #name, &rel_match_type_operand,              \
68229
 
+               REL_MATCH_INDEX(RELATIONAL_COUNT, rel_match)),        \
68230
 
+       FALSE, FALSE,                                             \
68231
 
+       NULL, NULL,                                               \
68232
 
+       mcht_count_match_init,                                    \
68233
 
+       mcht_count_match,                                         \
68234
 
+       mcht_count_match_deinit                                   \
68235
 
+}
68236
 
+       
68237
 
+COUNT_MATCH_TYPE(gt, REL_MATCH_GREATER);
68238
 
+COUNT_MATCH_TYPE(ge, REL_MATCH_GREATER_EQUAL);
68239
 
+COUNT_MATCH_TYPE(lt, REL_MATCH_LESS);
68240
 
+COUNT_MATCH_TYPE(le, REL_MATCH_LESS_EQUAL);
68241
 
+COUNT_MATCH_TYPE(eq, REL_MATCH_EQUAL);
68242
 
+COUNT_MATCH_TYPE(ne, REL_MATCH_NOT_EQUAL);
68243
 
+
68244
 
+/* 
68245
 
+ * Match-type implementation 
68246
 
+ */
68247
 
+
68248
 
+struct mcht_count_context {
68249
 
+       unsigned int count;
68250
 
+};
68251
 
+
68252
 
+static void mcht_count_match_init(struct sieve_match_context *mctx)
68253
 
+{
68254
 
+       struct mcht_count_context *cctx = p_new(mctx->pool, struct mcht_count_context, 1);
68255
 
+
68256
 
+       cctx->count = 0;
68257
 
+       mctx->data = (void *) cctx;
68258
 
+}
68259
 
+
68260
 
+static int mcht_count_match
68261
 
+(struct sieve_match_context *mctx, 
68262
 
+       const char *val ATTR_UNUSED, size_t val_size ATTR_UNUSED, 
68263
 
+       const char *key ATTR_UNUSED, size_t key_size ATTR_UNUSED,
68264
 
+       int key_index) 
68265
 
+{
68266
 
+       if ( val == NULL )
68267
 
+               return FALSE;
68268
 
+
68269
 
+       /* Count values */
68270
 
+       if ( key_index == -1 ) {
68271
 
+               struct mcht_count_context *cctx = 
68272
 
+                       (struct mcht_count_context *) mctx->data;
68273
 
+
68274
 
+               cctx->count++;
68275
 
+       }
68276
 
+
68277
 
+       return FALSE;
68278
 
+}
68279
 
+
68280
 
+static int mcht_count_match_deinit(struct sieve_match_context *mctx)
68281
 
+{
68282
 
+       struct mcht_count_context *cctx =
68283
 
+            (struct mcht_count_context *) mctx->data;
68284
 
+       int key_index;
68285
 
+       string_t *key_item;
68286
 
+    sieve_coded_stringlist_reset(mctx->key_list);
68287
 
+       bool ok = TRUE;
68288
 
+
68289
 
+       string_t *value = t_str_new(20);
68290
 
+       str_printfa(value, "%d", cctx->count);
68291
 
+
68292
 
+    /* Match to all key values */
68293
 
+    key_index = 0;
68294
 
+    key_item = NULL;
68295
 
+    while ( (ok=sieve_coded_stringlist_next_item(mctx->key_list, &key_item)) 
68296
 
+               && key_item != NULL )
68297
 
+    {
68298
 
+               int ret = mcht_value_match
68299
 
+                       (mctx, str_c(value), str_len(value), str_c(key_item), 
68300
 
+                               str_len(key_item), key_index);
68301
 
+        
68302
 
+               if ( ret > 0 )   
68303
 
+                       return TRUE;
68304
 
+       
68305
 
+               if ( ret < 0 )
68306
 
+                       return ret;
68307
 
+
68308
 
+        key_index++;
68309
 
+    }
68310
 
+
68311
 
+       return ( ok ? FALSE : -1 );
68312
 
+}
68313
 
+
68314
 
+
68315
 
+
68316
 
+
68317
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/relational/mcht-value.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/relational/mcht-value.c
68318
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/relational/mcht-value.c        1970-01-01 01:00:00.000000000 +0100
68319
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/relational/mcht-value.c 2009-01-06 00:15:52.000000000 +0100
68320
 
@@ -0,0 +1,92 @@
68321
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
68322
 
+ */
68323
 
+
68324
 
+#include "lib.h"
68325
 
+#include "str.h"
68326
 
+
68327
 
+#include "sieve-common.h"
68328
 
+
68329
 
+#include "sieve-ast.h"
68330
 
+#include "sieve-code.h"
68331
 
+#include "sieve-extensions.h"
68332
 
+#include "sieve-commands.h"
68333
 
+#include "sieve-comparators.h"
68334
 
+#include "sieve-match-types.h"
68335
 
+#include "sieve-validator.h"
68336
 
+#include "sieve-generator.h"
68337
 
+#include "sieve-interpreter.h"
68338
 
+#include "sieve-match.h"
68339
 
+
68340
 
+#include "ext-relational-common.h"
68341
 
+
68342
 
+/*
68343
 
+ * Match-type objects
68344
 
+ */
68345
 
+
68346
 
+const struct sieve_match_type value_match_type = {
68347
 
+       SIEVE_OBJECT("value", &rel_match_type_operand, RELATIONAL_VALUE), 
68348
 
+       TRUE, TRUE,
68349
 
+       mcht_relational_validate,
68350
 
+       NULL, NULL, NULL, NULL
68351
 
+};
68352
 
+
68353
 
+#define VALUE_MATCH_TYPE(name, rel_match)                   \
68354
 
+const struct sieve_match_type rel_match_value_ ## name = {  \
68355
 
+       SIEVE_OBJECT(                                           \
68356
 
+               "value-" #name, &rel_match_type_operand,            \
68357
 
+               REL_MATCH_INDEX(RELATIONAL_VALUE, rel_match)),      \
68358
 
+       TRUE, TRUE,                                             \
68359
 
+       NULL, NULL, NULL,                                       \
68360
 
+       mcht_value_match,                                       \
68361
 
+       NULL                                                    \
68362
 
+}
68363
 
+
68364
 
+VALUE_MATCH_TYPE(gt, REL_MATCH_GREATER);
68365
 
+VALUE_MATCH_TYPE(ge, REL_MATCH_GREATER_EQUAL); 
68366
 
+VALUE_MATCH_TYPE(lt, REL_MATCH_LESS);
68367
 
+VALUE_MATCH_TYPE(le, REL_MATCH_LESS_EQUAL); 
68368
 
+VALUE_MATCH_TYPE(eq, REL_MATCH_EQUAL);
68369
 
+VALUE_MATCH_TYPE(ne, REL_MATCH_NOT_EQUAL);
68370
 
+
68371
 
+/* 
68372
 
+ * Match-type implementation 
68373
 
+ */
68374
 
+
68375
 
+int mcht_value_match
68376
 
+(struct sieve_match_context *mctx, const char *val, size_t val_size, 
68377
 
+       const char *key, size_t key_size, int key_index ATTR_UNUSED)
68378
 
+{
68379
 
+       const struct sieve_match_type *mtch = mctx->match_type;
68380
 
+       unsigned int rel_match = REL_MATCH(mtch->object.code);  
68381
 
+       int cmp_result;
68382
 
+
68383
 
+       if ( val == NULL ) {
68384
 
+               val = "";
68385
 
+               val_size = 0;
68386
 
+       }
68387
 
+
68388
 
+       cmp_result = mctx->comparator->
68389
 
+               compare(mctx->comparator, val, val_size, key, key_size);
68390
 
+
68391
 
+       switch ( rel_match ) {
68392
 
+       case REL_MATCH_GREATER:
68393
 
+               return ( cmp_result > 0 );
68394
 
+       case REL_MATCH_GREATER_EQUAL:
68395
 
+               return ( cmp_result >= 0 );
68396
 
+       case REL_MATCH_LESS:
68397
 
+               return ( cmp_result < 0 );
68398
 
+       case REL_MATCH_LESS_EQUAL:
68399
 
+               return ( cmp_result <= 0 );
68400
 
+       case REL_MATCH_EQUAL:
68401
 
+               return ( cmp_result == 0 );
68402
 
+       case REL_MATCH_NOT_EQUAL:
68403
 
+               return ( cmp_result != 0 );
68404
 
+       case REL_MATCH_INVALID:
68405
 
+       default:
68406
 
+               break;
68407
 
+       }       
68408
 
+       
68409
 
+       return FALSE;
68410
 
+}
68411
 
+
68412
 
+
68413
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/subaddress/ext-subaddress.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/subaddress/ext-subaddress.c
68414
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/subaddress/ext-subaddress.c    1970-01-01 01:00:00.000000000 +0100
68415
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/subaddress/ext-subaddress.c     2009-04-10 13:53:54.000000000 +0200
68416
 
@@ -0,0 +1,163 @@
68417
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
68418
 
+ */
68419
 
+
68420
 
+/* Extension subaddress 
68421
 
+ * --------------------
68422
 
+ *
68423
 
+ * Author: Stephan Bosch
68424
 
+ * Specification: RFC 3598
68425
 
+ * Implementation: full, but not configurable
68426
 
+ * Status: experimental, largely untested
68427
 
+ * 
68428
 
+ * FIXME: This extension is not configurable in any way. The separation 
68429
 
+ * character is currently only configurable for compilation and not at runtime. 
68430
 
+ *
68431
 
+ */
68432
 
68433
 
+#include "sieve-common.h"
68434
 
+
68435
 
+#include "sieve-code.h"
68436
 
+#include "sieve-address.h"
68437
 
+#include "sieve-extensions.h"
68438
 
+#include "sieve-commands.h"
68439
 
+#include "sieve-address-parts.h"
68440
 
+#include "sieve-validator.h"
68441
 
+#include "sieve-generator.h"
68442
 
+#include "sieve-interpreter.h"
68443
 
+
68444
 
+#include <stdlib.h>
68445
 
+#include <string.h>
68446
 
+
68447
 
+/* 
68448
 
+ * Configuration 
68449
 
+ */
68450
 
+
68451
 
+#define SUBADDRESS_DEFAULT_SEP "+"
68452
 
+
68453
 
+static const char *sieve_subaddress_sep = SUBADDRESS_DEFAULT_SEP;
68454
 
+
68455
 
+/*
68456
 
+ * Forward declarations 
68457
 
+ */
68458
 
+
68459
 
+const struct sieve_address_part user_address_part;
68460
 
+const struct sieve_address_part detail_address_part;
68461
 
+
68462
 
+static struct sieve_operand subaddress_operand;
68463
 
+
68464
 
+/*
68465
 
+ * Extension
68466
 
+ */
68467
 
+
68468
 
+static bool ext_subaddress_load(void);
68469
 
+static bool ext_subaddress_validator_load(struct sieve_validator *validator);
68470
 
+
68471
 
+static int ext_my_id = -1;
68472
 
+
68473
 
+const struct sieve_extension subaddress_extension = { 
68474
 
+       "subaddress", 
68475
 
+       &ext_my_id,
68476
 
+       ext_subaddress_load, 
68477
 
+       NULL,
68478
 
+       ext_subaddress_validator_load,
68479
 
+       NULL, NULL, NULL, NULL, NULL,
68480
 
+       SIEVE_EXT_DEFINE_NO_OPERATIONS, 
68481
 
+       SIEVE_EXT_DEFINE_OPERAND(subaddress_operand)
68482
 
+};
68483
 
+
68484
 
+static bool ext_subaddress_load(void)
68485
 
+{
68486
 
+       sieve_subaddress_sep = getenv("SIEVE_SUBADDRESS_SEP");
68487
 
+
68488
 
+       if ( sieve_subaddress_sep == NULL )
68489
 
+               sieve_subaddress_sep = SUBADDRESS_DEFAULT_SEP;
68490
 
+
68491
 
+       return TRUE;
68492
 
+}
68493
 
+
68494
 
+static bool ext_subaddress_validator_load(struct sieve_validator *validator)
68495
 
+{
68496
 
+       sieve_address_part_register(validator, &user_address_part); 
68497
 
+       sieve_address_part_register(validator, &detail_address_part); 
68498
 
+
68499
 
+       return TRUE;
68500
 
+}
68501
 
+
68502
 
+/*
68503
 
+ * Address parts
68504
 
+ */
68505
 
68506
 
+enum ext_subaddress_address_part {
68507
 
+  SUBADDRESS_USER,
68508
 
+  SUBADDRESS_DETAIL
68509
 
+};
68510
 
+
68511
 
+/* Forward declarations */
68512
 
+
68513
 
+static const char *subaddress_user_extract_from
68514
 
+       (const struct sieve_address *address);
68515
 
+static const char *subaddress_detail_extract_from
68516
 
+       (const struct sieve_address *address);
68517
 
+
68518
 
+
68519
 
+/* Address part objects */     
68520
 
+
68521
 
+const struct sieve_address_part user_address_part = {
68522
 
+       SIEVE_OBJECT("user", &subaddress_operand, SUBADDRESS_USER),
68523
 
+       subaddress_user_extract_from
68524
 
+};
68525
 
+
68526
 
+const struct sieve_address_part detail_address_part = {
68527
 
+       SIEVE_OBJECT("detail", &subaddress_operand, SUBADDRESS_DETAIL),
68528
 
+       subaddress_detail_extract_from
68529
 
+};
68530
 
+
68531
 
+/* Address part implementation */
68532
 
+
68533
 
+static const char *subaddress_user_extract_from
68534
 
+       (const struct sieve_address *address)
68535
 
+{
68536
 
+       const char *sep;
68537
 
+
68538
 
+       sep = strstr(address->local_part, sieve_subaddress_sep);
68539
 
+       
68540
 
+       if ( sep == NULL ) return address->local_part;
68541
 
+       
68542
 
+       return t_strdup_until(address->local_part, sep);
68543
 
+}
68544
 
+
68545
 
+static const char *subaddress_detail_extract_from
68546
 
+       (const struct sieve_address *address)
68547
 
+{
68548
 
+       const char *sep;
68549
 
+
68550
 
+       if ( (sep=strstr(address->local_part, sieve_subaddress_sep)) == NULL )
68551
 
+               return NULL; 
68552
 
+
68553
 
+       sep += strlen(sieve_subaddress_sep);
68554
 
+
68555
 
+       /* Just to be sure */
68556
 
+       if ( sep > (address->local_part + strlen(address->local_part)) ) 
68557
 
+               return NULL;
68558
 
+
68559
 
+       return sep;
68560
 
+}
68561
 
+
68562
 
+/*
68563
 
+ * Operand 
68564
 
+ */
68565
 
+
68566
 
+const struct sieve_address_part *ext_subaddress_parts[] = {
68567
 
+       &user_address_part, &detail_address_part
68568
 
+};
68569
 
+
68570
 
+static const struct sieve_extension_objects ext_address_parts =
68571
 
+       SIEVE_EXT_DEFINE_ADDRESS_PARTS(ext_subaddress_parts);
68572
 
+
68573
 
+static struct sieve_operand subaddress_operand = { 
68574
 
+       "address-part", 
68575
 
+       &subaddress_extension, 0,
68576
 
+       &sieve_address_part_operand_class,
68577
 
+       &ext_address_parts
68578
 
+};
68579
 
+
68580
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/subaddress/Makefile.am dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/subaddress/Makefile.am
68581
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/subaddress/Makefile.am 1970-01-01 01:00:00.000000000 +0100
68582
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/subaddress/Makefile.am  2008-10-20 01:35:49.000000000 +0200
68583
 
@@ -0,0 +1,11 @@
68584
 
+noinst_LTLIBRARIES = libsieve_ext_subaddress.la
68585
 
+
68586
 
+AM_CPPFLAGS = \
68587
 
+       -I../../ \
68588
 
+       -I$(dovecot_incdir) \
68589
 
+       -I$(dovecot_incdir)/src/lib \
68590
 
+       -I$(dovecot_incdir)/src/lib-mail \
68591
 
+       -I$(dovecot_incdir)/src/lib-storage 
68592
 
+
68593
 
+libsieve_ext_subaddress_la_SOURCES = \
68594
 
+       ext-subaddress.c
68595
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/subaddress/Makefile.in dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/subaddress/Makefile.in
68596
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/subaddress/Makefile.in 1970-01-01 01:00:00.000000000 +0100
68597
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/subaddress/Makefile.in  2009-08-21 00:55:44.000000000 +0200
68598
 
@@ -0,0 +1,454 @@
68599
 
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
68600
 
+# @configure_input@
68601
 
+
68602
 
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
68603
 
+# 2003, 2004, 2005, 2006, 2007, 2008  Free Software Foundation, Inc.
68604
 
+# This Makefile.in is free software; the Free Software Foundation
68605
 
+# gives unlimited permission to copy and/or distribute it,
68606
 
+# with or without modifications, as long as this notice is preserved.
68607
 
+
68608
 
+# This program is distributed in the hope that it will be useful,
68609
 
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
68610
 
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
68611
 
+# PARTICULAR PURPOSE.
68612
 
+
68613
 
+@SET_MAKE@
68614
 
+
68615
 
+VPATH = @srcdir@
68616
 
+pkgdatadir = $(datadir)/@PACKAGE@
68617
 
+pkglibdir = $(libdir)/@PACKAGE@
68618
 
+pkgincludedir = $(includedir)/@PACKAGE@
68619
 
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
68620
 
+install_sh_DATA = $(install_sh) -c -m 644
68621
 
+install_sh_PROGRAM = $(install_sh) -c
68622
 
+install_sh_SCRIPT = $(install_sh) -c
68623
 
+INSTALL_HEADER = $(INSTALL_DATA)
68624
 
+transform = $(program_transform_name)
68625
 
+NORMAL_INSTALL = :
68626
 
+PRE_INSTALL = :
68627
 
+POST_INSTALL = :
68628
 
+NORMAL_UNINSTALL = :
68629
 
+PRE_UNINSTALL = :
68630
 
+POST_UNINSTALL = :
68631
 
+build_triplet = @build@
68632
 
+host_triplet = @host@
68633
 
+subdir = src/lib-sieve/plugins/subaddress
68634
 
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
68635
 
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
68636
 
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
68637
 
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
68638
 
+       $(ACLOCAL_M4)
68639
 
+mkinstalldirs = $(install_sh) -d
68640
 
+CONFIG_HEADER = $(top_builddir)/dummy-config.h \
68641
 
+       $(top_builddir)/dsieve-config.h
68642
 
+CONFIG_CLEAN_FILES =
68643
 
+LTLIBRARIES = $(noinst_LTLIBRARIES)
68644
 
+libsieve_ext_subaddress_la_LIBADD =
68645
 
+am_libsieve_ext_subaddress_la_OBJECTS = ext-subaddress.lo
68646
 
+libsieve_ext_subaddress_la_OBJECTS =  \
68647
 
+       $(am_libsieve_ext_subaddress_la_OBJECTS)
68648
 
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
68649
 
+depcomp = $(SHELL) $(top_srcdir)/depcomp
68650
 
+am__depfiles_maybe = depfiles
68651
 
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
68652
 
+       $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
68653
 
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
68654
 
+       --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
68655
 
+       $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
68656
 
+CCLD = $(CC)
68657
 
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
68658
 
+       --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
68659
 
+       $(LDFLAGS) -o $@
68660
 
+SOURCES = $(libsieve_ext_subaddress_la_SOURCES)
68661
 
+DIST_SOURCES = $(libsieve_ext_subaddress_la_SOURCES)
68662
 
+ETAGS = etags
68663
 
+CTAGS = ctags
68664
 
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
68665
 
+ACLOCAL = @ACLOCAL@
68666
 
+AMTAR = @AMTAR@
68667
 
+AR = @AR@
68668
 
+AUTOCONF = @AUTOCONF@
68669
 
+AUTOHEADER = @AUTOHEADER@
68670
 
+AUTOMAKE = @AUTOMAKE@
68671
 
+AWK = @AWK@
68672
 
+CC = @CC@
68673
 
+CCDEPMODE = @CCDEPMODE@
68674
 
+CFLAGS = @CFLAGS@
68675
 
+CPP = @CPP@
68676
 
+CPPFLAGS = @CPPFLAGS@
68677
 
+CYGPATH_W = @CYGPATH_W@
68678
 
+DEFS = @DEFS@
68679
 
+DEPDIR = @DEPDIR@
68680
 
+DSYMUTIL = @DSYMUTIL@
68681
 
+DUMPBIN = @DUMPBIN@
68682
 
+ECHO_C = @ECHO_C@
68683
 
+ECHO_N = @ECHO_N@
68684
 
+ECHO_T = @ECHO_T@
68685
 
+EGREP = @EGREP@
68686
 
+EXEEXT = @EXEEXT@
68687
 
+FGREP = @FGREP@
68688
 
+GREP = @GREP@
68689
 
+INSTALL = @INSTALL@
68690
 
+INSTALL_DATA = @INSTALL_DATA@
68691
 
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
68692
 
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
68693
 
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
68694
 
+LD = @LD@
68695
 
+LDFLAGS = @LDFLAGS@
68696
 
+LIBICONV = @LIBICONV@
68697
 
+LIBOBJS = @LIBOBJS@
68698
 
+LIBS = @LIBS@
68699
 
+LIBTOOL = @LIBTOOL@
68700
 
+LIPO = @LIPO@
68701
 
+LN_S = @LN_S@
68702
 
+LTLIBOBJS = @LTLIBOBJS@
68703
 
+MAINT = @MAINT@
68704
 
+MAKEINFO = @MAKEINFO@
68705
 
+MKDIR_P = @MKDIR_P@
68706
 
+MODULE_LIBS = @MODULE_LIBS@
68707
 
+NM = @NM@
68708
 
+NMEDIT = @NMEDIT@
68709
 
+OBJDUMP = @OBJDUMP@
68710
 
+OBJEXT = @OBJEXT@
68711
 
+OTOOL = @OTOOL@
68712
 
+OTOOL64 = @OTOOL64@
68713
 
+PACKAGE = @PACKAGE@
68714
 
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
68715
 
+PACKAGE_NAME = @PACKAGE_NAME@
68716
 
+PACKAGE_STRING = @PACKAGE_STRING@
68717
 
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
68718
 
+PACKAGE_URL = @PACKAGE_URL@
68719
 
+PACKAGE_VERSION = @PACKAGE_VERSION@
68720
 
+PATH_SEPARATOR = @PATH_SEPARATOR@
68721
 
+RAND_LIBS = @RAND_LIBS@
68722
 
+RANLIB = @RANLIB@
68723
 
+SED = @SED@
68724
 
+SET_MAKE = @SET_MAKE@
68725
 
+SHELL = @SHELL@
68726
 
+STORAGE_LIBS = @STORAGE_LIBS@
68727
 
+STRIP = @STRIP@
68728
 
+VERSION = @VERSION@
68729
 
+abs_builddir = @abs_builddir@
68730
 
+abs_srcdir = @abs_srcdir@
68731
 
+abs_top_builddir = @abs_top_builddir@
68732
 
+abs_top_srcdir = @abs_top_srcdir@
68733
 
+ac_ct_CC = @ac_ct_CC@
68734
 
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
68735
 
+am__include = @am__include@
68736
 
+am__leading_dot = @am__leading_dot@
68737
 
+am__quote = @am__quote@
68738
 
+am__tar = @am__tar@
68739
 
+am__untar = @am__untar@
68740
 
+bindir = @bindir@
68741
 
+build = @build@
68742
 
+build_alias = @build_alias@
68743
 
+build_cpu = @build_cpu@
68744
 
+build_os = @build_os@
68745
 
+build_vendor = @build_vendor@
68746
 
+builddir = @builddir@
68747
 
+datadir = @datadir@
68748
 
+datarootdir = @datarootdir@
68749
 
+docdir = @docdir@
68750
 
+dovecot_incdir = @dovecot_incdir@
68751
 
+dovecotdir = @dovecotdir@
68752
 
+dvidir = @dvidir@
68753
 
+exec_prefix = @exec_prefix@
68754
 
+host = @host@
68755
 
+host_alias = @host_alias@
68756
 
+host_cpu = @host_cpu@
68757
 
+host_os = @host_os@
68758
 
+host_vendor = @host_vendor@
68759
 
+htmldir = @htmldir@
68760
 
+includedir = @includedir@
68761
 
+infodir = @infodir@
68762
 
+install_sh = @install_sh@
68763
 
+libdir = @libdir@
68764
 
+libexecdir = @libexecdir@
68765
 
+localedir = @localedir@
68766
 
+localstatedir = @localstatedir@
68767
 
+lt_ECHO = @lt_ECHO@
68768
 
+mandir = @mandir@
68769
 
+mkdir_p = @mkdir_p@
68770
 
+moduledir = @moduledir@
68771
 
+oldincludedir = @oldincludedir@
68772
 
+pdfdir = @pdfdir@
68773
 
+prefix = @prefix@
68774
 
+program_transform_name = @program_transform_name@
68775
 
+psdir = @psdir@
68776
 
+sbindir = @sbindir@
68777
 
+sharedstatedir = @sharedstatedir@
68778
 
+srcdir = @srcdir@
68779
 
+sysconfdir = @sysconfdir@
68780
 
+target_alias = @target_alias@
68781
 
+top_build_prefix = @top_build_prefix@
68782
 
+top_builddir = @top_builddir@
68783
 
+top_srcdir = @top_srcdir@
68784
 
+noinst_LTLIBRARIES = libsieve_ext_subaddress.la
68785
 
+AM_CPPFLAGS = \
68786
 
+       -I../../ \
68787
 
+       -I$(dovecot_incdir) \
68788
 
+       -I$(dovecot_incdir)/src/lib \
68789
 
+       -I$(dovecot_incdir)/src/lib-mail \
68790
 
+       -I$(dovecot_incdir)/src/lib-storage 
68791
 
+
68792
 
+libsieve_ext_subaddress_la_SOURCES = \
68793
 
+       ext-subaddress.c
68794
 
+
68795
 
+all: all-am
68796
 
+
68797
 
+.SUFFIXES:
68798
 
+.SUFFIXES: .c .lo .o .obj
68799
 
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
68800
 
+       @for dep in $?; do \
68801
 
+         case '$(am__configure_deps)' in \
68802
 
+           *$$dep*) \
68803
 
+             ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
68804
 
+               && { if test -f $@; then exit 0; else break; fi; }; \
68805
 
+             exit 1;; \
68806
 
+         esac; \
68807
 
+       done; \
68808
 
+       echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign  src/lib-sieve/plugins/subaddress/Makefile'; \
68809
 
+       cd $(top_srcdir) && \
68810
 
+         $(AUTOMAKE) --foreign  src/lib-sieve/plugins/subaddress/Makefile
68811
 
+.PRECIOUS: Makefile
68812
 
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
68813
 
+       @case '$?' in \
68814
 
+         *config.status*) \
68815
 
+           cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
68816
 
+         *) \
68817
 
+           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
68818
 
+           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
68819
 
+       esac;
68820
 
+
68821
 
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
68822
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
68823
 
+
68824
 
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
68825
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
68826
 
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
68827
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
68828
 
+
68829
 
+clean-noinstLTLIBRARIES:
68830
 
+       -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
68831
 
+       @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
68832
 
+         dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
68833
 
+         test "$$dir" != "$$p" || dir=.; \
68834
 
+         echo "rm -f \"$${dir}/so_locations\""; \
68835
 
+         rm -f "$${dir}/so_locations"; \
68836
 
+       done
68837
 
+libsieve_ext_subaddress.la: $(libsieve_ext_subaddress_la_OBJECTS) $(libsieve_ext_subaddress_la_DEPENDENCIES) 
68838
 
+       $(LINK)  $(libsieve_ext_subaddress_la_OBJECTS) $(libsieve_ext_subaddress_la_LIBADD) $(LIBS)
68839
 
+
68840
 
+mostlyclean-compile:
68841
 
+       -rm -f *.$(OBJEXT)
68842
 
+
68843
 
+distclean-compile:
68844
 
+       -rm -f *.tab.c
68845
 
+
68846
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-subaddress.Plo@am__quote@
68847
 
+
68848
 
+.c.o:
68849
 
+@am__fastdepCC_TRUE@   $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
68850
 
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
68851
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
68852
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
68853
 
+@am__fastdepCC_FALSE@  $(COMPILE) -c $<
68854
 
+
68855
 
+.c.obj:
68856
 
+@am__fastdepCC_TRUE@   $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
68857
 
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
68858
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
68859
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
68860
 
+@am__fastdepCC_FALSE@  $(COMPILE) -c `$(CYGPATH_W) '$<'`
68861
 
+
68862
 
+.c.lo:
68863
 
+@am__fastdepCC_TRUE@   $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
68864
 
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
68865
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
68866
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
68867
 
+@am__fastdepCC_FALSE@  $(LTCOMPILE) -c -o $@ $<
68868
 
+
68869
 
+mostlyclean-libtool:
68870
 
+       -rm -f *.lo
68871
 
+
68872
 
+clean-libtool:
68873
 
+       -rm -rf .libs _libs
68874
 
+
68875
 
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
68876
 
+       list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
68877
 
+       unique=`for i in $$list; do \
68878
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
68879
 
+         done | \
68880
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
68881
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
68882
 
+       mkid -fID $$unique
68883
 
+tags: TAGS
68884
 
+
68885
 
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
68886
 
+               $(TAGS_FILES) $(LISP)
68887
 
+       tags=; \
68888
 
+       here=`pwd`; \
68889
 
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
68890
 
+       unique=`for i in $$list; do \
68891
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
68892
 
+         done | \
68893
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
68894
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
68895
 
+       if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
68896
 
+         test -n "$$unique" || unique=$$empty_fix; \
68897
 
+         $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
68898
 
+           $$tags $$unique; \
68899
 
+       fi
68900
 
+ctags: CTAGS
68901
 
+CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
68902
 
+               $(TAGS_FILES) $(LISP)
68903
 
+       tags=; \
68904
 
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
68905
 
+       unique=`for i in $$list; do \
68906
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
68907
 
+         done | \
68908
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
68909
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
68910
 
+       test -z "$(CTAGS_ARGS)$$tags$$unique" \
68911
 
+         || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
68912
 
+            $$tags $$unique
68913
 
+
68914
 
+GTAGS:
68915
 
+       here=`$(am__cd) $(top_builddir) && pwd` \
68916
 
+         && cd $(top_srcdir) \
68917
 
+         && gtags -i $(GTAGS_ARGS) $$here
68918
 
+
68919
 
+distclean-tags:
68920
 
+       -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
68921
 
+
68922
 
+distdir: $(DISTFILES)
68923
 
+       @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
68924
 
+       topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
68925
 
+       list='$(DISTFILES)'; \
68926
 
+         dist_files=`for file in $$list; do echo $$file; done | \
68927
 
+         sed -e "s|^$$srcdirstrip/||;t" \
68928
 
+             -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
68929
 
+       case $$dist_files in \
68930
 
+         */*) $(MKDIR_P) `echo "$$dist_files" | \
68931
 
+                          sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
68932
 
+                          sort -u` ;; \
68933
 
+       esac; \
68934
 
+       for file in $$dist_files; do \
68935
 
+         if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
68936
 
+         if test -d $$d/$$file; then \
68937
 
+           dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
68938
 
+           if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
68939
 
+             cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
68940
 
+           fi; \
68941
 
+           cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
68942
 
+         else \
68943
 
+           test -f $(distdir)/$$file \
68944
 
+           || cp -p $$d/$$file $(distdir)/$$file \
68945
 
+           || exit 1; \
68946
 
+         fi; \
68947
 
+       done
68948
 
+check-am: all-am
68949
 
+check: check-am
68950
 
+all-am: Makefile $(LTLIBRARIES)
68951
 
+installdirs:
68952
 
+install: install-am
68953
 
+install-exec: install-exec-am
68954
 
+install-data: install-data-am
68955
 
+uninstall: uninstall-am
68956
 
+
68957
 
+install-am: all-am
68958
 
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
68959
 
+
68960
 
+installcheck: installcheck-am
68961
 
+install-strip:
68962
 
+       $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
68963
 
+         install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
68964
 
+         `test -z '$(STRIP)' || \
68965
 
+           echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
68966
 
+mostlyclean-generic:
68967
 
+
68968
 
+clean-generic:
68969
 
+
68970
 
+distclean-generic:
68971
 
+       -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
68972
 
+
68973
 
+maintainer-clean-generic:
68974
 
+       @echo "This command is intended for maintainers to use"
68975
 
+       @echo "it deletes files that may require special tools to rebuild."
68976
 
+clean: clean-am
68977
 
+
68978
 
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
68979
 
+       mostlyclean-am
68980
 
+
68981
 
+distclean: distclean-am
68982
 
+       -rm -rf ./$(DEPDIR)
68983
 
+       -rm -f Makefile
68984
 
+distclean-am: clean-am distclean-compile distclean-generic \
68985
 
+       distclean-tags
68986
 
+
68987
 
+dvi: dvi-am
68988
 
+
68989
 
+dvi-am:
68990
 
+
68991
 
+html: html-am
68992
 
+
68993
 
+info: info-am
68994
 
+
68995
 
+info-am:
68996
 
+
68997
 
+install-data-am:
68998
 
+
68999
 
+install-dvi: install-dvi-am
69000
 
+
69001
 
+install-exec-am:
69002
 
+
69003
 
+install-html: install-html-am
69004
 
+
69005
 
+install-info: install-info-am
69006
 
+
69007
 
+install-man:
69008
 
+
69009
 
+install-pdf: install-pdf-am
69010
 
+
69011
 
+install-ps: install-ps-am
69012
 
+
69013
 
+installcheck-am:
69014
 
+
69015
 
+maintainer-clean: maintainer-clean-am
69016
 
+       -rm -rf ./$(DEPDIR)
69017
 
+       -rm -f Makefile
69018
 
+maintainer-clean-am: distclean-am maintainer-clean-generic
69019
 
+
69020
 
+mostlyclean: mostlyclean-am
69021
 
+
69022
 
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
69023
 
+       mostlyclean-libtool
69024
 
+
69025
 
+pdf: pdf-am
69026
 
+
69027
 
+pdf-am:
69028
 
+
69029
 
+ps: ps-am
69030
 
+
69031
 
+ps-am:
69032
 
+
69033
 
+uninstall-am:
69034
 
+
69035
 
+.MAKE: install-am install-strip
69036
 
+
69037
 
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
69038
 
+       clean-libtool clean-noinstLTLIBRARIES ctags distclean \
69039
 
+       distclean-compile distclean-generic distclean-libtool \
69040
 
+       distclean-tags distdir dvi dvi-am html html-am info info-am \
69041
 
+       install install-am install-data install-data-am install-dvi \
69042
 
+       install-dvi-am install-exec install-exec-am install-html \
69043
 
+       install-html-am install-info install-info-am install-man \
69044
 
+       install-pdf install-pdf-am install-ps install-ps-am \
69045
 
+       install-strip installcheck installcheck-am installdirs \
69046
 
+       maintainer-clean maintainer-clean-generic mostlyclean \
69047
 
+       mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
69048
 
+       pdf pdf-am ps ps-am tags uninstall uninstall-am
69049
 
+
69050
 
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
69051
 
+# Otherwise a system limit (for SysV at least) may be exceeded.
69052
 
+.NOEXPORT:
69053
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/vacation/cmd-vacation.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/vacation/cmd-vacation.c
69054
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/vacation/cmd-vacation.c        1970-01-01 01:00:00.000000000 +0100
69055
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/vacation/cmd-vacation.c 2009-07-21 03:09:40.000000000 +0200
69056
 
@@ -0,0 +1,1129 @@
69057
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
69058
 
+ */
69059
 
+
69060
 
+#include "lib.h"
69061
 
+#include "str.h"
69062
 
+#include "strfuncs.h"
69063
 
+#include "md5.h"
69064
 
+#include "hostpid.h"
69065
 
+#include "str-sanitize.h"
69066
 
+#include "message-address.h"
69067
 
+#include "message-date.h"
69068
 
+#include "ioloop.h"
69069
 
+
69070
 
+#include "rfc2822.h"
69071
 
+
69072
 
+#include "sieve-common.h"
69073
 
+#include "sieve-code.h"
69074
 
+#include "sieve-address.h"
69075
 
+#include "sieve-extensions.h"
69076
 
+#include "sieve-commands.h"
69077
 
+#include "sieve-actions.h"
69078
 
+#include "sieve-validator.h"
69079
 
+#include "sieve-generator.h"
69080
 
+#include "sieve-interpreter.h"
69081
 
+#include "sieve-dump.h"
69082
 
+#include "sieve-result.h"
69083
 
+#include "sieve-message.h"
69084
 
+
69085
 
+#include "ext-vacation-common.h"
69086
 
+
69087
 
+#include <stdio.h>
69088
 
+
69089
 
+/* 
69090
 
+ * Forward declarations 
69091
 
+ */
69092
 
69093
 
+static const struct sieve_argument vacation_days_tag;
69094
 
+static const struct sieve_argument vacation_subject_tag;
69095
 
+static const struct sieve_argument vacation_from_tag;
69096
 
+static const struct sieve_argument vacation_addresses_tag;
69097
 
+static const struct sieve_argument vacation_mime_tag;
69098
 
+static const struct sieve_argument vacation_handle_tag;
69099
 
+
69100
 
+/* 
69101
 
+ * Vacation command 
69102
 
+ *     
69103
 
+ * Syntax: 
69104
 
+ *    vacation [":days" number] [":subject" string]
69105
 
+ *                 [":from" string] [":addresses" string-list]
69106
 
+ *                 [":mime"] [":handle" string] <reason: string>
69107
 
+ */
69108
 
+
69109
 
+static bool cmd_vacation_registered
69110
 
+       (struct sieve_validator *validator, 
69111
 
+               struct sieve_command_registration *cmd_reg);
69112
 
+static bool cmd_vacation_pre_validate
69113
 
+       (struct sieve_validator *validator, struct sieve_command_context *cmd); 
69114
 
+static bool cmd_vacation_validate
69115
 
+       (struct sieve_validator *validator, struct sieve_command_context *cmd);
69116
 
+static bool cmd_vacation_generate
69117
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx);
69118
 
+
69119
 
+const struct sieve_command vacation_command = { 
69120
 
+       "vacation",
69121
 
+       SCT_COMMAND, 
69122
 
+       1, 0, FALSE, FALSE, 
69123
 
+       cmd_vacation_registered,
69124
 
+       cmd_vacation_pre_validate, 
69125
 
+       cmd_vacation_validate, 
69126
 
+       cmd_vacation_generate, 
69127
 
+       NULL 
69128
 
+};
69129
 
+
69130
 
+/*
69131
 
+ * Vacation command tags
69132
 
+ */
69133
 
+
69134
 
+/* Forward declarations */
69135
 
+
69136
 
+static bool cmd_vacation_validate_number_tag
69137
 
+       (struct sieve_validator *validator, struct sieve_ast_argument **arg, 
69138
 
+               struct sieve_command_context *cmd);
69139
 
+static bool cmd_vacation_validate_string_tag
69140
 
+       (struct sieve_validator *validator, struct sieve_ast_argument **arg, 
69141
 
+               struct sieve_command_context *cmd);
69142
 
+static bool cmd_vacation_validate_stringlist_tag
69143
 
+       (struct sieve_validator *validator, struct sieve_ast_argument **arg, 
69144
 
+               struct sieve_command_context *cmd);
69145
 
+static bool cmd_vacation_validate_mime_tag
69146
 
+       (struct sieve_validator *validator, struct sieve_ast_argument **arg, 
69147
 
+               struct sieve_command_context *cmd);
69148
 
+
69149
 
+/* Argument objects */
69150
 
+
69151
 
+static const struct sieve_argument vacation_days_tag = { 
69152
 
+       "days", 
69153
 
+       NULL, NULL,
69154
 
+       cmd_vacation_validate_number_tag, 
69155
 
+       NULL, NULL 
69156
 
+};
69157
 
+
69158
 
+static const struct sieve_argument vacation_subject_tag = { 
69159
 
+       "subject", 
69160
 
+       NULL, NULL,
69161
 
+       cmd_vacation_validate_string_tag, 
69162
 
+       NULL, NULL 
69163
 
+};
69164
 
+
69165
 
+static const struct sieve_argument vacation_from_tag = { 
69166
 
+       "from", 
69167
 
+       NULL, NULL,
69168
 
+       cmd_vacation_validate_string_tag, 
69169
 
+       NULL, NULL 
69170
 
+};
69171
 
+
69172
 
+static const struct sieve_argument vacation_addresses_tag = { 
69173
 
+       "addresses", 
69174
 
+       NULL, NULL,
69175
 
+       cmd_vacation_validate_stringlist_tag, 
69176
 
+       NULL, NULL 
69177
 
+};
69178
 
+
69179
 
+static const struct sieve_argument vacation_mime_tag = { 
69180
 
+       "mime", 
69181
 
+       NULL, NULL, 
69182
 
+       cmd_vacation_validate_mime_tag,
69183
 
+       NULL, NULL
69184
 
+};
69185
 
+
69186
 
+static const struct sieve_argument vacation_handle_tag = { 
69187
 
+       "handle", 
69188
 
+       NULL, NULL, 
69189
 
+       cmd_vacation_validate_string_tag, 
69190
 
+       NULL, NULL 
69191
 
+};
69192
 
+
69193
 
+/* Codes for optional arguments */
69194
 
+
69195
 
+enum cmd_vacation_optional {
69196
 
+       OPT_END,
69197
 
+       OPT_DAYS,
69198
 
+       OPT_SUBJECT,
69199
 
+       OPT_FROM,
69200
 
+       OPT_ADDRESSES,
69201
 
+       OPT_MIME
69202
 
+};
69203
 
+
69204
 
+/* 
69205
 
+ * Vacation operation 
69206
 
+ */
69207
 
+
69208
 
+static bool ext_vacation_operation_dump
69209
 
+       (const struct sieve_operation *op,      
69210
 
+               const struct sieve_dumptime_env *denv, sieve_size_t *address);
69211
 
+static int ext_vacation_operation_execute
69212
 
+       (const struct sieve_operation *op, 
69213
 
+               const struct sieve_runtime_env *renv, sieve_size_t *address);
69214
 
+
69215
 
+const struct sieve_operation vacation_operation = { 
69216
 
+       "VACATION",
69217
 
+       &vacation_extension,
69218
 
+       0,
69219
 
+       ext_vacation_operation_dump, 
69220
 
+       ext_vacation_operation_execute
69221
 
+};
69222
 
+
69223
 
+/* 
69224
 
+ * Vacation action 
69225
 
+ */
69226
 
+
69227
 
+/* Forward declarations */
69228
 
+
69229
 
+static int act_vacation_check_duplicate
69230
 
+       (const struct sieve_runtime_env *renv, 
69231
 
+               const struct sieve_action_data *act, 
69232
 
+               const struct sieve_action_data *act_other);
69233
 
+int act_vacation_check_conflict
69234
 
+       (const struct sieve_runtime_env *renv, 
69235
 
+               const struct sieve_action_data *act, 
69236
 
+               const struct sieve_action_data *act_other);
69237
 
+static void act_vacation_print
69238
 
+       (const struct sieve_action *action, 
69239
 
+               const struct sieve_result_print_env *rpenv, void *context, bool *keep); 
69240
 
+static bool act_vacation_commit
69241
 
+       (const struct sieve_action *action,     const struct sieve_action_exec_env *aenv, 
69242
 
+               void *tr_context, bool *keep);
69243
 
+
69244
 
+/* Action object */
69245
 
+
69246
 
+const struct sieve_action act_vacation = {
69247
 
+       "vacation",
69248
 
+       SIEVE_ACTFLAG_SENDS_RESPONSE,
69249
 
+       NULL,
69250
 
+       act_vacation_check_duplicate, 
69251
 
+       act_vacation_check_conflict,
69252
 
+       act_vacation_print,
69253
 
+       NULL, NULL,
69254
 
+       act_vacation_commit,
69255
 
+       NULL
69256
 
+};
69257
 
+
69258
 
+/* Action context information */
69259
 
+               
69260
 
+struct act_vacation_context {
69261
 
+       const char *reason;
69262
 
+
69263
 
+       sieve_number_t days;
69264
 
+       const char *subject;
69265
 
+       const char *handle;
69266
 
+       bool mime;
69267
 
+       const char *from;
69268
 
+       const char *from_normalized;    
69269
 
+       const char *const *addresses;
69270
 
+};
69271
 
+
69272
 
+/*
69273
 
+ * Command validation context
69274
 
+ */
69275
 
69276
 
+struct cmd_vacation_context_data {
69277
 
+       string_t *from;
69278
 
+       string_t *subject;
69279
 
+       
69280
 
+       bool mime;
69281
 
+       
69282
 
+       string_t *handle;
69283
 
+};
69284
 
+
69285
 
+/* 
69286
 
+ * Tag validation 
69287
 
+ */
69288
 
+
69289
 
+static bool cmd_vacation_validate_number_tag
69290
 
+(struct sieve_validator *validator, struct sieve_ast_argument **arg, 
69291
 
+       struct sieve_command_context *cmd)
69292
 
+{
69293
 
+       struct sieve_ast_argument *tag = *arg;
69294
 
+       
69295
 
+       /* Detach the tag itself */
69296
 
+       *arg = sieve_ast_arguments_detach(*arg,1);
69297
 
+       
69298
 
+       /* Check syntax:
69299
 
+        *   :days number
69300
 
+        */
69301
 
+       if ( !sieve_validate_tag_parameter
69302
 
+               (validator, cmd, tag, *arg, SAAT_NUMBER) ) {
69303
 
+               return FALSE;
69304
 
+       }
69305
 
+
69306
 
+       /* Enforce :days > 0 */
69307
 
+       if ( sieve_ast_argument_number(*arg) == 0 ) {
69308
 
+               sieve_ast_argument_number_set(*arg, 1);
69309
 
+       }
69310
 
+
69311
 
+       /* Skip parameter */
69312
 
+       *arg = sieve_ast_argument_next(*arg);
69313
 
+       
69314
 
+       return TRUE;
69315
 
+}
69316
 
+
69317
 
+static bool cmd_vacation_validate_string_tag
69318
 
+(struct sieve_validator *validator, struct sieve_ast_argument **arg, 
69319
 
+       struct sieve_command_context *cmd)
69320
 
+{
69321
 
+       struct sieve_ast_argument *tag = *arg;
69322
 
+       struct cmd_vacation_context_data *ctx_data = 
69323
 
+               (struct cmd_vacation_context_data *) cmd->data; 
69324
 
+
69325
 
+       /* Detach the tag itself */
69326
 
+       *arg = sieve_ast_arguments_detach(*arg,1);
69327
 
+       
69328
 
+       /* Check syntax:
69329
 
+        *   :subject string
69330
 
+        *   :from string
69331
 
+        *   :handle string
69332
 
+        */
69333
 
+       if ( !sieve_validate_tag_parameter
69334
 
+               (validator, cmd, tag, *arg, SAAT_STRING) ) {
69335
 
+               return FALSE;
69336
 
+       }
69337
 
+
69338
 
+       if ( tag->argument == &vacation_from_tag ) {
69339
 
+               if ( sieve_argument_is_string_literal(*arg) ) {
69340
 
+                       string_t *address = sieve_ast_argument_str(*arg);
69341
 
+                       const char *error;
69342
 
+                       bool result;
69343
 
+                       
69344
 
+                       T_BEGIN {
69345
 
+                               result = sieve_address_validate(address, &error);
69346
 
+        
69347
 
+                               if ( !result ) {
69348
 
+                                       sieve_argument_validate_error(validator, *arg, 
69349
 
+                                               "specified :from address '%s' is invalid for vacation action: %s", 
69350
 
+                                               str_sanitize(str_c(address), 128), error);
69351
 
+                               }
69352
 
+                       } T_END;
69353
 
+               
69354
 
+                       if ( !result )
69355
 
+                               return FALSE;
69356
 
+               }
69357
 
+               
69358
 
+               ctx_data->from = sieve_ast_argument_str(*arg);
69359
 
+               
69360
 
+               /* Skip parameter */
69361
 
+               *arg = sieve_ast_argument_next(*arg);
69362
 
+               
69363
 
+       } else if ( tag->argument == &vacation_subject_tag ) {
69364
 
+               ctx_data->subject = sieve_ast_argument_str(*arg);
69365
 
+               
69366
 
+               /* Skip parameter */
69367
 
+               *arg = sieve_ast_argument_next(*arg);
69368
 
+               
69369
 
+       } else if ( tag->argument == &vacation_handle_tag ) {
69370
 
+               ctx_data->handle = sieve_ast_argument_str(*arg);
69371
 
+               
69372
 
+               /* Detach optional argument (emitted as mandatory) */
69373
 
+               *arg = sieve_ast_arguments_detach(*arg,1);
69374
 
+       }
69375
 
+                       
69376
 
+       return TRUE;
69377
 
+}
69378
 
+
69379
 
+static bool cmd_vacation_validate_stringlist_tag
69380
 
+(struct sieve_validator *validator, struct sieve_ast_argument **arg, 
69381
 
+       struct sieve_command_context *cmd)
69382
 
+{
69383
 
+       struct sieve_ast_argument *tag = *arg;
69384
 
+
69385
 
+       /* Detach the tag itself */
69386
 
+       *arg = sieve_ast_arguments_detach(*arg,1);
69387
 
+       
69388
 
+       /* Check syntax:
69389
 
+        *   :addresses string-list
69390
 
+        */
69391
 
+       if ( !sieve_validate_tag_parameter
69392
 
+               (validator, cmd, tag, *arg, SAAT_STRING_LIST) ) {
69393
 
+               return FALSE;
69394
 
+       }
69395
 
+       
69396
 
+       /* Skip parameter */
69397
 
+       *arg = sieve_ast_argument_next(*arg);
69398
 
+
69399
 
+       return TRUE;
69400
 
+}
69401
 
+
69402
 
+static bool cmd_vacation_validate_mime_tag
69403
 
+(struct sieve_validator *validator ATTR_UNUSED, struct sieve_ast_argument **arg, 
69404
 
+       struct sieve_command_context *cmd)
69405
 
+{
69406
 
+       struct cmd_vacation_context_data *ctx_data = 
69407
 
+               (struct cmd_vacation_context_data *) cmd->data; 
69408
 
+
69409
 
+       ctx_data->mime = TRUE;
69410
 
+
69411
 
+       /* Skip tag */
69412
 
+       *arg = sieve_ast_argument_next(*arg);
69413
 
+       
69414
 
+       return TRUE;
69415
 
+}
69416
 
+
69417
 
+/* 
69418
 
+ * Command registration 
69419
 
+ */
69420
 
+
69421
 
+static bool cmd_vacation_registered
69422
 
+(struct sieve_validator *validator, struct sieve_command_registration *cmd_reg) 
69423
 
+{
69424
 
+       sieve_validator_register_tag
69425
 
+               (validator, cmd_reg, &vacation_days_tag, OPT_DAYS);     
69426
 
+       sieve_validator_register_tag
69427
 
+               (validator, cmd_reg, &vacation_subject_tag, OPT_SUBJECT);       
69428
 
+       sieve_validator_register_tag
69429
 
+               (validator, cmd_reg, &vacation_from_tag, OPT_FROM);     
69430
 
+       sieve_validator_register_tag
69431
 
+               (validator, cmd_reg, &vacation_addresses_tag, OPT_ADDRESSES);   
69432
 
+       sieve_validator_register_tag
69433
 
+               (validator, cmd_reg, &vacation_mime_tag, OPT_MIME);     
69434
 
+       sieve_validator_register_tag
69435
 
+               (validator, cmd_reg, &vacation_handle_tag, 0);  
69436
 
+
69437
 
+       return TRUE;
69438
 
+}
69439
 
+
69440
 
+/* 
69441
 
+ * Command validation 
69442
 
+ */
69443
 
69444
 
+static bool cmd_vacation_pre_validate
69445
 
+(struct sieve_validator *validator ATTR_UNUSED, 
69446
 
+       struct sieve_command_context *cmd) 
69447
 
+{
69448
 
+       struct cmd_vacation_context_data *ctx_data;
69449
 
+       
69450
 
+       /* Assign context */
69451
 
+       ctx_data = p_new(sieve_command_pool(cmd), 
69452
 
+               struct cmd_vacation_context_data, 1);
69453
 
+       cmd->data = ctx_data;
69454
 
+
69455
 
+       return TRUE;
69456
 
+}
69457
 
+
69458
 
+static const char _handle_empty_subject[] = "<default-subject>";
69459
 
+static const char _handle_empty_from[] = "<default-from>";
69460
 
+static const char _handle_mime_enabled[] = "<MIME>";
69461
 
+static const char _handle_mime_disabled[] = "<NO-MIME>";
69462
 
+
69463
 
+static bool cmd_vacation_validate
69464
 
+(struct sieve_validator *validator, struct sieve_command_context *cmd) 
69465
 
+{      
69466
 
+       struct sieve_ast_argument *arg = cmd->first_positional;
69467
 
+       struct cmd_vacation_context_data *ctx_data = 
69468
 
+               (struct cmd_vacation_context_data *) cmd->data; 
69469
 
+
69470
 
+       if ( !sieve_validate_positional_argument
69471
 
+               (validator, cmd, arg, "reason", 1, SAAT_STRING) ) {
69472
 
+               return FALSE;
69473
 
+       }
69474
 
+       
69475
 
+       if ( !sieve_validator_argument_activate(validator, cmd, arg, FALSE) )
69476
 
+               return FALSE;
69477
 
+               
69478
 
+       /* Construct handle if not set explicitly */
69479
 
+       if ( ctx_data->handle == NULL ) {
69480
 
+               string_t *reason = sieve_ast_argument_str(arg);
69481
 
+               unsigned int size = str_len(reason);
69482
 
+               
69483
 
+               /* Precalculate the size of it all */
69484
 
+               size += ctx_data->subject == NULL ? 
69485
 
+                       sizeof(_handle_empty_subject) - 1 : str_len(ctx_data->subject);
69486
 
+               size += ctx_data->from == NULL ? 
69487
 
+                       sizeof(_handle_empty_from) - 1 : str_len(ctx_data->from); 
69488
 
+               size += ctx_data->mime ? 
69489
 
+                       sizeof(_handle_mime_enabled) - 1 : sizeof(_handle_mime_disabled) - 1; 
69490
 
+                       
69491
 
+               /* Construct the string */
69492
 
+               ctx_data->handle = str_new(sieve_command_pool(cmd), size);
69493
 
+               str_append_str(ctx_data->handle, reason);
69494
 
+               
69495
 
+               if ( ctx_data->subject != NULL )
69496
 
+                       str_append_str(ctx_data->handle, ctx_data->subject);
69497
 
+               else
69498
 
+                       str_append(ctx_data->handle, _handle_empty_subject);
69499
 
+               
69500
 
+               if ( ctx_data->from != NULL )
69501
 
+                       str_append_str(ctx_data->handle, ctx_data->from);
69502
 
+               else
69503
 
+                       str_append(ctx_data->handle, _handle_empty_from);
69504
 
+                       
69505
 
+               str_append(ctx_data->handle, 
69506
 
+                       ctx_data->mime ? _handle_mime_enabled : _handle_mime_disabled );
69507
 
+       }
69508
 
+       
69509
 
+       return TRUE;
69510
 
+}
69511
 
+
69512
 
+/*
69513
 
+ * Code generation
69514
 
+ */
69515
 
69516
 
+static bool cmd_vacation_generate
69517
 
+(const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx) 
69518
 
+{
69519
 
+       struct cmd_vacation_context_data *ctx_data = 
69520
 
+               (struct cmd_vacation_context_data *) ctx->data;
69521
 
+                
69522
 
+       sieve_operation_emit_code(cgenv->sbin, &vacation_operation);
69523
 
+
69524
 
+       /* Emit source line */
69525
 
+       sieve_code_source_line_emit(cgenv->sbin, sieve_command_source_line(ctx));
69526
 
+
69527
 
+       /* Generate arguments */
69528
 
+       if ( !sieve_generate_arguments(cgenv, ctx, NULL) )
69529
 
+               return FALSE;   
69530
 
+
69531
 
+       /* FIXME: this will not allow the handle to be a variable */
69532
 
+       sieve_opr_string_emit(cgenv->sbin, ctx_data->handle);
69533
 
+               
69534
 
+       return TRUE;
69535
 
+}
69536
 
+
69537
 
+/* 
69538
 
+ * Code dump
69539
 
+ */
69540
 
69541
 
+static bool ext_vacation_operation_dump
69542
 
+(const struct sieve_operation *op ATTR_UNUSED,
69543
 
+       const struct sieve_dumptime_env *denv, sieve_size_t *address)
69544
 
+{      
69545
 
+       int opt_code = 1;
69546
 
+       
69547
 
+       sieve_code_dumpf(denv, "VACATION");
69548
 
+       sieve_code_descend(denv);       
69549
 
+
69550
 
+       /* Source line */
69551
 
+       if ( !sieve_code_source_line_dump(denv, address) )
69552
 
+               return FALSE;
69553
 
+
69554
 
+       /* Dump optional operands */
69555
 
+       if ( sieve_operand_optional_present(denv->sbin, address) ) {
69556
 
+               while ( opt_code != 0 ) {
69557
 
+                       sieve_code_mark(denv);
69558
 
+                       
69559
 
+                       if ( !sieve_operand_optional_read(denv->sbin, address, &opt_code) ) 
69560
 
+                               return FALSE;
69561
 
+
69562
 
+                       switch ( opt_code ) {
69563
 
+                       case 0:
69564
 
+                               break;
69565
 
+                       case OPT_DAYS:
69566
 
+                               if ( !sieve_opr_number_dump(denv, address, "days") )
69567
 
+                                       return FALSE;
69568
 
+                               break;
69569
 
+                       case OPT_SUBJECT:
69570
 
+                               if ( !sieve_opr_string_dump(denv, address, "subject") )
69571
 
+                                       return FALSE;
69572
 
+                               break;
69573
 
+                       case OPT_FROM:
69574
 
+                               if ( !sieve_opr_string_dump(denv, address, "from") )
69575
 
+                                       return FALSE;
69576
 
+                               break;
69577
 
+                       case OPT_ADDRESSES:
69578
 
+                               if ( !sieve_opr_stringlist_dump(denv, address, "addresses") )
69579
 
+                                       return FALSE;
69580
 
+                               break;
69581
 
+                       case OPT_MIME:
69582
 
+                               sieve_code_dumpf(denv, "mime"); 
69583
 
+                               break;
69584
 
+                       
69585
 
+                       default:
69586
 
+                               return FALSE;
69587
 
+                       }
69588
 
+               }
69589
 
+       }
69590
 
+       
69591
 
+       /* Dump reason and handle operands */
69592
 
+       return 
69593
 
+               sieve_opr_string_dump(denv, address, "reason") &&
69594
 
+               sieve_opr_string_dump(denv, address, "handle");
69595
 
+}
69596
 
+
69597
 
+/* 
69598
 
+ * Code execution
69599
 
+ */
69600
 
69601
 
+static int ext_vacation_operation_execute
69602
 
+(const struct sieve_operation *op ATTR_UNUSED,
69603
 
+       const struct sieve_runtime_env *renv, sieve_size_t *address)
69604
 
+{      
69605
 
+       struct sieve_side_effects_list *slist = NULL;
69606
 
+       struct act_vacation_context *act;
69607
 
+       pool_t pool;
69608
 
+       int opt_code = 1;
69609
 
+       sieve_number_t days = 7;
69610
 
+       bool mime = FALSE;
69611
 
+       struct sieve_coded_stringlist *addresses = NULL;
69612
 
+       string_t *reason, *subject = NULL, *from = NULL, *handle = NULL; 
69613
 
+       unsigned int source_line;
69614
 
+       const char *from_normalized = NULL;
69615
 
+
69616
 
+       /*
69617
 
+        * Read operands
69618
 
+        */
69619
 
+               
69620
 
+       /* Source line */
69621
 
+       if ( !sieve_code_source_line_read(renv, address, &source_line) ) {
69622
 
+               sieve_runtime_trace_error(renv, "invalid source line");
69623
 
+               return SIEVE_EXEC_BIN_CORRUPT;
69624
 
+       }
69625
 
+       
69626
 
+       /* Optional operands */ 
69627
 
+       if ( sieve_operand_optional_present(renv->sbin, address) ) {
69628
 
+               while ( opt_code != 0 ) {
69629
 
+                       if ( !sieve_operand_optional_read(renv->sbin, address, &opt_code) ) {
69630
 
+                               sieve_runtime_trace_error(renv, "invalid optional operand");
69631
 
+                               return SIEVE_EXEC_BIN_CORRUPT;
69632
 
+                       }
69633
 
+
69634
 
+                       switch ( opt_code ) {
69635
 
+                       case 0:
69636
 
+                               break;
69637
 
+                       case OPT_DAYS:
69638
 
+                               if ( !sieve_opr_number_read(renv, address, &days) ) {
69639
 
+                                       sieve_runtime_trace_error(renv, 
69640
 
+                                               "invalid days operand");
69641
 
+                                       return SIEVE_EXEC_BIN_CORRUPT;
69642
 
+                               }
69643
 
+       
69644
 
+                               /* Enforce days > 0 (just to be sure) */
69645
 
+                               if ( days == 0 )
69646
 
+                                       days = 1;
69647
 
+                               break;
69648
 
+                       case OPT_SUBJECT:
69649
 
+                               if ( !sieve_opr_string_read(renv, address, &subject) ) {
69650
 
+                                       sieve_runtime_trace_error(renv, 
69651
 
+                                               "invalid subject operand");
69652
 
+                                       return SIEVE_EXEC_BIN_CORRUPT;
69653
 
+                               }
69654
 
+                               break;
69655
 
+                       case OPT_FROM:
69656
 
+                               if ( !sieve_opr_string_read(renv, address, &from) ) {
69657
 
+                                       sieve_runtime_trace_error(renv, 
69658
 
+                                               "invalid from address operand");
69659
 
+                                       return SIEVE_EXEC_BIN_CORRUPT;
69660
 
+                               }
69661
 
+                               break;
69662
 
+                       case OPT_ADDRESSES:
69663
 
+                               if ( (addresses=sieve_opr_stringlist_read(renv, address))
69664
 
+                                       == NULL ) {
69665
 
+                                       sieve_runtime_trace_error(renv, 
69666
 
+                                               "invalid addresses operand");
69667
 
+                                       return SIEVE_EXEC_BIN_CORRUPT;
69668
 
+                               }
69669
 
+                               break;
69670
 
+                       case OPT_MIME:
69671
 
+                               mime = TRUE;
69672
 
+                               break;
69673
 
+                       default:
69674
 
+                               sieve_runtime_trace_error(renv, 
69675
 
+                                       "unknown optional operand");
69676
 
+                               return SIEVE_EXEC_BIN_CORRUPT;
69677
 
+                       }
69678
 
+               }
69679
 
+       }
69680
 
+       
69681
 
+       /* Reason operand */
69682
 
+       if ( !sieve_opr_string_read(renv, address, &reason) ) {
69683
 
+               sieve_runtime_trace_error(renv, "invalid reason operand");
69684
 
+               return SIEVE_EXEC_BIN_CORRUPT;
69685
 
+       }
69686
 
+       
69687
 
+       /* Handle operand */
69688
 
+       if ( !sieve_opr_string_read(renv, address, &handle) ) {
69689
 
+               sieve_runtime_trace_error(renv, "invalid handle operand");
69690
 
+               return SIEVE_EXEC_BIN_CORRUPT;
69691
 
+       }
69692
 
+       
69693
 
+       /*
69694
 
+        * Perform operation
69695
 
+        */
69696
 
+
69697
 
+       sieve_runtime_trace(renv, "VACATION action");   
69698
 
+
69699
 
+       /* Check and normalize :from address */
69700
 
+       if ( from != NULL ) {
69701
 
+               const char *error;
69702
 
+
69703
 
+               from_normalized = sieve_address_normalize(from, &error);
69704
 
+       
69705
 
+               if ( from_normalized == NULL) {
69706
 
+                       sieve_runtime_error(renv, 
69707
 
+                               sieve_error_script_location(renv->script, source_line),
69708
 
+                               "specified :from address '%s' is invalid for vacation action: %s",
69709
 
+                               str_sanitize(str_c(from), 128), error);
69710
 
+               }
69711
 
+       }
69712
 
+
69713
 
+       /* Add vacation action to the result */
69714
 
+
69715
 
+       pool = sieve_result_pool(renv->result);
69716
 
+       act = p_new(pool, struct act_vacation_context, 1);
69717
 
+       act->reason = p_strdup(pool, str_c(reason));
69718
 
+       act->handle = p_strdup(pool, str_c(handle));
69719
 
+       act->days = days;
69720
 
+       act->mime = mime;
69721
 
+       if ( subject != NULL )
69722
 
+               act->subject = p_strdup(pool, str_c(subject));
69723
 
+       if ( from != NULL ) {
69724
 
+               act->from = p_strdup(pool, str_c(from));
69725
 
+               act->from_normalized = p_strdup(pool, from_normalized);
69726
 
+       }
69727
 
+
69728
 
+       /* Normalize all addresses */
69729
 
+       if ( addresses != NULL ) {
69730
 
+               ARRAY_DEFINE(norm_addresses, const char *);
69731
 
+               string_t *raw_address;
69732
 
+               bool result = FALSE;
69733
 
+               
69734
 
+               sieve_coded_stringlist_reset(addresses);
69735
 
+                       
69736
 
+               p_array_init(&norm_addresses, pool, 4);
69737
 
+               
69738
 
+               raw_address = NULL;
69739
 
+               while ( (result=sieve_coded_stringlist_next_item(addresses, &raw_address))
69740
 
+                       && raw_address != NULL ) {
69741
 
+                       const char *error;
69742
 
+                       const char *addr_norm = sieve_address_normalize(raw_address, &error);
69743
 
+                       
69744
 
+                       if ( addr_norm != NULL ) {
69745
 
+                               addr_norm = p_strdup(pool, addr_norm);
69746
 
+               
69747
 
+                               array_append(&norm_addresses, &addr_norm, 1);                   
69748
 
+                       } else {
69749
 
+                               /* FIXME: report proper warning */
69750
 
+                       }
69751
 
+               }
69752
 
+               
69753
 
+               if ( !result ) {
69754
 
+                       sieve_runtime_trace_error(renv, "invalid addresses stringlist");
69755
 
+                       return SIEVE_EXEC_BIN_CORRUPT;
69756
 
+               }
69757
 
+               
69758
 
+               (void)array_append_space(&norm_addresses);
69759
 
+               act->addresses = array_idx(&norm_addresses, 0);
69760
 
+       }       
69761
 
+               
69762
 
+       return ( sieve_result_add_action
69763
 
+               (renv, &act_vacation, slist, source_line, (void *) act, 0) >= 0 );
69764
 
+}
69765
 
+
69766
 
+/*
69767
 
+ * Action
69768
 
+ */
69769
 
+
69770
 
+/* Runtime verification */
69771
 
+
69772
 
+static int act_vacation_check_duplicate
69773
 
+(const struct sieve_runtime_env *renv ATTR_UNUSED,
69774
 
+       const struct sieve_action_data *act, 
69775
 
+       const struct sieve_action_data *act_other)
69776
 
+{
69777
 
+       if ( !act_other->executed ) {
69778
 
+               sieve_runtime_error(renv, act->location, 
69779
 
+                       "duplicate vacation action not allowed "
69780
 
+                       "(previously triggered one was here: %s)", act_other->location);
69781
 
+               return -1;
69782
 
+       }
69783
 
+
69784
 
+       /* Not an error if executed in preceeding script */
69785
 
+       return 1;
69786
 
+}
69787
 
+
69788
 
+int act_vacation_check_conflict
69789
 
+(const struct sieve_runtime_env *renv,
69790
 
+       const struct sieve_action_data *act, 
69791
 
+       const struct sieve_action_data *act_other)
69792
 
+{
69793
 
+       if ( (act_other->action->flags & SIEVE_ACTFLAG_SENDS_RESPONSE) > 0 ) {
69794
 
+               if ( !act_other->executed && !act->executed) {
69795
 
+                       sieve_runtime_error(renv, act->location, 
69796
 
+                               "vacation action conflicts with other action: "
69797
 
+                               "the %s action (%s) also sends a response back to the sender",  
69798
 
+                               act_other->action->name, act_other->location);
69799
 
+                       return -1;
69800
 
+               } else {
69801
 
+                       /* Not an error if executed in preceeding script */
69802
 
+                       return 1;
69803
 
+               }
69804
 
+       }
69805
 
+
69806
 
+       return 0;
69807
 
+}
69808
 
+
69809
 
+/* Result printing */
69810
 
69811
 
+static void act_vacation_print
69812
 
+(const struct sieve_action *action ATTR_UNUSED, 
69813
 
+       const struct sieve_result_print_env *rpenv, void *context, 
69814
 
+       bool *keep ATTR_UNUSED) 
69815
 
+{
69816
 
+       struct act_vacation_context *ctx = (struct act_vacation_context *) context;
69817
 
+       
69818
 
+       sieve_result_action_printf( rpenv, "send vacation message:");
69819
 
+       sieve_result_printf(rpenv, "    => days   : %d\n", ctx->days);
69820
 
+       if ( ctx->subject != NULL )
69821
 
+               sieve_result_printf(rpenv, "    => subject: %s\n", ctx->subject);
69822
 
+       if ( ctx->from != NULL )
69823
 
+               sieve_result_printf(rpenv, "    => from   : %s\n", ctx->from);
69824
 
+       if ( ctx->handle != NULL )
69825
 
+               sieve_result_printf(rpenv, "    => handle : %s\n", ctx->handle);
69826
 
+       sieve_result_printf(rpenv, "\nSTART MESSAGE\n%s\nEND MESSAGE\n", ctx->reason);
69827
 
+}
69828
 
+
69829
 
+/* Result execution */
69830
 
+
69831
 
+/* Headers known to be associated with mailing lists 
69832
 
+ */
69833
 
+static const char * const _list_headers[] = {
69834
 
+       "list-id",
69835
 
+       "list-owner",
69836
 
+       "list-subscribe",
69837
 
+       "list-post",    
69838
 
+       "list-unsubscribe",
69839
 
+       "list-help",
69840
 
+       "list-archive",
69841
 
+       NULL
69842
 
+};
69843
 
+
69844
 
+/* Headers that should be searched for the user's own mail address(es) 
69845
 
+ */
69846
 
+
69847
 
+static const char * const _my_address_headers[] = {
69848
 
+       "to",
69849
 
+       "cc",
69850
 
+       "bcc",
69851
 
+       "resent-to",    
69852
 
+       "resent-cc",
69853
 
+       "resent-bcc",
69854
 
+       NULL
69855
 
+};
69856
 
+
69857
 
+static inline bool _is_system_address(const char *address)
69858
 
+{
69859
 
+       if ( strncasecmp(address, "MAILER-DAEMON", 13) == 0 )
69860
 
+               return TRUE;
69861
 
+
69862
 
+       if ( strncasecmp(address, "LISTSERV", 8) == 0 )
69863
 
+               return TRUE;
69864
 
+
69865
 
+       if ( strncasecmp(address, "majordomo", 9) == 0 )
69866
 
+               return TRUE;
69867
 
+
69868
 
+       if ( strstr(address, "-request@") != NULL )
69869
 
+               return TRUE;
69870
 
+
69871
 
+       if ( strncmp(address, "owner-", 6) == 0 )
69872
 
+               return TRUE;
69873
 
+
69874
 
+       return FALSE;
69875
 
+}
69876
 
+
69877
 
+static inline bool _contains_my_address
69878
 
+       (const char * const *headers, const char *my_address)
69879
 
+{
69880
 
+       const char *const *hdsp = headers;
69881
 
+       bool result = FALSE;
69882
 
+       
69883
 
+       while ( *hdsp != NULL && !result ) {
69884
 
+               const struct message_address *addr;
69885
 
+
69886
 
+               T_BEGIN {
69887
 
+       
69888
 
+                       addr = message_address_parse
69889
 
+                               (pool_datastack_create(), (const unsigned char *) *hdsp, 
69890
 
+                                       strlen(*hdsp), 256, FALSE);
69891
 
+
69892
 
+                       while ( addr != NULL && !result ) {
69893
 
+                               if (addr->domain != NULL) {
69894
 
+                                       const char *hdr_address; 
69895
 
+                                       
69896
 
+                                       i_assert(addr->mailbox != NULL);
69897
 
+
69898
 
+                                       hdr_address = t_strconcat(addr->mailbox, "@", addr->domain, NULL);
69899
 
+                                       if ( sieve_address_compare(hdr_address, my_address, TRUE) == 0 ) {
69900
 
+                                               result = TRUE;
69901
 
+                                               break;
69902
 
+                                       }
69903
 
+                               }
69904
 
+
69905
 
+                               addr = addr->next;
69906
 
+                       }
69907
 
+               } T_END;
69908
 
+               
69909
 
+               hdsp++;
69910
 
+       }
69911
 
+       
69912
 
+       return result;
69913
 
+}
69914
 
+
69915
 
+static bool act_vacation_send  
69916
 
+(const struct sieve_action_exec_env *aenv, struct act_vacation_context *ctx,
69917
 
+       const char *sender, const char *recipient)
69918
 
+{
69919
 
+       const struct sieve_message_data *msgdata = aenv->msgdata;
69920
 
+       const struct sieve_script_env *senv = aenv->scriptenv;
69921
 
+       void *smtp_handle;
69922
 
+       FILE *f;
69923
 
+       const char *outmsgid;
69924
 
+       const char *const *headers;
69925
 
+       int ret;
69926
 
+
69927
 
+       /* Check smpt functions just to be sure */
69928
 
+
69929
 
+       if ( senv->smtp_open == NULL || senv->smtp_close == NULL ) {
69930
 
+               sieve_result_warning(aenv, "vacation action has no means to send mail");
69931
 
+               return TRUE;
69932
 
+       }
69933
 
+
69934
 
+       /* Open smtp session */
69935
 
+
69936
 
+       smtp_handle = senv->smtp_open(sender, NULL, &f);
69937
 
+       outmsgid = sieve_message_get_new_id(senv);
69938
 
+
69939
 
+       /* Produce a proper reply */
69940
 
+
69941
 
+       rfc2822_header_field_write(f, "X-Sieve", SIEVE_IMPLEMENTATION);    
69942
 
+       rfc2822_header_field_write(f, "Message-ID", outmsgid);
69943
 
+       rfc2822_header_field_write(f, "Date", message_date_create(ioloop_time));
69944
 
+
69945
 
+       if ( ctx->from != NULL && *(ctx->from) != '\0' )
69946
 
+               rfc2822_header_field_printf(f, "From", "%s", ctx->from);
69947
 
+       else if ( recipient != NULL ) 
69948
 
+               rfc2822_header_field_printf(f, "From", "<%s>", recipient);
69949
 
+       else
69950
 
+               rfc2822_header_field_printf(f, "From", "Postmaster <%s>", senv->postmaster_address);
69951
 
+               
69952
 
+       /* FIXME: If From header of message has same address, we should use that in 
69953
 
+        * stead properly include the phrase part.
69954
 
+        */
69955
 
+       rfc2822_header_field_printf(f, "To", "<%s>", sender);
69956
 
+
69957
 
+       rfc2822_header_field_printf(f, "Subject", "%s", 
69958
 
+               str_sanitize(ctx->subject, 256));
69959
 
+
69960
 
+       /* Compose proper in-reply-to and references headers */
69961
 
+       
69962
 
+       ret = mail_get_headers
69963
 
+               (aenv->msgdata->mail, "references", &headers);
69964
 
+                       
69965
 
+       if ( msgdata->id != NULL ) {
69966
 
+               rfc2822_header_field_write(f, "In-Reply-To", msgdata->id);
69967
 
+       
69968
 
+               if ( ret >= 0 && headers[0] != NULL )
69969
 
+                       rfc2822_header_field_write
69970
 
+                               (f, "References", t_strconcat(headers[0], " ", msgdata->id, NULL));
69971
 
+               else
69972
 
+                       rfc2822_header_field_write(f, "References", msgdata->id);
69973
 
+       } else if ( ret >= 0 && headers[0] != NULL ) {
69974
 
+               rfc2822_header_field_write(f, "References", headers[0]);
69975
 
+       }
69976
 
+                       
69977
 
+       rfc2822_header_field_write(f, "Auto-Submitted", "auto-replied (vacation)");
69978
 
+       rfc2822_header_field_write(f, "Precedence", "bulk");
69979
 
+       
69980
 
+       rfc2822_header_field_write(f, "MIME-Version", "1.0");
69981
 
+    
69982
 
+       if ( !ctx->mime ) {
69983
 
+               rfc2822_header_field_write(f, "Content-Type", "text/plain; charset=utf-8");
69984
 
+               rfc2822_header_field_write(f, "Content-Transfer-Encoding", "8bit");
69985
 
+               fprintf(f, "\r\n");
69986
 
+       }
69987
 
+
69988
 
+       fprintf(f, "%s\r\n", ctx->reason);
69989
 
+
69990
 
+       /* Close smtp session */    
69991
 
+       if ( !senv->smtp_close(smtp_handle) ) {
69992
 
+               sieve_result_error(aenv, 
69993
 
+                       "failed to send vacation response to <%s> "
69994
 
+                       "(refer to server log for more information)", 
69995
 
+                       str_sanitize(sender, 128));     
69996
 
+               return TRUE;
69997
 
+       }
69998
 
+       
69999
 
+       return TRUE;
70000
 
+}
70001
 
+
70002
 
+static void act_vacation_hash
70003
 
+(struct act_vacation_context *vctx, const char *sender, unsigned char hash_r[])
70004
 
+{
70005
 
+       const char *rpath = t_str_lcase(sender);
70006
 
+       struct md5_context ctx;
70007
 
+
70008
 
+       md5_init(&ctx);
70009
 
+       md5_update(&ctx, rpath, strlen(rpath));
70010
 
+
70011
 
+       md5_update(&ctx, vctx->handle, strlen(vctx->handle));
70012
 
+       
70013
 
+       md5_final(&ctx, hash_r);
70014
 
+}
70015
 
+
70016
 
+static bool act_vacation_commit
70017
 
+(const struct sieve_action *action ATTR_UNUSED, 
70018
 
+       const struct sieve_action_exec_env *aenv, void *tr_context, 
70019
 
+       bool *keep ATTR_UNUSED)
70020
 
+{
70021
 
+       const char *const *hdsp;
70022
 
+       const struct sieve_message_data *msgdata = aenv->msgdata;
70023
 
+       const struct sieve_script_env *senv = aenv->scriptenv;
70024
 
+       struct act_vacation_context *ctx = (struct act_vacation_context *) tr_context;
70025
 
+       unsigned char dupl_hash[MD5_RESULTLEN];
70026
 
+       const char *const *headers;
70027
 
+       const char *sender = sieve_message_get_sender(aenv->msgctx);
70028
 
+       const char *recipient = sieve_message_get_recipient(aenv->msgctx);
70029
 
+       pool_t pool;
70030
 
+
70031
 
+       /* Is the recipient unset? 
70032
 
+        */
70033
 
+       if ( recipient == NULL ) {
70034
 
+               sieve_result_warning(aenv, "vacation action aborted: envelope recipient is <>");
70035
 
+               return TRUE;
70036
 
+       }
70037
 
+
70038
 
+       /* Is the return path unset ?
70039
 
+        */
70040
 
+       if ( sender == NULL ) {
70041
 
+               sieve_result_log(aenv, "discarded vacation reply to <>");
70042
 
+               return TRUE;
70043
 
+       }    
70044
 
+       
70045
 
+       /* Are we perhaps trying to respond to ourselves ? 
70046
 
+        * (FIXME: verify this to :addresses as well?)
70047
 
+        */
70048
 
+       if ( sieve_address_compare(sender, recipient, TRUE) 
70049
 
+               == 0 ) {
70050
 
+               sieve_result_log(aenv, "discarded vacation reply to own address");      
70051
 
+               return TRUE;
70052
 
+       }
70053
 
+       
70054
 
+       /* Did whe respond to this user before? */
70055
 
+       if ( senv->duplicate_check != NULL ) {
70056
 
+               act_vacation_hash(ctx, sender, dupl_hash);
70057
 
+       
70058
 
+               if ( senv->duplicate_check(dupl_hash, sizeof(dupl_hash), senv->username) ) 
70059
 
+               {
70060
 
+                       sieve_result_log(aenv, "discarded duplicate vacation response to <%s>",
70061
 
+                               str_sanitize(sender, 128));
70062
 
+                       return TRUE;
70063
 
+               }
70064
 
+       }
70065
 
+       
70066
 
+       /* Are we trying to respond to a mailing list ? */
70067
 
+       hdsp = _list_headers;
70068
 
+       while ( *hdsp != NULL ) {
70069
 
+               if ( mail_get_headers
70070
 
+                       (msgdata->mail, *hdsp, &headers) >= 0 && headers[0] != NULL ) { 
70071
 
+                       /* Yes, bail out */
70072
 
+                       sieve_result_log(aenv, 
70073
 
+                               "discarding vacation response to mailinglist recipient <%s>", 
70074
 
+                               str_sanitize(sender, 128));     
70075
 
+                       return TRUE;                             
70076
 
+               }
70077
 
+               hdsp++;
70078
 
+       }
70079
 
+       
70080
 
+       /* Is the message that we are replying to an automatic reply ? */
70081
 
+       if ( mail_get_headers
70082
 
+               (msgdata->mail, "auto-submitted", &headers) >= 0 ) {
70083
 
+               /* Theoretically multiple headers could exist, so lets make sure */
70084
 
+               hdsp = headers;
70085
 
+               while ( *hdsp != NULL ) {
70086
 
+                       if ( strcasecmp(*hdsp, "no") != 0 ) {
70087
 
+                               sieve_result_log(aenv, 
70088
 
+                                       "discardig vacation response to auto-submitted message from <%s>", 
70089
 
+                                       str_sanitize(sender, 128));     
70090
 
+                                       return TRUE;                             
70091
 
+                       }
70092
 
+                       hdsp++;
70093
 
+               }
70094
 
+       }
70095
 
+       
70096
 
+       /* Check for the (non-standard) precedence header */
70097
 
+       if ( mail_get_headers
70098
 
+               (msgdata->mail, "precedence", &headers) >= 0 ) {
70099
 
+               /* Theoretically multiple headers could exist, so lets make sure */
70100
 
+               hdsp = headers;
70101
 
+               while ( *hdsp != NULL ) {
70102
 
+                       if ( strcasecmp(*hdsp, "junk") == 0 || strcasecmp(*hdsp, "bulk") == 0 ||
70103
 
+                               strcasecmp(*hdsp, "list") == 0 ) {
70104
 
+                               sieve_result_log(aenv, 
70105
 
+                                       "discarding vacation response to precedence=%s message from <%s>", 
70106
 
+                                       *hdsp, str_sanitize(sender, 128));      
70107
 
+                                       return TRUE;                             
70108
 
+                       }
70109
 
+                       hdsp++;
70110
 
+               }
70111
 
+       }
70112
 
+       
70113
 
+       /* Do not reply to system addresses */
70114
 
+       if ( _is_system_address(sender) ) {
70115
 
+               sieve_result_log(aenv, 
70116
 
+                       "not sending vacation response to system address <%s>", 
70117
 
+                       str_sanitize(sender, 128));     
70118
 
+               return TRUE;                            
70119
 
+       } 
70120
 
+       
70121
 
+       /* Is the original message directly addressed to the user or the addresses
70122
 
+        * specified using the :addresses tag? 
70123
 
+        */
70124
 
+       hdsp = _my_address_headers;
70125
 
+       while ( *hdsp != NULL ) {
70126
 
+               if ( mail_get_headers_utf8
70127
 
+                       (msgdata->mail, *hdsp, &headers) >= 0 && headers[0] != NULL ) { 
70128
 
+                       
70129
 
+                       if ( _contains_my_address(headers, recipient) ) 
70130
 
+                               break;
70131
 
+                       
70132
 
+                       if ( ctx->addresses != NULL ) {
70133
 
+                               bool found = FALSE;
70134
 
+                               const char * const *my_address = ctx->addresses;
70135
 
+               
70136
 
+                               while ( !found && *my_address != NULL ) {
70137
 
+                                       found = _contains_my_address(headers, *my_address);
70138
 
+                                       my_address++;
70139
 
+                               }
70140
 
+                               
70141
 
+                               if ( found ) break;
70142
 
+                       }
70143
 
+               }
70144
 
+               hdsp++;
70145
 
+       }       
70146
 
+
70147
 
+       if ( *hdsp == NULL ) {
70148
 
+               /* No, bail out */
70149
 
+               sieve_result_log(aenv, 
70150
 
+                       "discarding vacation response for message implicitly delivered to <%s>",
70151
 
+                       recipient );    
70152
 
+               return TRUE;                             
70153
 
+       }       
70154
 
+               
70155
 
+       /* Make sure we have a subject for our reply */
70156
 
+       if ( ctx->subject == NULL || *(ctx->subject) == '\0' ) {
70157
 
+               if ( mail_get_headers_utf8
70158
 
+                       (msgdata->mail, "subject", &headers) >= 0 && headers[0] != NULL ) {
70159
 
+                       pool = sieve_result_pool(aenv->result);
70160
 
+                       ctx->subject = p_strconcat(pool, "Auto: ", headers[0], NULL);
70161
 
+               }       else {
70162
 
+                       ctx->subject = "Automated reply";
70163
 
+               }
70164
 
+       }       
70165
 
+       
70166
 
+       /* Send the message */
70167
 
+       
70168
 
+       if ( act_vacation_send(aenv, ctx, sender, recipient) ) {
70169
 
+               sieve_result_log(aenv, "sent vacation response to <%s>", 
70170
 
+                       str_sanitize(sender, 128));     
70171
 
+
70172
 
+               /* Mark as replied */
70173
 
+               if ( senv->duplicate_mark != NULL )
70174
 
+                       senv->duplicate_mark(dupl_hash, sizeof(dupl_hash), senv->username,
70175
 
+                               ioloop_time + ctx->days * (24 * 60 * 60));
70176
 
+
70177
 
+               return TRUE;
70178
 
+       }
70179
 
+
70180
 
+       return FALSE;
70181
 
+}
70182
 
+
70183
 
+
70184
 
+
70185
 
+
70186
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/vacation/ext-vacation.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/vacation/ext-vacation.c
70187
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/vacation/ext-vacation.c        1970-01-01 01:00:00.000000000 +0100
70188
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/vacation/ext-vacation.c 2009-01-06 00:15:52.000000000 +0100
70189
 
@@ -0,0 +1,52 @@
70190
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
70191
 
+ */
70192
 
+
70193
 
+/* Extension vacation
70194
 
+ * ------------------
70195
 
+ *
70196
 
+ * Authors: Stephan Bosch <stephan@rename-it.nl>
70197
 
+ * Specification: RFC 5230
70198
 
+ * Implementation: almost complete; the required sopport for Refences header 
70199
 
+ *   is missing.
70200
 
+ * Status: experimental, largely untested
70201
 
+ * 
70202
 
+ */
70203
 
+
70204
 
+#include "lib.h"
70205
 
+
70206
 
+#include "sieve-common.h"
70207
 
+
70208
 
+#include "sieve-extensions.h"
70209
 
+#include "sieve-commands.h"
70210
 
+#include "sieve-validator.h"
70211
 
+#include "sieve-generator.h"
70212
 
+#include "sieve-interpreter.h"
70213
 
+#include "sieve-dump.h"
70214
 
+
70215
 
+#include "ext-vacation-common.h"
70216
 
+
70217
 
+/* 
70218
 
+ * Extension
70219
 
+ */
70220
 
+
70221
 
+static bool ext_vacation_validator_load(struct sieve_validator *validator);
70222
 
+
70223
 
+static int ext_my_id = -1;
70224
 
+
70225
 
+const struct sieve_extension vacation_extension = { 
70226
 
+       "vacation",
70227
 
+       &ext_my_id,
70228
 
+       NULL, NULL,
70229
 
+       ext_vacation_validator_load, 
70230
 
+       NULL, NULL, NULL, NULL, NULL,
70231
 
+       SIEVE_EXT_DEFINE_OPERATION(vacation_operation),
70232
 
+       SIEVE_EXT_DEFINE_NO_OPERANDS
70233
 
+};
70234
 
+
70235
 
+static bool ext_vacation_validator_load(struct sieve_validator *validator)
70236
 
+{
70237
 
+       /* Register new command */
70238
 
+       sieve_validator_register_command(validator, &vacation_command);
70239
 
+
70240
 
+       return TRUE;
70241
 
+}
70242
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/vacation/ext-vacation-common.h dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/vacation/ext-vacation-common.h
70243
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/vacation/ext-vacation-common.h 1970-01-01 01:00:00.000000000 +0100
70244
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/vacation/ext-vacation-common.h  2009-01-06 00:15:52.000000000 +0100
70245
 
@@ -0,0 +1,25 @@
70246
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
70247
 
+ */
70248
 
+
70249
 
+#ifndef __EXT_VACATION_COMMON_H
70250
 
+#define __EXT_VACATION_COMMON_H
70251
 
+
70252
 
+#include "sieve-common.h"
70253
 
+
70254
 
+/* 
70255
 
+ * Commands 
70256
 
+ */
70257
 
+
70258
 
+extern const struct sieve_command vacation_command;
70259
 
+
70260
 
+/* 
70261
 
+ * Operations 
70262
 
+ */
70263
 
+
70264
 
+extern const struct sieve_operation vacation_operation;
70265
 
+
70266
 
+/* Extension */
70267
 
+
70268
 
+extern const struct sieve_extension vacation_extension;
70269
 
+
70270
 
+#endif /* __EXT_VACATION_COMMON_H */
70271
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/vacation/Makefile.am dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/vacation/Makefile.am
70272
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/vacation/Makefile.am   1970-01-01 01:00:00.000000000 +0100
70273
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/vacation/Makefile.am    2008-10-20 01:35:49.000000000 +0200
70274
 
@@ -0,0 +1,19 @@
70275
 
+noinst_LTLIBRARIES = libsieve_ext_vacation.la
70276
 
+
70277
 
+AM_CPPFLAGS = \
70278
 
+       -I../../ \
70279
 
+       -I$(dovecot_incdir) \
70280
 
+       -I$(dovecot_incdir)/src/lib \
70281
 
+       -I$(dovecot_incdir)/src/lib-mail \
70282
 
+       -I$(dovecot_incdir)/src/lib-storage 
70283
 
+
70284
 
+cmds = \
70285
 
+       cmd-vacation.c
70286
 
+
70287
 
+libsieve_ext_vacation_la_SOURCES = \
70288
 
+       $(cmds) \
70289
 
+       ext-vacation.c
70290
 
+
70291
 
+noinst_HEADERS = \
70292
 
+       ext-vacation-common.h
70293
 
+
70294
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/vacation/Makefile.in dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/vacation/Makefile.in
70295
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/vacation/Makefile.in   1970-01-01 01:00:00.000000000 +0100
70296
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/vacation/Makefile.in    2009-08-21 00:55:44.000000000 +0200
70297
 
@@ -0,0 +1,466 @@
70298
 
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
70299
 
+# @configure_input@
70300
 
+
70301
 
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
70302
 
+# 2003, 2004, 2005, 2006, 2007, 2008  Free Software Foundation, Inc.
70303
 
+# This Makefile.in is free software; the Free Software Foundation
70304
 
+# gives unlimited permission to copy and/or distribute it,
70305
 
+# with or without modifications, as long as this notice is preserved.
70306
 
+
70307
 
+# This program is distributed in the hope that it will be useful,
70308
 
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
70309
 
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
70310
 
+# PARTICULAR PURPOSE.
70311
 
+
70312
 
+@SET_MAKE@
70313
 
+
70314
 
+
70315
 
+VPATH = @srcdir@
70316
 
+pkgdatadir = $(datadir)/@PACKAGE@
70317
 
+pkglibdir = $(libdir)/@PACKAGE@
70318
 
+pkgincludedir = $(includedir)/@PACKAGE@
70319
 
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
70320
 
+install_sh_DATA = $(install_sh) -c -m 644
70321
 
+install_sh_PROGRAM = $(install_sh) -c
70322
 
+install_sh_SCRIPT = $(install_sh) -c
70323
 
+INSTALL_HEADER = $(INSTALL_DATA)
70324
 
+transform = $(program_transform_name)
70325
 
+NORMAL_INSTALL = :
70326
 
+PRE_INSTALL = :
70327
 
+POST_INSTALL = :
70328
 
+NORMAL_UNINSTALL = :
70329
 
+PRE_UNINSTALL = :
70330
 
+POST_UNINSTALL = :
70331
 
+build_triplet = @build@
70332
 
+host_triplet = @host@
70333
 
+subdir = src/lib-sieve/plugins/vacation
70334
 
+DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
70335
 
+       $(srcdir)/Makefile.in
70336
 
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
70337
 
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
70338
 
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
70339
 
+       $(ACLOCAL_M4)
70340
 
+mkinstalldirs = $(install_sh) -d
70341
 
+CONFIG_HEADER = $(top_builddir)/dummy-config.h \
70342
 
+       $(top_builddir)/dsieve-config.h
70343
 
+CONFIG_CLEAN_FILES =
70344
 
+LTLIBRARIES = $(noinst_LTLIBRARIES)
70345
 
+libsieve_ext_vacation_la_LIBADD =
70346
 
+am__objects_1 = cmd-vacation.lo
70347
 
+am_libsieve_ext_vacation_la_OBJECTS = $(am__objects_1) ext-vacation.lo
70348
 
+libsieve_ext_vacation_la_OBJECTS =  \
70349
 
+       $(am_libsieve_ext_vacation_la_OBJECTS)
70350
 
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
70351
 
+depcomp = $(SHELL) $(top_srcdir)/depcomp
70352
 
+am__depfiles_maybe = depfiles
70353
 
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
70354
 
+       $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
70355
 
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
70356
 
+       --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
70357
 
+       $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
70358
 
+CCLD = $(CC)
70359
 
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
70360
 
+       --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
70361
 
+       $(LDFLAGS) -o $@
70362
 
+SOURCES = $(libsieve_ext_vacation_la_SOURCES)
70363
 
+DIST_SOURCES = $(libsieve_ext_vacation_la_SOURCES)
70364
 
+HEADERS = $(noinst_HEADERS)
70365
 
+ETAGS = etags
70366
 
+CTAGS = ctags
70367
 
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
70368
 
+ACLOCAL = @ACLOCAL@
70369
 
+AMTAR = @AMTAR@
70370
 
+AR = @AR@
70371
 
+AUTOCONF = @AUTOCONF@
70372
 
+AUTOHEADER = @AUTOHEADER@
70373
 
+AUTOMAKE = @AUTOMAKE@
70374
 
+AWK = @AWK@
70375
 
+CC = @CC@
70376
 
+CCDEPMODE = @CCDEPMODE@
70377
 
+CFLAGS = @CFLAGS@
70378
 
+CPP = @CPP@
70379
 
+CPPFLAGS = @CPPFLAGS@
70380
 
+CYGPATH_W = @CYGPATH_W@
70381
 
+DEFS = @DEFS@
70382
 
+DEPDIR = @DEPDIR@
70383
 
+DSYMUTIL = @DSYMUTIL@
70384
 
+DUMPBIN = @DUMPBIN@
70385
 
+ECHO_C = @ECHO_C@
70386
 
+ECHO_N = @ECHO_N@
70387
 
+ECHO_T = @ECHO_T@
70388
 
+EGREP = @EGREP@
70389
 
+EXEEXT = @EXEEXT@
70390
 
+FGREP = @FGREP@
70391
 
+GREP = @GREP@
70392
 
+INSTALL = @INSTALL@
70393
 
+INSTALL_DATA = @INSTALL_DATA@
70394
 
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
70395
 
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
70396
 
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
70397
 
+LD = @LD@
70398
 
+LDFLAGS = @LDFLAGS@
70399
 
+LIBICONV = @LIBICONV@
70400
 
+LIBOBJS = @LIBOBJS@
70401
 
+LIBS = @LIBS@
70402
 
+LIBTOOL = @LIBTOOL@
70403
 
+LIPO = @LIPO@
70404
 
+LN_S = @LN_S@
70405
 
+LTLIBOBJS = @LTLIBOBJS@
70406
 
+MAINT = @MAINT@
70407
 
+MAKEINFO = @MAKEINFO@
70408
 
+MKDIR_P = @MKDIR_P@
70409
 
+MODULE_LIBS = @MODULE_LIBS@
70410
 
+NM = @NM@
70411
 
+NMEDIT = @NMEDIT@
70412
 
+OBJDUMP = @OBJDUMP@
70413
 
+OBJEXT = @OBJEXT@
70414
 
+OTOOL = @OTOOL@
70415
 
+OTOOL64 = @OTOOL64@
70416
 
+PACKAGE = @PACKAGE@
70417
 
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
70418
 
+PACKAGE_NAME = @PACKAGE_NAME@
70419
 
+PACKAGE_STRING = @PACKAGE_STRING@
70420
 
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
70421
 
+PACKAGE_URL = @PACKAGE_URL@
70422
 
+PACKAGE_VERSION = @PACKAGE_VERSION@
70423
 
+PATH_SEPARATOR = @PATH_SEPARATOR@
70424
 
+RAND_LIBS = @RAND_LIBS@
70425
 
+RANLIB = @RANLIB@
70426
 
+SED = @SED@
70427
 
+SET_MAKE = @SET_MAKE@
70428
 
+SHELL = @SHELL@
70429
 
+STORAGE_LIBS = @STORAGE_LIBS@
70430
 
+STRIP = @STRIP@
70431
 
+VERSION = @VERSION@
70432
 
+abs_builddir = @abs_builddir@
70433
 
+abs_srcdir = @abs_srcdir@
70434
 
+abs_top_builddir = @abs_top_builddir@
70435
 
+abs_top_srcdir = @abs_top_srcdir@
70436
 
+ac_ct_CC = @ac_ct_CC@
70437
 
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
70438
 
+am__include = @am__include@
70439
 
+am__leading_dot = @am__leading_dot@
70440
 
+am__quote = @am__quote@
70441
 
+am__tar = @am__tar@
70442
 
+am__untar = @am__untar@
70443
 
+bindir = @bindir@
70444
 
+build = @build@
70445
 
+build_alias = @build_alias@
70446
 
+build_cpu = @build_cpu@
70447
 
+build_os = @build_os@
70448
 
+build_vendor = @build_vendor@
70449
 
+builddir = @builddir@
70450
 
+datadir = @datadir@
70451
 
+datarootdir = @datarootdir@
70452
 
+docdir = @docdir@
70453
 
+dovecot_incdir = @dovecot_incdir@
70454
 
+dovecotdir = @dovecotdir@
70455
 
+dvidir = @dvidir@
70456
 
+exec_prefix = @exec_prefix@
70457
 
+host = @host@
70458
 
+host_alias = @host_alias@
70459
 
+host_cpu = @host_cpu@
70460
 
+host_os = @host_os@
70461
 
+host_vendor = @host_vendor@
70462
 
+htmldir = @htmldir@
70463
 
+includedir = @includedir@
70464
 
+infodir = @infodir@
70465
 
+install_sh = @install_sh@
70466
 
+libdir = @libdir@
70467
 
+libexecdir = @libexecdir@
70468
 
+localedir = @localedir@
70469
 
+localstatedir = @localstatedir@
70470
 
+lt_ECHO = @lt_ECHO@
70471
 
+mandir = @mandir@
70472
 
+mkdir_p = @mkdir_p@
70473
 
+moduledir = @moduledir@
70474
 
+oldincludedir = @oldincludedir@
70475
 
+pdfdir = @pdfdir@
70476
 
+prefix = @prefix@
70477
 
+program_transform_name = @program_transform_name@
70478
 
+psdir = @psdir@
70479
 
+sbindir = @sbindir@
70480
 
+sharedstatedir = @sharedstatedir@
70481
 
+srcdir = @srcdir@
70482
 
+sysconfdir = @sysconfdir@
70483
 
+target_alias = @target_alias@
70484
 
+top_build_prefix = @top_build_prefix@
70485
 
+top_builddir = @top_builddir@
70486
 
+top_srcdir = @top_srcdir@
70487
 
+noinst_LTLIBRARIES = libsieve_ext_vacation.la
70488
 
+AM_CPPFLAGS = \
70489
 
+       -I../../ \
70490
 
+       -I$(dovecot_incdir) \
70491
 
+       -I$(dovecot_incdir)/src/lib \
70492
 
+       -I$(dovecot_incdir)/src/lib-mail \
70493
 
+       -I$(dovecot_incdir)/src/lib-storage 
70494
 
+
70495
 
+cmds = \
70496
 
+       cmd-vacation.c
70497
 
+
70498
 
+libsieve_ext_vacation_la_SOURCES = \
70499
 
+       $(cmds) \
70500
 
+       ext-vacation.c
70501
 
+
70502
 
+noinst_HEADERS = \
70503
 
+       ext-vacation-common.h
70504
 
+
70505
 
+all: all-am
70506
 
+
70507
 
+.SUFFIXES:
70508
 
+.SUFFIXES: .c .lo .o .obj
70509
 
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
70510
 
+       @for dep in $?; do \
70511
 
+         case '$(am__configure_deps)' in \
70512
 
+           *$$dep*) \
70513
 
+             ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
70514
 
+               && { if test -f $@; then exit 0; else break; fi; }; \
70515
 
+             exit 1;; \
70516
 
+         esac; \
70517
 
+       done; \
70518
 
+       echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign  src/lib-sieve/plugins/vacation/Makefile'; \
70519
 
+       cd $(top_srcdir) && \
70520
 
+         $(AUTOMAKE) --foreign  src/lib-sieve/plugins/vacation/Makefile
70521
 
+.PRECIOUS: Makefile
70522
 
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
70523
 
+       @case '$?' in \
70524
 
+         *config.status*) \
70525
 
+           cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
70526
 
+         *) \
70527
 
+           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
70528
 
+           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
70529
 
+       esac;
70530
 
+
70531
 
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
70532
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
70533
 
+
70534
 
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
70535
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
70536
 
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
70537
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
70538
 
+
70539
 
+clean-noinstLTLIBRARIES:
70540
 
+       -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
70541
 
+       @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
70542
 
+         dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
70543
 
+         test "$$dir" != "$$p" || dir=.; \
70544
 
+         echo "rm -f \"$${dir}/so_locations\""; \
70545
 
+         rm -f "$${dir}/so_locations"; \
70546
 
+       done
70547
 
+libsieve_ext_vacation.la: $(libsieve_ext_vacation_la_OBJECTS) $(libsieve_ext_vacation_la_DEPENDENCIES) 
70548
 
+       $(LINK)  $(libsieve_ext_vacation_la_OBJECTS) $(libsieve_ext_vacation_la_LIBADD) $(LIBS)
70549
 
+
70550
 
+mostlyclean-compile:
70551
 
+       -rm -f *.$(OBJEXT)
70552
 
+
70553
 
+distclean-compile:
70554
 
+       -rm -f *.tab.c
70555
 
+
70556
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd-vacation.Plo@am__quote@
70557
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-vacation.Plo@am__quote@
70558
 
+
70559
 
+.c.o:
70560
 
+@am__fastdepCC_TRUE@   $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
70561
 
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
70562
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
70563
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
70564
 
+@am__fastdepCC_FALSE@  $(COMPILE) -c $<
70565
 
+
70566
 
+.c.obj:
70567
 
+@am__fastdepCC_TRUE@   $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
70568
 
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
70569
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
70570
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
70571
 
+@am__fastdepCC_FALSE@  $(COMPILE) -c `$(CYGPATH_W) '$<'`
70572
 
+
70573
 
+.c.lo:
70574
 
+@am__fastdepCC_TRUE@   $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
70575
 
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
70576
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
70577
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
70578
 
+@am__fastdepCC_FALSE@  $(LTCOMPILE) -c -o $@ $<
70579
 
+
70580
 
+mostlyclean-libtool:
70581
 
+       -rm -f *.lo
70582
 
+
70583
 
+clean-libtool:
70584
 
+       -rm -rf .libs _libs
70585
 
+
70586
 
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
70587
 
+       list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
70588
 
+       unique=`for i in $$list; do \
70589
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
70590
 
+         done | \
70591
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
70592
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
70593
 
+       mkid -fID $$unique
70594
 
+tags: TAGS
70595
 
+
70596
 
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
70597
 
+               $(TAGS_FILES) $(LISP)
70598
 
+       tags=; \
70599
 
+       here=`pwd`; \
70600
 
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
70601
 
+       unique=`for i in $$list; do \
70602
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
70603
 
+         done | \
70604
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
70605
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
70606
 
+       if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
70607
 
+         test -n "$$unique" || unique=$$empty_fix; \
70608
 
+         $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
70609
 
+           $$tags $$unique; \
70610
 
+       fi
70611
 
+ctags: CTAGS
70612
 
+CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
70613
 
+               $(TAGS_FILES) $(LISP)
70614
 
+       tags=; \
70615
 
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
70616
 
+       unique=`for i in $$list; do \
70617
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
70618
 
+         done | \
70619
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
70620
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
70621
 
+       test -z "$(CTAGS_ARGS)$$tags$$unique" \
70622
 
+         || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
70623
 
+            $$tags $$unique
70624
 
+
70625
 
+GTAGS:
70626
 
+       here=`$(am__cd) $(top_builddir) && pwd` \
70627
 
+         && cd $(top_srcdir) \
70628
 
+         && gtags -i $(GTAGS_ARGS) $$here
70629
 
+
70630
 
+distclean-tags:
70631
 
+       -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
70632
 
+
70633
 
+distdir: $(DISTFILES)
70634
 
+       @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
70635
 
+       topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
70636
 
+       list='$(DISTFILES)'; \
70637
 
+         dist_files=`for file in $$list; do echo $$file; done | \
70638
 
+         sed -e "s|^$$srcdirstrip/||;t" \
70639
 
+             -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
70640
 
+       case $$dist_files in \
70641
 
+         */*) $(MKDIR_P) `echo "$$dist_files" | \
70642
 
+                          sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
70643
 
+                          sort -u` ;; \
70644
 
+       esac; \
70645
 
+       for file in $$dist_files; do \
70646
 
+         if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
70647
 
+         if test -d $$d/$$file; then \
70648
 
+           dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
70649
 
+           if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
70650
 
+             cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
70651
 
+           fi; \
70652
 
+           cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
70653
 
+         else \
70654
 
+           test -f $(distdir)/$$file \
70655
 
+           || cp -p $$d/$$file $(distdir)/$$file \
70656
 
+           || exit 1; \
70657
 
+         fi; \
70658
 
+       done
70659
 
+check-am: all-am
70660
 
+check: check-am
70661
 
+all-am: Makefile $(LTLIBRARIES) $(HEADERS)
70662
 
+installdirs:
70663
 
+install: install-am
70664
 
+install-exec: install-exec-am
70665
 
+install-data: install-data-am
70666
 
+uninstall: uninstall-am
70667
 
+
70668
 
+install-am: all-am
70669
 
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
70670
 
+
70671
 
+installcheck: installcheck-am
70672
 
+install-strip:
70673
 
+       $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
70674
 
+         install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
70675
 
+         `test -z '$(STRIP)' || \
70676
 
+           echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
70677
 
+mostlyclean-generic:
70678
 
+
70679
 
+clean-generic:
70680
 
+
70681
 
+distclean-generic:
70682
 
+       -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
70683
 
+
70684
 
+maintainer-clean-generic:
70685
 
+       @echo "This command is intended for maintainers to use"
70686
 
+       @echo "it deletes files that may require special tools to rebuild."
70687
 
+clean: clean-am
70688
 
+
70689
 
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
70690
 
+       mostlyclean-am
70691
 
+
70692
 
+distclean: distclean-am
70693
 
+       -rm -rf ./$(DEPDIR)
70694
 
+       -rm -f Makefile
70695
 
+distclean-am: clean-am distclean-compile distclean-generic \
70696
 
+       distclean-tags
70697
 
+
70698
 
+dvi: dvi-am
70699
 
+
70700
 
+dvi-am:
70701
 
+
70702
 
+html: html-am
70703
 
+
70704
 
+info: info-am
70705
 
+
70706
 
+info-am:
70707
 
+
70708
 
+install-data-am:
70709
 
+
70710
 
+install-dvi: install-dvi-am
70711
 
+
70712
 
+install-exec-am:
70713
 
+
70714
 
+install-html: install-html-am
70715
 
+
70716
 
+install-info: install-info-am
70717
 
+
70718
 
+install-man:
70719
 
+
70720
 
+install-pdf: install-pdf-am
70721
 
+
70722
 
+install-ps: install-ps-am
70723
 
+
70724
 
+installcheck-am:
70725
 
+
70726
 
+maintainer-clean: maintainer-clean-am
70727
 
+       -rm -rf ./$(DEPDIR)
70728
 
+       -rm -f Makefile
70729
 
+maintainer-clean-am: distclean-am maintainer-clean-generic
70730
 
+
70731
 
+mostlyclean: mostlyclean-am
70732
 
+
70733
 
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
70734
 
+       mostlyclean-libtool
70735
 
+
70736
 
+pdf: pdf-am
70737
 
+
70738
 
+pdf-am:
70739
 
+
70740
 
+ps: ps-am
70741
 
+
70742
 
+ps-am:
70743
 
+
70744
 
+uninstall-am:
70745
 
+
70746
 
+.MAKE: install-am install-strip
70747
 
+
70748
 
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
70749
 
+       clean-libtool clean-noinstLTLIBRARIES ctags distclean \
70750
 
+       distclean-compile distclean-generic distclean-libtool \
70751
 
+       distclean-tags distdir dvi dvi-am html html-am info info-am \
70752
 
+       install install-am install-data install-data-am install-dvi \
70753
 
+       install-dvi-am install-exec install-exec-am install-html \
70754
 
+       install-html-am install-info install-info-am install-man \
70755
 
+       install-pdf install-pdf-am install-ps install-ps-am \
70756
 
+       install-strip installcheck installcheck-am installdirs \
70757
 
+       maintainer-clean maintainer-clean-generic mostlyclean \
70758
 
+       mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
70759
 
+       pdf pdf-am ps ps-am tags uninstall uninstall-am
70760
 
+
70761
 
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
70762
 
+# Otherwise a system limit (for SysV at least) may be exceeded.
70763
 
+.NOEXPORT:
70764
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/variables/cmd-set.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/variables/cmd-set.c
70765
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/variables/cmd-set.c    1970-01-01 01:00:00.000000000 +0100
70766
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/variables/cmd-set.c     2009-01-06 00:15:52.000000000 +0100
70767
 
@@ -0,0 +1,368 @@
70768
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
70769
 
+ */
70770
 
+
70771
 
+#include "lib.h"
70772
 
+#include "str.h"
70773
 
+#include "array.h"
70774
 
+
70775
 
+#include "sieve-common.h"
70776
 
+#include "sieve-extensions.h"
70777
 
+
70778
 
+#include "sieve-code.h"
70779
 
+#include "sieve-ast.h"
70780
 
+#include "sieve-commands.h"
70781
 
+#include "sieve-binary.h"
70782
 
+
70783
 
+#include "sieve-validator.h"
70784
 
+#include "sieve-generator.h"
70785
 
+#include "sieve-interpreter.h"
70786
 
+#include "sieve-dump.h"
70787
 
+
70788
 
+#include "ext-variables-common.h"
70789
 
+#include "ext-variables-modifiers.h"
70790
 
+
70791
 
+/* 
70792
 
+ * Set command 
70793
 
+ *     
70794
 
+ * Syntax: 
70795
 
+ *    set [MODIFIER] <name: string> <value: string>
70796
 
+ */
70797
 
+
70798
 
+static bool cmd_set_registered
70799
 
+       (struct sieve_validator *validator, struct sieve_command_registration *cmd_reg);
70800
 
+static bool cmd_set_pre_validate
70801
 
+       (struct sieve_validator *validator, struct sieve_command_context *cmd);
70802
 
+static bool cmd_set_validate
70803
 
+       (struct sieve_validator *validator, struct sieve_command_context *cmd);
70804
 
+static bool cmd_set_generate
70805
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx);
70806
 
+
70807
 
+const struct sieve_command cmd_set = { 
70808
 
+       "set",
70809
 
+       SCT_COMMAND, 
70810
 
+       2, 0, FALSE, FALSE, 
70811
 
+       cmd_set_registered,
70812
 
+       cmd_set_pre_validate,  
70813
 
+       cmd_set_validate, 
70814
 
+       cmd_set_generate, 
70815
 
+       NULL 
70816
 
+};
70817
 
+
70818
 
+/* 
70819
 
+ * Set operation 
70820
 
+ */
70821
 
+
70822
 
+static bool cmd_set_operation_dump
70823
 
+       (const struct sieve_operation *op,      
70824
 
+               const struct sieve_dumptime_env *denv, sieve_size_t *address);
70825
 
+static int cmd_set_operation_execute
70826
 
+       (const struct sieve_operation *op, 
70827
 
+               const struct sieve_runtime_env *renv, sieve_size_t *address);
70828
 
+
70829
 
+const struct sieve_operation cmd_set_operation = { 
70830
 
+       "SET",
70831
 
+       &variables_extension,
70832
 
+       EXT_VARIABLES_OPERATION_SET,
70833
 
+       cmd_set_operation_dump, 
70834
 
+       cmd_set_operation_execute
70835
 
+};
70836
 
+
70837
 
+/* 
70838
 
+ * Compiler context 
70839
 
+ */
70840
 
+
70841
 
+struct cmd_set_context {
70842
 
+       ARRAY_DEFINE(modifiers, const struct sieve_variables_modifier *);
70843
 
+};
70844
 
+
70845
 
+/* 
70846
 
+ * Set modifier tag
70847
 
+ *
70848
 
+ * [MODIFIER]:
70849
 
+ *   ":lower" / ":upper" / ":lowerfirst" / ":upperfirst" /
70850
 
+ *             ":quotewildcard" / ":length"
70851
 
+ */
70852
 
+
70853
 
+/* Forward declarations */
70854
 
70855
 
+static bool tag_modifier_is_instance_of
70856
 
+       (struct sieve_validator *validator, struct sieve_command_context *cmdctx,       
70857
 
+               struct sieve_ast_argument *arg);        
70858
 
+static bool tag_modifier_validate
70859
 
+       (struct sieve_validator *validator, struct sieve_ast_argument **arg, 
70860
 
+               struct sieve_command_context *cmd);
70861
 
+
70862
 
+/* Modifier tag object */
70863
 
+
70864
 
+const struct sieve_argument modifier_tag = { 
70865
 
+       "MODIFIER",
70866
 
+       tag_modifier_is_instance_of, 
70867
 
+       NULL,
70868
 
+       tag_modifier_validate, 
70869
 
+       NULL, NULL
70870
 
+};
70871
 
70872
 
+/* Modifier tag implementation */ 
70873
 
70874
 
+static bool tag_modifier_is_instance_of
70875
 
+(struct sieve_validator *validator ATTR_UNUSED, 
70876
 
+       struct sieve_command_context *cmdctx ATTR_UNUSED,       
70877
 
+       struct sieve_ast_argument *arg)
70878
 
+{      
70879
 
+       const struct sieve_variables_modifier *modf = ext_variables_modifier_find
70880
 
+               (validator, sieve_ast_argument_tag(arg));
70881
 
+
70882
 
+       arg->context = (void *) modf;
70883
 
+               
70884
 
+       return ( modf != NULL );
70885
 
+}
70886
 
+
70887
 
+static bool tag_modifier_validate
70888
 
+(struct sieve_validator *validator, struct sieve_ast_argument **arg, 
70889
 
+       struct sieve_command_context *cmd)
70890
 
+{
70891
 
+       unsigned int i;
70892
 
+       bool inserted;
70893
 
+       const struct sieve_variables_modifier *modf = 
70894
 
+               (const struct sieve_variables_modifier *) (*arg)->context;
70895
 
+       struct cmd_set_context *sctx = (struct cmd_set_context *) cmd->data;
70896
 
+       
70897
 
+       inserted = FALSE;
70898
 
+       for ( i = 0; i < array_count(&sctx->modifiers) && !inserted; i++ ) {
70899
 
+               const struct sieve_variables_modifier * const *smdf =
70900
 
+                       array_idx(&sctx->modifiers, i);
70901
 
+       
70902
 
+               if ( (*smdf)->precedence == modf->precedence ) {
70903
 
+                       sieve_argument_validate_error(validator, *arg, 
70904
 
+                               "modifiers :%s and :%s specified for the set command conflict "
70905
 
+                               "having equal precedence", 
70906
 
+                               (*smdf)->object.identifier, modf->object.identifier);
70907
 
+                       return FALSE;
70908
 
+               }
70909
 
+                       
70910
 
+               if ( (*smdf)->precedence < modf->precedence ) {
70911
 
+                       array_insert(&sctx->modifiers, i, &modf, 1);
70912
 
+                       inserted = TRUE;
70913
 
+               }
70914
 
+       }
70915
 
+       
70916
 
+       if ( !inserted )
70917
 
+               array_append(&sctx->modifiers, &modf, 1);
70918
 
+       
70919
 
+       /* Added to modifier list; self-destruct to prevent duplicate generation */
70920
 
+       *arg = sieve_ast_arguments_detach(*arg, 1);
70921
 
+       
70922
 
+       return TRUE;
70923
 
+}
70924
 
+
70925
 
+/* Command registration */
70926
 
+
70927
 
+static bool cmd_set_registered
70928
 
+       (struct sieve_validator *validator, struct sieve_command_registration *cmd_reg) 
70929
 
+{
70930
 
+       sieve_validator_register_tag(validator, cmd_reg, &modifier_tag, 0);     
70931
 
+
70932
 
+       return TRUE;
70933
 
+}
70934
 
+
70935
 
+/* 
70936
 
+ * Command validation 
70937
 
+ */
70938
 
+
70939
 
+static bool cmd_set_pre_validate
70940
 
+(struct sieve_validator *validator ATTR_UNUSED, 
70941
 
+       struct sieve_command_context *cmd)
70942
 
+{
70943
 
+       pool_t pool = sieve_command_pool(cmd);
70944
 
+       struct cmd_set_context *sctx = p_new(pool, struct cmd_set_context, 1);
70945
 
+       
70946
 
+       /* Create an array for the sorted list of modifiers */
70947
 
+       p_array_init(&sctx->modifiers, pool, 2);
70948
 
+
70949
 
+       cmd->data = (void *) sctx;
70950
 
+       
70951
 
+       return TRUE;
70952
 
+} 
70953
 
+
70954
 
+static bool cmd_set_validate(struct sieve_validator *validator, 
70955
 
+       struct sieve_command_context *cmd) 
70956
 
+{ 
70957
 
+       struct sieve_ast_argument *arg = cmd->first_positional;
70958
 
+               
70959
 
+       if ( !sieve_validate_positional_argument
70960
 
+               (validator, cmd, arg, "name", 1, SAAT_STRING) ) {
70961
 
+               return FALSE;
70962
 
+       }
70963
 
+       
70964
 
+       if ( !sieve_variable_argument_activate(validator, cmd, arg, TRUE) ) {
70965
 
+               return FALSE;
70966
 
+       }
70967
 
+
70968
 
+       arg = sieve_ast_argument_next(arg);
70969
 
+       
70970
 
+       if ( !sieve_validate_positional_argument
70971
 
+               (validator, cmd, arg, "value", 2, SAAT_STRING) ) {
70972
 
+               return FALSE;
70973
 
+       }
70974
 
+       
70975
 
+       return sieve_validator_argument_activate(validator, cmd, arg, FALSE);   
70976
 
+}
70977
 
+
70978
 
+/*
70979
 
+ * Code generation
70980
 
+ */
70981
 
70982
 
+static bool cmd_set_generate
70983
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx) 
70984
 
+{
70985
 
+       struct sieve_binary *sbin = cgenv->sbin;
70986
 
+       struct cmd_set_context *sctx = (struct cmd_set_context *) ctx->data;
70987
 
+       unsigned int i; 
70988
 
+
70989
 
+       sieve_operation_emit_code(sbin, &cmd_set_operation); 
70990
 
+
70991
 
+       /* Generate arguments */
70992
 
+       if ( !sieve_generate_arguments(cgenv, ctx, NULL) )
70993
 
+               return FALSE;   
70994
 
+               
70995
 
+       /* Generate modifiers (already sorted during validation) */
70996
 
+       sieve_binary_emit_byte(sbin, array_count(&sctx->modifiers));
70997
 
+       for ( i = 0; i < array_count(&sctx->modifiers); i++ ) {
70998
 
+               const struct sieve_variables_modifier * const * modf =
70999
 
+                       array_idx(&sctx->modifiers, i);
71000
 
+                       
71001
 
+               ext_variables_opr_modifier_emit(sbin, *modf);
71002
 
+       }
71003
 
+
71004
 
+       return TRUE;
71005
 
+}
71006
 
+
71007
 
+/* 
71008
 
+ * Code dump
71009
 
+ */
71010
 
71011
 
+static bool cmd_set_operation_dump
71012
 
+(const struct sieve_operation *op ATTR_UNUSED,
71013
 
+       const struct sieve_dumptime_env *denv, sieve_size_t *address)
71014
 
+{      
71015
 
+       unsigned int mdfs, i;
71016
 
+       
71017
 
+       sieve_code_dumpf(denv, "SET");
71018
 
+       sieve_code_descend(denv);
71019
 
+       
71020
 
+       /* Print both variable name and string value */
71021
 
+       if ( !sieve_opr_string_dump(denv, address, "variable") ||
71022
 
+               !sieve_opr_string_dump(denv, address, "value") )
71023
 
+               return FALSE;
71024
 
+       
71025
 
+       /* Read the number of applied modifiers we need to read */
71026
 
+       if ( !sieve_binary_read_byte(denv->sbin, address, &mdfs) ) 
71027
 
+               return FALSE;
71028
 
+       
71029
 
+       /* Print all modifiers (sorted during code generation already) */
71030
 
+       for ( i = 0; i < mdfs; i++ ) {
71031
 
+               if ( !ext_variables_opr_modifier_dump(denv, address) )
71032
 
+                       return FALSE;
71033
 
+       }
71034
 
+       
71035
 
+       return TRUE;
71036
 
+}
71037
 
+
71038
 
+/* 
71039
 
+ * Code execution
71040
 
+ */
71041
 
71042
 
+static int cmd_set_operation_execute
71043
 
+(const struct sieve_operation *op ATTR_UNUSED,
71044
 
+       const struct sieve_runtime_env *renv, sieve_size_t *address)
71045
 
+{      
71046
 
+       struct sieve_variable_storage *storage;
71047
 
+       unsigned int var_index, mdfs, i;
71048
 
+       string_t *value;
71049
 
+       int ret = SIEVE_EXEC_OK;
71050
 
+
71051
 
+       /*
71052
 
+        * Read the normal operands
71053
 
+        */
71054
 
+               
71055
 
+       /* Read the variable */
71056
 
+       if ( !sieve_variable_operand_read
71057
 
+               (renv, address, &storage, &var_index) ) {
71058
 
+               sieve_runtime_trace_error(renv, "invalid variable operand");
71059
 
+               return SIEVE_EXEC_BIN_CORRUPT;
71060
 
+       }
71061
 
+               
71062
 
+       /* Read the raw string value */
71063
 
+       if ( !sieve_opr_string_read(renv, address, &value) ) {
71064
 
+               sieve_runtime_trace_error(renv, "invalid string operand");
71065
 
+               return SIEVE_EXEC_BIN_CORRUPT;
71066
 
+       }
71067
 
+               
71068
 
+       /* Read the number of modifiers used */
71069
 
+       if ( !sieve_binary_read_byte(renv->sbin, address, &mdfs) ) {
71070
 
+               sieve_runtime_trace_error(renv, "invalid modifier count");
71071
 
+               return SIEVE_EXEC_BIN_CORRUPT;
71072
 
+       }
71073
 
+       
71074
 
+       /* 
71075
 
+        * Determine and assign the value 
71076
 
+        */
71077
 
+
71078
 
+       sieve_runtime_trace(renv, "SET action");
71079
 
+
71080
 
+       /* Hold value within limits */
71081
 
+       if ( str_len(value) > SIEVE_VARIABLES_MAX_VARIABLE_SIZE )
71082
 
+               str_truncate(value, SIEVE_VARIABLES_MAX_VARIABLE_SIZE);
71083
 
+
71084
 
+       T_BEGIN {
71085
 
+               /* Apply modifiers if necessary (sorted during code generation already) */
71086
 
+               if ( str_len(value) > 0 ) {
71087
 
+                       for ( i = 0; i < mdfs; i++ ) {
71088
 
+                               string_t *new_value;
71089
 
+                               const struct sieve_variables_modifier *modf =
71090
 
+                                       ext_variables_opr_modifier_read(renv, address);
71091
 
+
71092
 
+                               if ( modf == NULL ) {
71093
 
+                                       value = NULL;
71094
 
+
71095
 
+                                       sieve_runtime_trace_error(renv, "invalid modifier operand");
71096
 
+                                       ret = SIEVE_EXEC_BIN_CORRUPT;
71097
 
+                                       break;
71098
 
+                               }
71099
 
+                               
71100
 
+                               if ( modf->modify != NULL ) {
71101
 
+                                       if ( !modf->modify(value, &new_value) ) {
71102
 
+                                               value = NULL;
71103
 
+                                               ret = SIEVE_EXEC_FAILURE;
71104
 
+                                               break;
71105
 
+                                       }
71106
 
+
71107
 
+                                       value = new_value;
71108
 
+                                       if ( value == NULL )
71109
 
+                                               break;
71110
 
+
71111
 
+                                       /* Hold value within limits */
71112
 
+                                       if ( str_len(value) > SIEVE_VARIABLES_MAX_VARIABLE_SIZE )
71113
 
+                                               str_truncate(value, SIEVE_VARIABLES_MAX_VARIABLE_SIZE);
71114
 
+                               }
71115
 
+                       }
71116
 
+               }       
71117
 
+               
71118
 
+               /* Actually assign the value if all is well */
71119
 
+               if ( value != NULL ) {
71120
 
+                       if ( !sieve_variable_assign(storage, var_index, value) )
71121
 
+                               ret = SIEVE_EXEC_BIN_CORRUPT;
71122
 
+               }       
71123
 
+       } T_END;
71124
 
+                       
71125
 
+       if ( ret <= 0 ) 
71126
 
+               return ret;             
71127
 
+
71128
 
+       return ( value != NULL );
71129
 
+}
71130
 
+
71131
 
+
71132
 
+
71133
 
+
71134
 
+
71135
 
+
71136
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/variables/ext-variables-arguments.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/variables/ext-variables-arguments.c
71137
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/variables/ext-variables-arguments.c    1970-01-01 01:00:00.000000000 +0100
71138
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/variables/ext-variables-arguments.c     2009-01-06 00:15:52.000000000 +0100
71139
 
@@ -0,0 +1,438 @@
71140
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
71141
 
+ */
71142
 
+
71143
 
+#include "lib.h"
71144
 
+#include "str.h"
71145
 
+#include "str-sanitize.h"
71146
 
+#include "array.h"
71147
 
+
71148
 
+#include "sieve-common.h"
71149
 
+#include "sieve-ast.h"
71150
 
+#include "sieve-commands.h"
71151
 
+#include "sieve-code.h"
71152
 
+#include "sieve-validator.h"
71153
 
+#include "sieve-generator.h"
71154
 
+#include "sieve-dump.h"
71155
 
+
71156
 
+#include "ext-variables-common.h"
71157
 
+#include "ext-variables-limits.h"
71158
 
+#include "ext-variables-name.h"
71159
 
+#include "ext-variables-arguments.h"
71160
 
+
71161
 
+/*
71162
 
+ * Common error messages
71163
 
+ */
71164
 
+
71165
 
+static inline void _ext_variables_scope_size_error
71166
 
+(struct sieve_validator *valdtr, struct sieve_ast_argument *arg,
71167
 
+       const char *variable)
71168
 
+{
71169
 
+       sieve_argument_validate_error(valdtr, arg, 
71170
 
+               "(implicit) declaration of new variable '%s' exceeds the limit "
71171
 
+               "(max variables: %u)", variable, 
71172
 
+               SIEVE_VARIABLES_MAX_SCOPE_SIZE);
71173
 
+}
71174
 
+
71175
 
+static inline void _ext_variables_match_index_error
71176
 
+(struct sieve_validator *valdtr, struct sieve_ast_argument *arg,
71177
 
+       unsigned int variable_index)
71178
 
+{
71179
 
+       sieve_argument_validate_error(valdtr, arg, 
71180
 
+               "match value index %u out of range (max: %u)", variable_index, 
71181
 
+               SIEVE_VARIABLES_MAX_MATCH_INDEX);
71182
 
+}
71183
 
+
71184
 
+/* 
71185
 
+ * Variable argument 
71186
 
+ */
71187
 
+
71188
 
+static bool arg_variable_generate
71189
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, 
71190
 
+               struct sieve_command_context *context);
71191
 
+
71192
 
+const struct sieve_argument variable_argument = { 
71193
 
+       "@variable", 
71194
 
+       NULL, NULL, NULL, NULL,
71195
 
+       arg_variable_generate 
71196
 
+};
71197
 
+
71198
 
+static struct sieve_ast_argument *ext_variables_variable_argument_create
71199
 
+(struct sieve_validator *validator, struct sieve_ast *ast, 
71200
 
+       unsigned int source_line, const char *variable)
71201
 
+{
71202
 
+       struct sieve_variable *var;
71203
 
+       struct sieve_ast_argument *arg;
71204
 
+       
71205
 
+       var = ext_variables_validator_get_variable(validator, variable, TRUE);
71206
 
+
71207
 
+       if ( var == NULL ) 
71208
 
+               return NULL;
71209
 
+       
71210
 
+       arg = sieve_ast_argument_create(ast, source_line);
71211
 
+       arg->type = SAAT_STRING;
71212
 
+       arg->argument = &variable_argument;
71213
 
+       arg->context = (void *) var;
71214
 
+       
71215
 
+       return arg;
71216
 
+}
71217
 
+
71218
 
+static bool _sieve_variable_argument_activate
71219
 
+(struct sieve_validator *validator, struct sieve_command_context *cmd ATTR_UNUSED, 
71220
 
+       struct sieve_ast_argument *arg, bool assignment)
71221
 
+{
71222
 
+       bool result = FALSE;
71223
 
+       struct sieve_variable *var;
71224
 
+       string_t *variable;
71225
 
+       const char *varstr, *varend;
71226
 
+       ARRAY_TYPE(ext_variable_name) vname;    
71227
 
+       int nelements = 0;
71228
 
+
71229
 
+       T_BEGIN {
71230
 
+               t_array_init(&vname, 2);                        
71231
 
+       
71232
 
+               variable = sieve_ast_argument_str(arg);
71233
 
+               varstr = str_c(variable);
71234
 
+               varend = PTR_OFFSET(varstr, str_len(variable));
71235
 
+               nelements = ext_variable_name_parse(&vname, &varstr, varend);
71236
 
+
71237
 
+               /* Check whether name parsing succeeded */      
71238
 
+               if ( nelements < 0 || varstr != varend ) {
71239
 
+                       /* Parse failed */
71240
 
+                       sieve_argument_validate_error(validator, arg, 
71241
 
+                               "invalid variable name '%s'", str_sanitize(str_c(variable),80));
71242
 
+               } else if ( nelements == 1 ) {
71243
 
+                       /* Normal (match) variable */
71244
 
+
71245
 
+                       const struct ext_variable_name *cur_element = 
71246
 
+                               array_idx(&vname, 0);
71247
 
+
71248
 
+                       if ( cur_element->num_variable < 0 ) {
71249
 
+                               /* Variable */
71250
 
+                               var = ext_variables_validator_get_variable
71251
 
+                                       (validator, str_c(cur_element->identifier), TRUE);
71252
 
+
71253
 
+                               if ( var == NULL ) {
71254
 
+                                       _ext_variables_scope_size_error
71255
 
+                                               (validator, arg, str_c(cur_element->identifier));
71256
 
+                               } else {
71257
 
+                                       arg->argument = &variable_argument;
71258
 
+                                       arg->context = (void *) var;
71259
 
+                               
71260
 
+                                       result = TRUE;
71261
 
+                               }
71262
 
+                       } else {
71263
 
+                               /* Match value */
71264
 
+                               if ( !assignment ) {
71265
 
+                                       if ( cur_element->num_variable > SIEVE_VARIABLES_MAX_MATCH_INDEX ) {
71266
 
+                                               _ext_variables_match_index_error
71267
 
+                                                       (validator, arg, cur_element->num_variable);
71268
 
+                                       } else {
71269
 
+                                               arg->argument = &match_value_argument;
71270
 
+                                               arg->context = POINTER_CAST(cur_element->num_variable);
71271
 
+                                                                               
71272
 
+                                               result = TRUE;
71273
 
+                                       }
71274
 
+                               } else {                
71275
 
+                                       sieve_argument_validate_error(validator, arg, 
71276
 
+                                               "cannot assign to match variable");
71277
 
+                               }
71278
 
+                       }
71279
 
+               } else {
71280
 
+                       /* Namespace variable */
71281
 
+
71282
 
+                       const struct ext_variable_name *cur_element = 
71283
 
+                               array_idx(&vname, 0);
71284
 
+
71285
 
+                       /* FIXME: Variable namespaces unsupported. */
71286
 
+       
71287
 
+                       /* References to namespaces without a prior require statement for 
71288
 
+                        * the relevant extension MUST cause an error.
71289
 
+                        */
71290
 
+
71291
 
+                       sieve_argument_validate_error(validator, arg, 
71292
 
+                               "cannot %s to variable in unknown namespace '%s'", 
71293
 
+                               assignment ? "assign" : "refer", str_c(cur_element->identifier));
71294
 
+               }
71295
 
+       } T_END;
71296
 
+
71297
 
+       return result;
71298
 
+}
71299
 
+
71300
 
+bool sieve_variable_argument_activate
71301
 
+(struct sieve_validator *validator, struct sieve_command_context *cmd, 
71302
 
+       struct sieve_ast_argument *arg, bool assignment)
71303
 
+{
71304
 
+       if ( sieve_ast_argument_type(arg) == SAAT_STRING ) {
71305
 
+               /* Single string */
71306
 
+               return _sieve_variable_argument_activate(validator, cmd, arg, assignment);
71307
 
+               
71308
 
+       } else if ( sieve_ast_argument_type(arg) == SAAT_STRING_LIST ) {
71309
 
+               /* String list */
71310
 
+               struct sieve_ast_argument *stritem;
71311
 
+               
71312
 
+               i_assert ( !assignment );
71313
 
+               
71314
 
+               stritem = sieve_ast_strlist_first(arg);
71315
 
+               while ( stritem != NULL ) {
71316
 
+                       if ( !_sieve_variable_argument_activate
71317
 
+                               (validator, cmd, stritem, assignment) )
71318
 
+                               return FALSE;
71319
 
+                       
71320
 
+                       stritem = sieve_ast_strlist_next(stritem);
71321
 
+
71322
 
+               }
71323
 
+               
71324
 
+               arg->argument = &string_list_argument;
71325
 
+               
71326
 
+               return TRUE;
71327
 
+       } 
71328
 
+       
71329
 
+       return FALSE;
71330
 
+}
71331
 
+
71332
 
+static bool arg_variable_generate
71333
 
+(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, 
71334
 
+       struct sieve_command_context *context ATTR_UNUSED)
71335
 
+{
71336
 
+       struct sieve_variable *var = (struct sieve_variable *) arg->context;
71337
 
+       
71338
 
+       ext_variables_opr_variable_emit(cgenv->sbin, var);
71339
 
+
71340
 
+       return TRUE;
71341
 
+}
71342
 
+
71343
 
+/* 
71344
 
+ * Match value argument 
71345
 
+ */
71346
 
+
71347
 
+static bool arg_match_value_generate
71348
 
+(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, 
71349
 
+       struct sieve_command_context *context ATTR_UNUSED);
71350
 
+
71351
 
+const struct sieve_argument match_value_argument = { 
71352
 
+       "@match_value", 
71353
 
+       NULL, NULL, NULL, NULL,
71354
 
+       arg_match_value_generate 
71355
 
+};
71356
 
+
71357
 
+static struct sieve_ast_argument *ext_variables_match_value_argument_create
71358
 
+(struct sieve_validator *validator ATTR_UNUSED, struct sieve_ast *ast, 
71359
 
+       unsigned int source_line,       unsigned int index)
71360
 
+{
71361
 
+       struct sieve_ast_argument *arg;
71362
 
+       
71363
 
+       arg = sieve_ast_argument_create(ast, source_line);
71364
 
+       arg->type = SAAT_STRING;
71365
 
+       arg->argument = &match_value_argument;
71366
 
+       arg->context = POINTER_CAST(index);
71367
 
+       
71368
 
+       return arg;
71369
 
+}
71370
 
+
71371
 
+static bool arg_match_value_generate
71372
 
+(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, 
71373
 
+       struct sieve_command_context *context ATTR_UNUSED)
71374
 
+{
71375
 
+       unsigned int index = POINTER_CAST_TO(arg->context, unsigned int);
71376
 
+       
71377
 
+       ext_variables_opr_match_value_emit(cgenv->sbin, index);
71378
 
+
71379
 
+       return TRUE;
71380
 
+}
71381
 
+
71382
 
+/* 
71383
 
+ * Variable string argument 
71384
 
+ */
71385
 
+
71386
 
+static bool arg_variable_string_validate
71387
 
+       (struct sieve_validator *validator, struct sieve_ast_argument **arg, 
71388
 
+               struct sieve_command_context *context);
71389
 
+
71390
 
+const struct sieve_argument variable_string_argument = { 
71391
 
+       "@variable-string", 
71392
 
+       NULL, NULL,
71393
 
+       arg_variable_string_validate, 
71394
 
+       NULL, 
71395
 
+       sieve_arg_catenated_string_generate,
71396
 
+};
71397
 
+
71398
 
+static bool arg_variable_string_validate
71399
 
+(struct sieve_validator *validator, struct sieve_ast_argument **arg, 
71400
 
+               struct sieve_command_context *cmd)
71401
 
+{
71402
 
+       enum { ST_NONE, ST_OPEN, ST_VARIABLE, ST_CLOSE } state = ST_NONE;
71403
 
+       pool_t pool = sieve_ast_pool((*arg)->ast);
71404
 
+       struct sieve_arg_catenated_string *catstr = NULL;
71405
 
+       string_t *str = sieve_ast_argument_str(*arg);
71406
 
+       const char *p, *strstart, *substart = NULL;
71407
 
+       const char *strval = (const char *) str_data(str);
71408
 
+       const char *strend = strval + str_len(str);
71409
 
+       bool result = TRUE;
71410
 
+
71411
 
+       ARRAY_TYPE(ext_variable_name) substitution;     
71412
 
+       int nelements = 0;
71413
 
+       
71414
 
+       T_BEGIN {
71415
 
+               /* Initialize substitution structure */
71416
 
+               t_array_init(&substitution, 2);         
71417
 
+       
71418
 
+               p = strval;
71419
 
+               strstart = p;
71420
 
+               while ( result && p < strend ) {
71421
 
+                       switch ( state ) {
71422
 
+
71423
 
+                       /* Nothing found yet */
71424
 
+                       case ST_NONE:
71425
 
+                               if ( *p == '$' ) {
71426
 
+                                       substart = p;
71427
 
+                                       state = ST_OPEN;
71428
 
+                               }
71429
 
+                               p++;
71430
 
+                               break;
71431
 
+
71432
 
+                       /* Got '$' */
71433
 
+                       case ST_OPEN:
71434
 
+                               if ( *p == '{' ) {
71435
 
+                                       state = ST_VARIABLE;
71436
 
+                                       p++;
71437
 
+                               } else 
71438
 
+                                       state = ST_NONE;
71439
 
+                               break;
71440
 
+
71441
 
+                       /* Got '${' */ 
71442
 
+                       case ST_VARIABLE:
71443
 
+                               nelements = ext_variable_name_parse(&substitution, &p, strend);
71444
 
+                       
71445
 
+                               if ( nelements < 0 )
71446
 
+                                       state = ST_NONE;
71447
 
+                               else 
71448
 
+                                       state = ST_CLOSE;
71449
 
+                       
71450
 
+                               break;
71451
 
+
71452
 
+                       /* Finished parsing name, expecting '}' */
71453
 
+                       case ST_CLOSE:
71454
 
+                               if ( *p == '}' ) {                              
71455
 
+                                       struct sieve_ast_argument *strarg;
71456
 
+                               
71457
 
+                                       /* We now know that the substitution is valid */        
71458
 
+                                       
71459
 
+                                       if ( catstr == NULL ) {
71460
 
+                                               catstr = sieve_arg_catenated_string_create(*arg);
71461
 
+                                       }
71462
 
+                               
71463
 
+                                       /* Add the substring that is before the substitution to the 
71464
 
+                                        * variable-string AST.
71465
 
+                                        *
71466
 
+                                        * FIXME: For efficiency, if the variable is not found we should 
71467
 
+                                        * coalesce this substring with the one after the substitution.
71468
 
+                                        */
71469
 
+                                       if ( substart > strstart ) {
71470
 
+                                               string_t *newstr = str_new(pool, substart - strstart);
71471
 
+                                               str_append_n(newstr, strstart, substart - strstart); 
71472
 
+                                               
71473
 
+                                               strarg = sieve_ast_argument_string_create_raw
71474
 
+                                                       ((*arg)->ast, newstr, (*arg)->source_line);
71475
 
+                                               sieve_arg_catenated_string_add_element(catstr, strarg);
71476
 
+                                       
71477
 
+                                               /* Give other substitution extensions a chance to do their work */
71478
 
+                                               if ( !sieve_validator_argument_activate_super
71479
 
+                                                       (validator, cmd, strarg, FALSE) ) {
71480
 
+                                                       result = FALSE;
71481
 
+                                                       break;
71482
 
+                                               }
71483
 
+                                       }
71484
 
+                               
71485
 
+                                       /* Find the variable */
71486
 
+                                       if ( nelements == 1 ) {
71487
 
+                                               const struct ext_variable_name *cur_element = 
71488
 
+                                                       array_idx(&substitution, 0);
71489
 
+                                               
71490
 
+                                               if ( cur_element->num_variable == -1 ) {
71491
 
+                                                       /* Add variable argument '${identifier}' */
71492
 
+                                                       string_t *cur_ident = cur_element->identifier; 
71493
 
+                                               
71494
 
+                                                       strarg = ext_variables_variable_argument_create
71495
 
+                                                               (validator, (*arg)->ast, (*arg)->source_line, str_c(cur_ident));
71496
 
+                                                       if ( strarg != NULL )
71497
 
+                                                               sieve_arg_catenated_string_add_element(catstr, strarg);
71498
 
+                                                       else {
71499
 
+                                                               _ext_variables_scope_size_error
71500
 
+                                                                       (validator, *arg, str_c(cur_element->identifier));
71501
 
+                                                               result = FALSE;
71502
 
+                                                               break;
71503
 
+                                                       }
71504
 
+                                               } else {
71505
 
+                                                       /* Add match value argument '${000}' */
71506
 
+                                                       if ( cur_element->num_variable > SIEVE_VARIABLES_MAX_MATCH_INDEX ) {
71507
 
+                                                               _ext_variables_match_index_error
71508
 
+                                                                       (validator, *arg, cur_element->num_variable);
71509
 
+                                                               result = FALSE;
71510
 
+                                                               break;
71511
 
+                                                       }
71512
 
+
71513
 
+                                                       strarg = ext_variables_match_value_argument_create
71514
 
+                                                               (validator, (*arg)->ast, (*arg)->source_line, 
71515
 
+                                                               cur_element->num_variable);
71516
 
+                                                       if ( strarg != NULL )
71517
 
+                                                               sieve_arg_catenated_string_add_element(catstr, strarg);
71518
 
+                                               }
71519
 
+                                       } else {
71520
 
+                                               const struct ext_variable_name *cur_element = 
71521
 
+                                                       array_idx(&substitution, 0);
71522
 
+
71523
 
+                                               /* FIXME: Namespaces are not supported. */
71524
 
+
71525
 
+                                               /* References to namespaces without a prior require 
71526
 
+                                                * statement for thecrelevant extension MUST cause an error.
71527
 
+                                                */
71528
 
+                                               sieve_argument_validate_error(validator, *arg, 
71529
 
+                                                       "referring to variable in unknown namespace '%s'", 
71530
 
+                                                       str_c(cur_element->identifier));
71531
 
+                                               result = FALSE;
71532
 
+                                               break;
71533
 
+                                       }
71534
 
+                               
71535
 
+                                       strstart = p + 1;
71536
 
+                                       substart = strstart;
71537
 
+
71538
 
+                                       p++;    
71539
 
+                               }
71540
 
+               
71541
 
+                               /* Finished, reset for the next substitution */ 
71542
 
+                               state = ST_NONE;
71543
 
+                       }
71544
 
+               }
71545
 
+       } T_END;
71546
 
+
71547
 
+       /* Bail out early if substitution is invalid */
71548
 
+       if ( !result ) return FALSE;
71549
 
+       
71550
 
+       /* Check whether any substitutions were found */
71551
 
+       if ( catstr == NULL ) {
71552
 
+               /* No substitutions in this string, pass it on to any other substution
71553
 
+                * extension.
71554
 
+                */
71555
 
+               return sieve_validator_argument_activate_super(validator, cmd, *arg, TRUE);
71556
 
+       }
71557
 
+       
71558
 
+       /* Add the final substring that comes after the last substitution to the 
71559
 
+        * variable-string AST.
71560
 
+        */
71561
 
+       if ( strend > strstart ) {
71562
 
+               struct sieve_ast_argument *strarg;
71563
 
+               string_t *newstr = str_new(pool, strend - strstart);
71564
 
+               str_append_n(newstr, strstart, strend - strstart); 
71565
 
+
71566
 
+               strarg = sieve_ast_argument_string_create_raw
71567
 
+                       ((*arg)->ast, newstr, (*arg)->source_line);
71568
 
+               sieve_arg_catenated_string_add_element(catstr, strarg);
71569
 
+                       
71570
 
+               /* Give other substitution extensions a chance to do their work */      
71571
 
+               if ( !sieve_validator_argument_activate_super
71572
 
+                       (validator, cmd, strarg, FALSE) )
71573
 
+                       return FALSE;
71574
 
+       }       
71575
 
+       
71576
 
+       return TRUE;
71577
 
+}
71578
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/variables/ext-variables-arguments.h dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/variables/ext-variables-arguments.h
71579
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/variables/ext-variables-arguments.h    1970-01-01 01:00:00.000000000 +0100
71580
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/variables/ext-variables-arguments.h     2009-01-06 00:15:52.000000000 +0100
71581
 
@@ -0,0 +1,27 @@
71582
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
71583
 
+ */
71584
 
+
71585
 
+#ifndef __EXT_VARIABLES_ARGUMENTS_H
71586
 
+#define __EXT_VARIABLES_ARGUMENTS_H
71587
 
+
71588
 
+#include "sieve-common.h"
71589
 
+
71590
 
+/* 
71591
 
+ * Variable argument 
71592
 
+ */
71593
 
+
71594
 
+extern const struct sieve_argument variable_argument;
71595
 
+
71596
 
+/* 
71597
 
+ * Match value argument 
71598
 
+ */
71599
 
+
71600
 
+extern const struct sieve_argument match_value_argument;
71601
 
+
71602
 
+/* 
71603
 
+ * Variable string argument 
71604
 
+ */
71605
 
+
71606
 
+extern const struct sieve_argument variable_string_argument;
71607
 
+
71608
 
+#endif /* __EXT_VARIABLES_ARGUMENTS_H */
71609
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/variables/ext-variables.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/variables/ext-variables.c
71610
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/variables/ext-variables.c      1970-01-01 01:00:00.000000000 +0100
71611
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/variables/ext-variables.c       2009-01-06 00:15:52.000000000 +0100
71612
 
@@ -0,0 +1,90 @@
71613
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
71614
 
+ */
71615
 
+
71616
 
+/* Extension variables 
71617
 
+ * -------------------
71618
 
+ *
71619
 
+ * Authors: Stephan Bosch
71620
 
+ * Specification: RFC 5229
71621
 
+ * Implementation: mostly full; no support for future namespaces
71622
 
+ * Status: experimental, not thoroughly tested
71623
 
+ *
71624
 
+ */
71625
 
71626
 
+/* FIXME: This implementation of the variables extension does not support 
71627
 
+ * namespaces. It recognizes them, but there is currently no support to let
71628
 
+ * an extension register a new namespace. Currently no such extension exists 
71629
 
+ * and therefore this support has a very low implementation priority.
71630
 
+ */
71631
 
+
71632
 
+#include "lib.h"
71633
 
+#include "str.h"
71634
 
+#include "unichar.h"
71635
 
+
71636
 
+#include "sieve-extensions.h"
71637
 
+#include "sieve-commands.h"
71638
 
+#include "sieve-binary.h"
71639
 
+#include "sieve-interpreter.h"
71640
 
+
71641
 
+#include "sieve-validator.h"
71642
 
+
71643
 
+#include "ext-variables-common.h"
71644
 
+#include "ext-variables-arguments.h"
71645
 
+#include "ext-variables-operands.h"
71646
 
+#include "ext-variables-modifiers.h"
71647
 
+#include "ext-variables-dump.h"
71648
 
+
71649
 
+/* 
71650
 
+ * Operations 
71651
 
+ */
71652
 
+
71653
 
+const struct sieve_operation *ext_variables_operations[] = {
71654
 
+       &cmd_set_operation, 
71655
 
+       &tst_string_operation
71656
 
+};
71657
 
+
71658
 
+/* 
71659
 
+ * Operands 
71660
 
+ */
71661
 
+
71662
 
+const struct sieve_operand *ext_variables_operands[] = {
71663
 
+       &variable_operand, 
71664
 
+       &match_value_operand,
71665
 
+       &modifier_operand
71666
 
+};
71667
 
+
71668
 
+/* 
71669
 
+ * Extension 
71670
 
+ */
71671
 
+
71672
 
+static bool ext_variables_validator_load(struct sieve_validator *validator);
71673
 
+
71674
 
+static int ext_my_id = -1;
71675
 
+       
71676
 
+const struct sieve_extension variables_extension = { 
71677
 
+       "variables", 
71678
 
+       &ext_my_id,
71679
 
+       NULL, NULL,
71680
 
+       ext_variables_validator_load, 
71681
 
+       ext_variables_generator_load,
71682
 
+       ext_variables_interpreter_load,
71683
 
+       NULL, NULL, 
71684
 
+       ext_variables_code_dump,
71685
 
+       SIEVE_EXT_DEFINE_OPERATIONS(ext_variables_operations), 
71686
 
+       SIEVE_EXT_DEFINE_OPERANDS(ext_variables_operands)
71687
 
+};
71688
 
+
71689
 
+static bool ext_variables_validator_load
71690
 
+       (struct sieve_validator *validator)
71691
 
+{
71692
 
+       sieve_validator_argument_override(validator, SAT_VAR_STRING, 
71693
 
+               &variable_string_argument); 
71694
 
+               
71695
 
+       sieve_validator_register_command(validator, &cmd_set);
71696
 
+       sieve_validator_register_command(validator, &tst_string);
71697
 
+       
71698
 
+       ext_variables_validator_initialize(validator);
71699
 
+
71700
 
+       return TRUE;
71701
 
+}
71702
 
+
71703
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/variables/ext-variables-common.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/variables/ext-variables-common.c
71704
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/variables/ext-variables-common.c       1970-01-01 01:00:00.000000000 +0100
71705
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/variables/ext-variables-common.c        2009-01-06 00:15:52.000000000 +0100
71706
 
@@ -0,0 +1,567 @@
71707
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
71708
 
+ */
71709
 
+
71710
 
+#include "lib.h"
71711
 
+#include "hash.h"
71712
 
+#include "str.h"
71713
 
+#include "array.h"
71714
 
+
71715
 
+#include "sieve-common.h"
71716
 
+
71717
 
+#include "sieve-ast.h"
71718
 
+#include "sieve-binary.h"
71719
 
+#include "sieve-code.h"
71720
 
+#include "sieve-objects.h"
71721
 
+#include "sieve-match-types.h"
71722
 
+
71723
 
+#include "sieve-commands.h"
71724
 
+#include "sieve-validator.h"
71725
 
+#include "sieve-generator.h"
71726
 
+#include "sieve-dump.h"
71727
 
+#include "sieve-interpreter.h"
71728
 
+
71729
 
+#include "ext-variables-common.h"
71730
 
+#include "ext-variables-name.h"
71731
 
+#include "ext-variables-modifiers.h"
71732
 
+
71733
 
+/*
71734
 
+ * Variable scope 
71735
 
+ */
71736
 
+
71737
 
+struct sieve_variable_scope {
71738
 
+       pool_t pool;
71739
 
+       int refcount;
71740
 
+
71741
 
+       struct sieve_variable *error_var;
71742
 
+
71743
 
+       const struct sieve_extension *ext;
71744
 
+
71745
 
+       struct hash_table *variables;
71746
 
+       ARRAY_DEFINE(variable_index, struct sieve_variable *);
71747
 
+};
71748
 
+
71749
 
+struct sieve_variable_scope_iter {
71750
 
+       struct sieve_variable_scope *scope;
71751
 
+       struct hash_iterate_context *hctx;
71752
 
+};
71753
 
+
71754
 
+struct sieve_variable_scope *sieve_variable_scope_create
71755
 
+       (const struct sieve_extension *ext) 
71756
 
+{
71757
 
+       struct sieve_variable_scope *scope;
71758
 
+       pool_t pool;
71759
 
+
71760
 
+       pool = pool_alloconly_create("sieve_variable_scope", 4096);
71761
 
+       scope = p_new(pool, struct sieve_variable_scope, 1);
71762
 
+       scope->pool = pool;
71763
 
+       scope->refcount = 1;
71764
 
+
71765
 
+       scope->ext = ext;
71766
 
+       scope->variables = hash_table_create
71767
 
+               (default_pool, pool, 0, strcase_hash, (hash_cmp_callback_t *)strcasecmp);
71768
 
+       p_array_init(&scope->variable_index, pool, 128);
71769
 
+               
71770
 
+       return scope;
71771
 
+}
71772
 
+
71773
 
+void sieve_variable_scope_ref(struct sieve_variable_scope *scope)
71774
 
+{
71775
 
+       scope->refcount++;
71776
 
+}
71777
 
+
71778
 
+void sieve_variable_scope_unref(struct sieve_variable_scope **scope)
71779
 
+{
71780
 
+       i_assert((*scope)->refcount > 0);
71781
 
+
71782
 
+       if (--(*scope)->refcount != 0)
71783
 
+               return;
71784
 
+
71785
 
+       hash_table_destroy(&(*scope)->variables);
71786
 
+
71787
 
+       pool_unref(&(*scope)->pool);
71788
 
+    *scope = NULL;
71789
 
+}
71790
 
+
71791
 
+pool_t sieve_variable_scope_pool(struct sieve_variable_scope *scope)
71792
 
+{
71793
 
+       return scope->pool;
71794
 
+}
71795
 
+
71796
 
+struct sieve_variable *sieve_variable_scope_declare
71797
 
+(struct sieve_variable_scope *scope, const char *identifier)
71798
 
+{
71799
 
+       struct sieve_variable *new_var;
71800
 
+
71801
 
+       new_var = p_new(scope->pool, struct sieve_variable, 1);
71802
 
+       new_var->ext = scope->ext;
71803
 
+
71804
 
+       if ( array_count(&scope->variable_index) >= SIEVE_VARIABLES_MAX_SCOPE_SIZE ) {
71805
 
+               if ( scope->error_var == NULL ) {
71806
 
+                       new_var->identifier = "@ERROR@";
71807
 
+                       new_var->index = 0;
71808
 
+                       
71809
 
+                       scope->error_var = new_var;
71810
 
+                       return NULL;
71811
 
+               }
71812
 
+
71813
 
+               return scope->error_var;
71814
 
+       }
71815
 
+       
71816
 
+       new_var->identifier = p_strdup(scope->pool, identifier);
71817
 
+       new_var->index = array_count(&scope->variable_index);
71818
 
+
71819
 
+       hash_table_insert(scope->variables, (void *) new_var->identifier, (void *) new_var);
71820
 
+       array_append(&scope->variable_index, &new_var, 1);
71821
 
+       
71822
 
+       return new_var;
71823
 
+}
71824
 
+
71825
 
+struct sieve_variable *sieve_variable_scope_get_variable
71826
 
+(struct sieve_variable_scope *scope, const char *identifier, bool declare)
71827
 
+{
71828
 
+       struct sieve_variable *var = 
71829
 
+               (struct sieve_variable *) hash_table_lookup(scope->variables, identifier);
71830
 
+
71831
 
+       if ( var == NULL && declare ) {
71832
 
+               var = sieve_variable_scope_declare(scope, identifier);
71833
 
+       }
71834
 
+
71835
 
+       return var;
71836
 
+}
71837
 
+
71838
 
+struct sieve_variable *sieve_variable_scope_import
71839
 
+(struct sieve_variable_scope *scope, struct sieve_variable *var)
71840
 
+{
71841
 
+       struct sieve_variable *new_var = p_new(scope->pool, struct sieve_variable, 1);
71842
 
+       memcpy(new_var, var, sizeof(struct sieve_variable));
71843
 
+               
71844
 
+       hash_table_insert(scope->variables, (void *) new_var->identifier, (void *) new_var);
71845
 
+       
71846
 
+       /* Not entered into the index because it is an external variable 
71847
 
+        * (This can be done unlimited; only limited by the size of the external scope)
71848
 
+        */
71849
 
+
71850
 
+       return new_var;
71851
 
+}
71852
 
+
71853
 
+struct sieve_variable_scope_iter *sieve_variable_scope_iterate_init
71854
 
+(struct sieve_variable_scope *scope)
71855
 
+{
71856
 
+       struct sieve_variable_scope_iter *iter = t_new(struct sieve_variable_scope_iter, 1);
71857
 
+       iter->scope = scope;
71858
 
+       iter->hctx = hash_table_iterate_init(scope->variables);
71859
 
+
71860
 
+       return iter;
71861
 
+}
71862
 
+
71863
 
+bool sieve_variable_scope_iterate
71864
 
+(struct sieve_variable_scope_iter *iter, struct sieve_variable **var_r)
71865
 
+{
71866
 
+       void *key, *value;
71867
 
+
71868
 
+       if ( !hash_table_iterate(iter->hctx, &key, &value) )
71869
 
+               return FALSE; 
71870
 
+       
71871
 
+       *var_r = (struct sieve_variable *) value;
71872
 
+       return TRUE;
71873
 
+}
71874
 
+
71875
 
+void sieve_variable_scope_iterate_deinit
71876
 
+(struct sieve_variable_scope_iter **iter)
71877
 
+{
71878
 
+       hash_table_iterate_deinit(&(*iter)->hctx);
71879
 
+       *iter = NULL;
71880
 
+}
71881
 
+
71882
 
+unsigned int sieve_variable_scope_declarations
71883
 
+(struct sieve_variable_scope *scope)
71884
 
+{
71885
 
+       return hash_table_count(scope->variables);
71886
 
+}
71887
 
+
71888
 
+unsigned int sieve_variable_scope_size
71889
 
+(struct sieve_variable_scope *scope)
71890
 
+{
71891
 
+       return array_count(&scope->variable_index);
71892
 
+}
71893
 
+
71894
 
+struct sieve_variable * const *sieve_variable_scope_get_variables
71895
 
+(struct sieve_variable_scope *scope, unsigned int *size_r)
71896
 
+{
71897
 
+       return array_get(&scope->variable_index, size_r);
71898
 
+}
71899
 
+
71900
 
+struct sieve_variable *sieve_variable_scope_get_indexed
71901
 
+(struct sieve_variable_scope *scope, unsigned int index)
71902
 
+{
71903
 
+       struct sieve_variable * const *var;
71904
 
+       
71905
 
+       if ( index >= array_count(&scope->variable_index) ) 
71906
 
+               return NULL;
71907
 
+               
71908
 
+       var = array_idx(&scope->variable_index, index); 
71909
 
+       
71910
 
+       return *var;
71911
 
+}
71912
 
+
71913
 
+/* 
71914
 
+ * Variable storage 
71915
 
+ */
71916
 
+
71917
 
+struct sieve_variable_storage {
71918
 
+       pool_t pool;
71919
 
+       struct sieve_variable_scope *scope;
71920
 
+       unsigned int max_size;
71921
 
+       ARRAY_DEFINE(var_values, string_t *); 
71922
 
+};
71923
 
+
71924
 
+struct sieve_variable_storage *sieve_variable_storage_create
71925
 
+(pool_t pool, struct sieve_variable_scope *scope, unsigned int max_size)
71926
 
+{
71927
 
+       struct sieve_variable_storage *storage;
71928
 
+       
71929
 
+       storage = p_new(pool, struct sieve_variable_storage, 1);
71930
 
+       storage->pool = pool;
71931
 
+       storage->scope = scope;
71932
 
+       
71933
 
+       if ( scope != NULL )
71934
 
+               storage->max_size = sieve_variable_scope_size(scope);
71935
 
+       else
71936
 
+               storage->max_size = max_size;
71937
 
+               
71938
 
+       p_array_init(&storage->var_values, pool, 4);
71939
 
+
71940
 
+       return storage;
71941
 
+}
71942
 
+
71943
 
+static inline bool sieve_variable_valid
71944
 
+(struct sieve_variable_storage *storage, unsigned int index)
71945
 
+{
71946
 
+       if ( storage->scope == NULL ) return TRUE;
71947
 
+
71948
 
+       return ( index < storage->max_size );
71949
 
+}
71950
 
+
71951
 
+bool sieve_variable_get_identifier
71952
 
+(struct sieve_variable_storage *storage, unsigned int index, const char **identifier)
71953
 
+{
71954
 
+       struct sieve_variable * const *var;
71955
 
+       *identifier = NULL;
71956
 
+
71957
 
+       if ( storage->scope == NULL ) return TRUE;
71958
 
+
71959
 
+       /* FIXME: direct invasion of the scope object is a bit ugly */
71960
 
+       if ( index >= array_count(&storage->scope->variable_index) )
71961
 
+               return FALSE;
71962
 
+
71963
 
+       var = array_idx(&storage->scope->variable_index, index);
71964
 
+
71965
 
+       if ( *var != NULL )
71966
 
+               *identifier = (*var)->identifier;
71967
 
+
71968
 
+       return TRUE;
71969
 
+}
71970
 
+
71971
 
+bool sieve_variable_get
71972
 
+(struct sieve_variable_storage *storage, unsigned int index, string_t **value)
71973
 
+{
71974
 
+       *value = NULL;
71975
 
+       
71976
 
+       if  ( index < array_count(&storage->var_values) ) {
71977
 
+               string_t * const *varent;
71978
 
+                       
71979
 
+               varent = array_idx(&storage->var_values, index);
71980
 
+               
71981
 
+               *value = *varent;
71982
 
+       } else if ( !sieve_variable_valid(storage, index) )
71983
 
+               return FALSE;
71984
 
+
71985
 
+       return TRUE;
71986
 
+} 
71987
 
+
71988
 
+bool sieve_variable_get_modifiable
71989
 
+(struct sieve_variable_storage *storage, unsigned int index, string_t **value)
71990
 
+{
71991
 
+       string_t *dummy;
71992
 
+       
71993
 
+       if ( value == NULL ) value = &dummy;
71994
 
+       
71995
 
+       if ( !sieve_variable_get(storage, index, value) )
71996
 
+               return FALSE;
71997
 
+       
71998
 
+       if ( *value == NULL ) {
71999
 
+               *value = str_new(storage->pool, 256);
72000
 
+               array_idx_set(&storage->var_values, index, value);      
72001
 
+       }
72002
 
+
72003
 
+       return TRUE; 
72004
 
+}
72005
 
+
72006
 
+bool sieve_variable_assign
72007
 
+(struct sieve_variable_storage *storage, unsigned int index, 
72008
 
+       const string_t *value)
72009
 
+{
72010
 
+       string_t *varval;
72011
 
+       
72012
 
+       if ( !sieve_variable_get_modifiable(storage, index, &varval) ) 
72013
 
+               return FALSE;
72014
 
+
72015
 
+       str_truncate(varval, 0);
72016
 
+       str_append_str(varval, value);
72017
 
+
72018
 
+       /* Just a precaution, caller should prevent this in the first place */
72019
 
+       if ( str_len(varval) > SIEVE_VARIABLES_MAX_VARIABLE_SIZE )
72020
 
+               str_truncate(varval, SIEVE_VARIABLES_MAX_VARIABLE_SIZE);
72021
 
+
72022
 
+       return TRUE;
72023
 
+}
72024
 
+
72025
 
+/*
72026
 
+ * AST Context
72027
 
+ */
72028
 
+
72029
 
+static void ext_variables_ast_free
72030
 
+(struct sieve_ast *ast ATTR_UNUSED, void *context)
72031
 
+{
72032
 
+       struct sieve_variable_scope *main_scope =
72033
 
+               (struct sieve_variable_scope *) context;
72034
 
+
72035
 
+       /* Unreference main variable scope */
72036
 
+       sieve_variable_scope_unref(&main_scope);
72037
 
+}
72038
 
+
72039
 
+static const struct sieve_ast_extension variables_ast_extension = {
72040
 
+    &variables_extension,
72041
 
+    ext_variables_ast_free
72042
 
+};
72043
 
+
72044
 
+static struct sieve_variable_scope *ext_variables_create_main_scope
72045
 
+(struct sieve_ast *ast)
72046
 
+{
72047
 
+       struct sieve_variable_scope *scope;
72048
 
+
72049
 
+       scope = sieve_variable_scope_create(NULL);
72050
 
+
72051
 
+       sieve_ast_extension_register(ast, &variables_ast_extension, (void *) scope);
72052
 
+
72053
 
+       return scope;
72054
 
+}
72055
 
+
72056
 
+static struct sieve_variable_scope *ext_variables_ast_get_main_scope
72057
 
+(struct sieve_ast *ast)
72058
 
+{
72059
 
+       struct sieve_variable_scope *main_scope =
72060
 
+               (struct sieve_variable_scope *) sieve_ast_extension_get_context
72061
 
+               (ast, &variables_extension);
72062
 
+       
72063
 
+       return main_scope;
72064
 
+}
72065
 
+
72066
 
+/*
72067
 
+ * Validator context 
72068
 
+ */
72069
 
+
72070
 
+static struct ext_variables_validator_context *
72071
 
+ext_variables_validator_context_create(struct sieve_validator *valdtr)
72072
 
+{              
72073
 
+       pool_t pool = sieve_validator_pool(valdtr);
72074
 
+       struct ext_variables_validator_context *ctx;
72075
 
+       struct sieve_ast *ast = sieve_validator_ast(valdtr);
72076
 
+       
72077
 
+       ctx = p_new(pool, struct ext_variables_validator_context, 1);
72078
 
+       ctx->modifiers = sieve_validator_object_registry_create(valdtr);
72079
 
+       ctx->main_scope = ext_variables_create_main_scope(ast);
72080
 
+
72081
 
+       sieve_validator_extension_set_context
72082
 
+               (valdtr, &variables_extension, (void *) ctx);
72083
 
+
72084
 
+       return ctx;
72085
 
+}
72086
 
+
72087
 
+struct ext_variables_validator_context *ext_variables_validator_context_get
72088
 
+(struct sieve_validator *valdtr)
72089
 
+{
72090
 
+       struct ext_variables_validator_context *ctx = 
72091
 
+               (struct ext_variables_validator_context *)
72092
 
+               sieve_validator_extension_get_context(valdtr, &variables_extension);
72093
 
+       
72094
 
+       if ( ctx == NULL ) {
72095
 
+               ctx = ext_variables_validator_context_create(valdtr);
72096
 
+       }
72097
 
+       
72098
 
+       return ctx;
72099
 
+}
72100
 
+
72101
 
+void ext_variables_validator_initialize(struct sieve_validator *validator)
72102
 
+{
72103
 
+       struct ext_variables_validator_context *ctx;
72104
 
+       
72105
 
+       /* Create our context */
72106
 
+       ctx = ext_variables_validator_context_get(validator);
72107
 
+       
72108
 
+       ext_variables_register_core_modifiers(ctx);
72109
 
+       
72110
 
+       ctx->active = TRUE;
72111
 
+}
72112
 
+
72113
 
+struct sieve_variable *ext_variables_validator_get_variable
72114
 
+(struct sieve_validator *validator, const char *variable, bool declare)
72115
 
+{
72116
 
+       struct ext_variables_validator_context *ctx = 
72117
 
+               ext_variables_validator_context_get(validator);
72118
 
+               
72119
 
+       return sieve_variable_scope_get_variable(ctx->main_scope, variable, declare);
72120
 
+}
72121
 
+
72122
 
+struct sieve_variable_scope *sieve_ext_variables_get_main_scope
72123
 
+(struct sieve_validator *validator)
72124
 
+{
72125
 
+       struct ext_variables_validator_context *ctx = 
72126
 
+               ext_variables_validator_context_get(validator);
72127
 
+               
72128
 
+       return ctx->main_scope;
72129
 
+}
72130
 
+
72131
 
+bool sieve_ext_variables_is_active(struct sieve_validator *valdtr)
72132
 
+{
72133
 
+       struct ext_variables_validator_context *ctx = 
72134
 
+               ext_variables_validator_context_get(valdtr);
72135
 
+               
72136
 
+       return ( ctx != NULL && ctx->active );
72137
 
+}
72138
 
+
72139
 
+/*
72140
 
+ * Code generation
72141
 
+ */
72142
 
72143
 
+bool ext_variables_generator_load(const struct sieve_codegen_env *cgenv)
72144
 
+{
72145
 
+       struct sieve_variable_scope *main_scope = 
72146
 
+               ext_variables_ast_get_main_scope(cgenv->ast);
72147
 
+       unsigned int count = sieve_variable_scope_size(main_scope);
72148
 
+       sieve_size_t jump;
72149
 
+
72150
 
+       sieve_binary_emit_unsigned(cgenv->sbin, count);
72151
 
+
72152
 
+       jump = sieve_binary_emit_offset(cgenv->sbin, 0);
72153
 
+
72154
 
+       if ( count > 0 ) {
72155
 
+               unsigned int size, i;
72156
 
+               struct sieve_variable *const *vars = 
72157
 
+                       sieve_variable_scope_get_variables(main_scope, &size);
72158
 
+
72159
 
+               for ( i = 0; i < size; i++ ) {                  
72160
 
+                       sieve_binary_emit_cstring(cgenv->sbin, vars[i]->identifier);
72161
 
+               }
72162
 
+       }
72163
 
+       
72164
 
+       sieve_binary_resolve_offset(cgenv->sbin, jump);
72165
 
+               
72166
 
+       return TRUE;
72167
 
+}
72168
 
+
72169
 
+/* 
72170
 
+ * Interpreter context 
72171
 
+ */
72172
 
+
72173
 
+struct ext_variables_interpreter_context {
72174
 
+       struct sieve_variable_storage *local_storage;
72175
 
+       ARRAY_DEFINE(ext_storages, struct sieve_variable_storage *);
72176
 
+};
72177
 
+
72178
 
+static struct ext_variables_interpreter_context *
72179
 
+ext_variables_interpreter_context_create
72180
 
+(struct sieve_interpreter *interp, unsigned int max_size)
72181
 
+{              
72182
 
+       pool_t pool = sieve_interpreter_pool(interp);
72183
 
+       struct ext_variables_interpreter_context *ctx;
72184
 
+       
72185
 
+       ctx = p_new(pool, struct ext_variables_interpreter_context, 1);
72186
 
+       ctx->local_storage = sieve_variable_storage_create(pool, NULL, max_size);
72187
 
+       p_array_init(&ctx->ext_storages, pool, sieve_extensions_get_count());
72188
 
+
72189
 
+       sieve_interpreter_extension_set_context
72190
 
+               (interp, &variables_extension, (void *) ctx);
72191
 
+
72192
 
+       return ctx;
72193
 
+}
72194
 
+
72195
 
+bool ext_variables_interpreter_load
72196
 
+       (const struct sieve_runtime_env *renv, sieve_size_t *address)
72197
 
+{
72198
 
+       struct ext_variables_interpreter_context *ctx;
72199
 
+       unsigned int scope_size;
72200
 
+       sieve_size_t pc;
72201
 
+       int end_offset;
72202
 
+               
72203
 
+       if ( !sieve_binary_read_unsigned(renv->sbin, address, &scope_size) ) {
72204
 
+               sieve_sys_error("variables: failed to read main scope size");
72205
 
+               return FALSE;
72206
 
+       }
72207
 
+
72208
 
+       if ( scope_size > SIEVE_VARIABLES_MAX_SCOPE_SIZE ) {
72209
 
+               sieve_sys_error("variables: scope size exceeds the limit (%u > %u)", 
72210
 
+                       scope_size, SIEVE_VARIABLES_MAX_SCOPE_SIZE );
72211
 
+               return FALSE;
72212
 
+       }
72213
 
+       
72214
 
+       pc = *address;
72215
 
+       if ( !sieve_binary_read_offset(renv->sbin, address, &end_offset) )
72216
 
+               return NULL;
72217
 
+       *address = pc + end_offset;
72218
 
+       
72219
 
+       /* Create our context */
72220
 
+       ctx = ext_variables_interpreter_context_create(renv->interp, scope_size);
72221
 
+
72222
 
+       /* Enable support for match values */
72223
 
+       (void) sieve_match_values_set_enabled(renv->interp, TRUE);
72224
 
+       
72225
 
+       return TRUE;
72226
 
+}
72227
 
+
72228
 
+static inline struct ext_variables_interpreter_context *
72229
 
+ext_variables_interpreter_context_get(struct sieve_interpreter *interp)
72230
 
+{
72231
 
+       return (struct ext_variables_interpreter_context *)
72232
 
+               sieve_interpreter_extension_get_context(interp, &variables_extension);
72233
 
+}
72234
 
+
72235
 
+struct sieve_variable_storage *sieve_ext_variables_get_storage
72236
 
+(struct sieve_interpreter *interp, const struct sieve_extension *ext)
72237
 
+{
72238
 
+       struct ext_variables_interpreter_context *ctx = 
72239
 
+               ext_variables_interpreter_context_get(interp);
72240
 
+       struct sieve_variable_storage * const *storage;
72241
 
+       int ext_id;
72242
 
+               
72243
 
+       if ( ext == NULL )
72244
 
+               return ctx->local_storage;
72245
 
+
72246
 
+       ext_id = SIEVE_EXT_ID(ext);
72247
 
+       if ( ext_id >= (int) array_count(&ctx->ext_storages) ) {
72248
 
+               storage = NULL;
72249
 
+       } else {
72250
 
+               storage = array_idx(&ctx->ext_storages, ext_id);
72251
 
+       }
72252
 
+       
72253
 
+       if ( storage == NULL || *storage == NULL ) 
72254
 
+               return NULL;
72255
 
+       
72256
 
+       return *storage;
72257
 
+}
72258
 
+
72259
 
+void sieve_ext_variables_set_storage
72260
 
+(struct sieve_interpreter *interp, struct sieve_variable_storage *storage,
72261
 
+       const struct sieve_extension *ext)
72262
 
+{
72263
 
+       struct ext_variables_interpreter_context *ctx = 
72264
 
+               ext_variables_interpreter_context_get(interp);
72265
 
+               
72266
 
+       if ( ctx == NULL || ext == NULL || storage == NULL )
72267
 
+               return;
72268
 
+               
72269
 
+       array_idx_set(&ctx->ext_storages, (unsigned int) SIEVE_EXT_ID(ext), &storage);
72270
 
+}
72271
 
+
72272
 
+
72273
 
+
72274
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/variables/ext-variables-common.h dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/variables/ext-variables-common.h
72275
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/variables/ext-variables-common.h       1970-01-01 01:00:00.000000000 +0100
72276
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/variables/ext-variables-common.h        2009-01-06 00:15:52.000000000 +0100
72277
 
@@ -0,0 +1,100 @@
72278
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
72279
 
+ */
72280
 
+
72281
 
+#ifndef __EXT_VARIABLES_COMMON_H
72282
 
+#define __EXT_VARIABLES_COMMON_H
72283
 
+
72284
 
+#include "sieve-common.h"
72285
 
+#include "sieve-validator.h"
72286
 
+
72287
 
+#include "sieve-ext-variables.h"
72288
 
+
72289
 
+/*
72290
 
+ * Extension
72291
 
+ */
72292
 
+
72293
 
+extern const struct sieve_extension variables_extension;
72294
 
+
72295
 
+/* 
72296
 
+ * Commands 
72297
 
+ */
72298
 
+
72299
 
+extern const struct sieve_command cmd_set;
72300
 
+extern const struct sieve_command tst_string;
72301
 
+
72302
 
+/* 
72303
 
+ * Operands
72304
 
+ */
72305
 
+
72306
 
+enum ext_variables_operand {
72307
 
+       EXT_VARIABLES_OPERAND_VARIABLE,
72308
 
+       EXT_VARIABLES_OPERAND_MATCH_VALUE,
72309
 
+       EXT_VARIABLES_OPERAND_MODIFIER
72310
 
+};
72311
 
+
72312
 
+/*
72313
 
+ * Operations
72314
 
+ */
72315
 
+
72316
 
+extern const struct sieve_operation cmd_set_operation;
72317
 
+extern const struct sieve_operation tst_string_operation;
72318
 
+
72319
 
+enum ext_variables_opcode {
72320
 
+       EXT_VARIABLES_OPERATION_SET,
72321
 
+       EXT_VARIABLES_OPERATION_STRING
72322
 
+};
72323
 
+
72324
 
+/* 
72325
 
+ * Validator context 
72326
 
+ */
72327
 
+
72328
 
+struct ext_variables_validator_context {
72329
 
+       bool active;
72330
 
+       
72331
 
+       struct sieve_validator_object_registry *modifiers;
72332
 
+       
72333
 
+       struct sieve_variable_scope *main_scope;
72334
 
+};
72335
 
+
72336
 
+void ext_variables_validator_initialize(struct sieve_validator *validator);
72337
 
+       
72338
 
+struct ext_variables_validator_context *ext_variables_validator_context_get
72339
 
+       (struct sieve_validator *valdtr);
72340
 
+
72341
 
+struct sieve_variable *ext_variables_validator_get_variable
72342
 
+       (struct sieve_validator *validator, const char *variable, bool declare);
72343
 
+
72344
 
+/*
72345
 
+ * Code generation
72346
 
+ */
72347
 
72348
 
+bool ext_variables_generator_load
72349
 
+       (const struct sieve_codegen_env *cgenv);
72350
 
+
72351
 
+/*
72352
 
+ * Interpreter context
72353
 
+ */    
72354
 
+
72355
 
+bool ext_variables_interpreter_load
72356
 
+(const struct sieve_runtime_env *renv, sieve_size_t *address);
72357
 
+
72358
 
+/* 
72359
 
+ * Variable coding 
72360
 
+ */
72361
 
+
72362
 
+void ext_variables_opr_variable_emit
72363
 
+       (struct sieve_binary *sbin, struct sieve_variable *var);
72364
 
+void ext_variables_opr_match_value_emit
72365
 
+       (struct sieve_binary *sbin, unsigned int index);
72366
 
+bool ext_variables_opr_variable_read
72367
 
+       (const struct sieve_runtime_env *renv, sieve_size_t *address, 
72368
 
+               struct sieve_variable_storage **storage, unsigned int *var_index);
72369
 
+
72370
 
+void ext_variables_opr_variable_string_emit
72371
 
+       (struct sieve_binary *sbin, unsigned int elements);
72372
 
+
72373
 
+bool ext_variables_variable_assignment_activate
72374
 
+(struct sieve_validator *validator, struct sieve_ast_argument *arg,
72375
 
+       struct sieve_command_context *cmd);
72376
 
+       
72377
 
+#endif /* __EXT_VARIABLES_COMMON_H */
72378
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/variables/ext-variables-dump.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/variables/ext-variables-dump.c
72379
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/variables/ext-variables-dump.c 1970-01-01 01:00:00.000000000 +0100
72380
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/variables/ext-variables-dump.c  2009-01-06 00:15:52.000000000 +0100
72381
 
@@ -0,0 +1,156 @@
72382
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
72383
 
+ */
72384
 
72385
 
+#include "lib.h"
72386
 
+#include "str.h"
72387
 
72388
 
+#include "sieve-common.h"
72389
 
+#include "sieve-dump.h"
72390
 
+#include "sieve-binary.h"
72391
 
+#include "sieve-code.h"
72392
 
+
72393
 
+#include "ext-variables-common.h"
72394
 
+#include "ext-variables-dump.h"
72395
 
+
72396
 
+/*
72397
 
+ * Code dumper extension
72398
 
+ */
72399
 
+
72400
 
+static void ext_variables_code_dumper_free
72401
 
+       (struct sieve_code_dumper *dumper, void *context);
72402
 
+
72403
 
+const struct sieve_code_dumper_extension variables_dump_extension = {
72404
 
+       &variables_extension,
72405
 
+       ext_variables_code_dumper_free
72406
 
+};
72407
 
+
72408
 
+/*
72409
 
+ * Code dump context
72410
 
+ */
72411
 
72412
 
+struct ext_variables_dump_context {
72413
 
+       struct sieve_variable_scope *main_scope;
72414
 
+       ARRAY_DEFINE(ext_scopes, struct sieve_variable_scope *);
72415
 
+};
72416
 
+
72417
 
+static void ext_variables_code_dumper_free
72418
 
+(struct sieve_code_dumper *dumper ATTR_UNUSED, void *context)
72419
 
+{
72420
 
+       struct ext_variables_dump_context *dctx = 
72421
 
+               (struct ext_variables_dump_context *) context;
72422
 
+
72423
 
+       if ( dctx == NULL || dctx->main_scope == NULL )
72424
 
+               return;
72425
 
+
72426
 
+       sieve_variable_scope_unref(&dctx->main_scope);
72427
 
+}
72428
 
+
72429
 
+static struct ext_variables_dump_context *ext_variables_dump_get_context
72430
 
+       (const struct sieve_dumptime_env *denv)
72431
 
+{
72432
 
+       struct sieve_code_dumper *dumper = denv->cdumper;
72433
 
+       struct ext_variables_dump_context *dctx = sieve_dump_extension_get_context
72434
 
+               (dumper, &variables_extension);
72435
 
+       pool_t pool;
72436
 
+
72437
 
+       if ( dctx == NULL ) {
72438
 
+               /* Create dumper context */
72439
 
+               pool = sieve_code_dumper_pool(dumper);
72440
 
+               dctx = p_new(pool, struct ext_variables_dump_context, 1);
72441
 
+               p_array_init(&dctx->ext_scopes, pool, sieve_extensions_get_count());
72442
 
+       
72443
 
+               sieve_dump_extension_set_context(dumper, &variables_extension, dctx);
72444
 
+       }
72445
 
+
72446
 
+       return dctx;
72447
 
+} 
72448
 
72449
 
+bool ext_variables_code_dump
72450
 
+(const struct sieve_dumptime_env *denv, sieve_size_t *address)
72451
 
+{
72452
 
+       struct ext_variables_dump_context *dctx;
72453
 
+       struct sieve_variable_scope *main_scope;
72454
 
+       unsigned int i, scope_size;
72455
 
+       sieve_size_t pc;
72456
 
+       int end_offset;
72457
 
+       
72458
 
+       sieve_code_mark(denv);
72459
 
+       if ( !sieve_binary_read_unsigned(denv->sbin, address, &scope_size) )
72460
 
+               return FALSE;
72461
 
+               
72462
 
+       pc = *address;  
72463
 
+       if ( !sieve_binary_read_offset(denv->sbin, address, &end_offset) )
72464
 
+               return FALSE;
72465
 
+       
72466
 
+       main_scope = sieve_variable_scope_create(NULL);
72467
 
+       
72468
 
+       sieve_code_dumpf(denv, "SCOPE [%u] (end: %08x)", 
72469
 
+               scope_size, (unsigned int) (pc + end_offset));
72470
 
+       
72471
 
+       /* Read main variable scope */
72472
 
+       
72473
 
+       for ( i = 0; i < scope_size; i++ ) {
72474
 
+               string_t *identifier;
72475
 
+
72476
 
+               sieve_code_mark(denv);
72477
 
+               if (!sieve_binary_read_string(denv->sbin, address, &identifier) ) {
72478
 
+                       return FALSE;
72479
 
+               }
72480
 
+               
72481
 
+               sieve_code_dumpf(denv, "%3d: '%s'", i, str_c(identifier));
72482
 
+               
72483
 
+               (void) sieve_variable_scope_declare(main_scope, str_c(identifier));
72484
 
+       }
72485
 
+       
72486
 
+       dctx = ext_variables_dump_get_context(denv);
72487
 
+       dctx->main_scope = main_scope;
72488
 
+       
72489
 
+       return TRUE;
72490
 
+}
72491
 
+
72492
 
+/*
72493
 
+ * Scope registry
72494
 
+ */
72495
 
+
72496
 
+void sieve_ext_variables_dump_set_scope
72497
 
+(const struct sieve_dumptime_env *denv, const struct sieve_extension *ext, 
72498
 
+       struct sieve_variable_scope *scope)
72499
 
+{
72500
 
+       struct ext_variables_dump_context *dctx = ext_variables_dump_get_context(denv);
72501
 
+
72502
 
+       array_idx_set(&dctx->ext_scopes, (unsigned int) SIEVE_EXT_ID(ext), &scope);     
72503
 
+}
72504
 
+
72505
 
+/*
72506
 
+ * Variable identifier dump
72507
 
+ */
72508
 
+
72509
 
+const char *ext_variables_dump_get_identifier
72510
 
+(const struct sieve_dumptime_env *denv, const struct sieve_extension *ext,
72511
 
+       unsigned int index)
72512
 
+{
72513
 
+       struct ext_variables_dump_context *dctx = ext_variables_dump_get_context(denv); 
72514
 
+       struct sieve_variable_scope *scope;
72515
 
+       struct sieve_variable *var;
72516
 
+
72517
 
+       if ( ext == NULL )
72518
 
+               scope = dctx->main_scope;
72519
 
+       else {
72520
 
+               struct sieve_variable_scope *const *ext_scope;
72521
 
+               int ext_id = SIEVE_EXT_ID(ext);
72522
 
+
72523
 
+               if  ( ext_id < 0 || ext_id >= (int) array_count(&dctx->ext_scopes) )
72524
 
+                       return NULL;
72525
 
+       
72526
 
+               ext_scope = array_idx(&dctx->ext_scopes, (unsigned int) ext_id);
72527
 
+               scope = *ext_scope;                     
72528
 
+       }
72529
 
+
72530
 
+       if ( scope == NULL )
72531
 
+               return NULL;
72532
 
+                       
72533
 
+       var = sieve_variable_scope_get_indexed(scope, index);
72534
 
+       
72535
 
+       return var->identifier;
72536
 
+}
72537
 
+
72538
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/variables/ext-variables-dump.h dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/variables/ext-variables-dump.h
72539
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/variables/ext-variables-dump.h 1970-01-01 01:00:00.000000000 +0100
72540
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/variables/ext-variables-dump.h  2009-01-06 00:15:52.000000000 +0100
72541
 
@@ -0,0 +1,24 @@
72542
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
72543
 
+ */
72544
 
+
72545
 
+#ifndef __EXT_VARIABLES_DUMP_H
72546
 
+#define __EXT_VARIABLES_DUMP_H
72547
 
+
72548
 
+#include "sieve-common.h"
72549
 
+
72550
 
+/*
72551
 
+ * Code dump context
72552
 
+ */
72553
 
72554
 
+bool ext_variables_code_dump
72555
 
+       (const struct sieve_dumptime_env *denv, sieve_size_t *address);
72556
 
+
72557
 
+/*
72558
 
+ * Variable identifier dump
72559
 
+ */
72560
 
72561
 
+const char *ext_variables_dump_get_identifier
72562
 
+(const struct sieve_dumptime_env *denv, const struct sieve_extension *ext,
72563
 
+       unsigned int index);
72564
 
+
72565
 
+#endif /* __EXT_VARIABLES_DUMP_H */
72566
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/variables/ext-variables-limits.h dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/variables/ext-variables-limits.h
72567
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/variables/ext-variables-limits.h       1970-01-01 01:00:00.000000000 +0100
72568
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/variables/ext-variables-limits.h        2009-01-06 00:15:52.000000000 +0100
72569
 
@@ -0,0 +1,34 @@
72570
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
72571
 
+ */
72572
 
+
72573
 
+#ifndef __EXT_VARIABLES_LIMITS_H
72574
 
+#define __EXT_VARIABLES_LIMITS_H
72575
 
+
72576
 
+#include "sieve-limits.h"
72577
 
+
72578
 
+/* From RFC 5229:
72579
 
+ * 
72580
 
+ * 6.  Implementation Limits
72581
 
+ *
72582
 
+ *  An implementation of this document MUST support at least 128 distinct
72583
 
+ *  variables.  The supported length of variable names MUST be at least
72584
 
+ *  32 characters.  Each variable MUST be able to hold at least 4000
72585
 
+ *  characters.  Attempts to set the variable to a value larger than what
72586
 
+ *  the implementation supports SHOULD be reported as an error at
72587
 
+ *  compile-time if possible.  If the attempt is discovered during run-
72588
 
+ *  time, the value SHOULD be truncated, and it MUST NOT be treated as an
72589
 
+ *  error.
72590
 
+
72591
 
+ *  Match variables ${1} through ${9} MUST be supported.  References to
72592
 
+ *  higher indices than those the implementation supports MUST be treated
72593
 
+ *  as a syntax error, which SHOULD be discovered at compile-time.
72594
 
+ */
72595
 
+
72596
 
+#define SIEVE_VARIABLES_MAX_SCOPE_SIZE              255
72597
 
+#define SIEVE_VARIABLES_MAX_VARIABLE_NAME_LEN       64
72598
 
+#define SIEVE_VARIABLES_MAX_VARIABLE_SIZE           (4 * 1024)
72599
 
+#define SIEVE_VARIABLES_MAX_NAMESPACE_ELEMENTS      4
72600
 
+
72601
 
+#define SIEVE_VARIABLES_MAX_MATCH_INDEX             SIEVE_MAX_MATCH_VALUES
72602
 
+
72603
 
+#endif /* __EXT_VARIABLES_LIMITS_H */
72604
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/variables/ext-variables-modifiers.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/variables/ext-variables-modifiers.c
72605
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/variables/ext-variables-modifiers.c    1970-01-01 01:00:00.000000000 +0100
72606
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/variables/ext-variables-modifiers.c     2009-01-06 00:15:52.000000000 +0100
72607
 
@@ -0,0 +1,241 @@
72608
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
72609
 
+ */
72610
 
+
72611
 
+#include "sieve-common.h"
72612
 
+#include "sieve-commands.h"
72613
 
+#include "sieve-code.h"
72614
 
+#include "sieve-binary.h"
72615
 
+
72616
 
+#include "ext-variables-common.h"
72617
 
+#include "ext-variables-modifiers.h"
72618
 
+
72619
 
+#include <ctype.h>
72620
 
+
72621
 
+/*
72622
 
+ * Core modifiers
72623
 
+ */
72624
 
72625
 
+extern const struct sieve_variables_modifier lower_modifier;
72626
 
+extern const struct sieve_variables_modifier upper_modifier;
72627
 
+extern const struct sieve_variables_modifier lowerfirst_modifier;
72628
 
+extern const struct sieve_variables_modifier upperfirst_modifier;
72629
 
+extern const struct sieve_variables_modifier quotewildcard_modifier;
72630
 
+extern const struct sieve_variables_modifier length_modifier;
72631
 
+
72632
 
+enum ext_variables_modifier_code {
72633
 
+    EXT_VARIABLES_MODIFIER_LOWER,
72634
 
+    EXT_VARIABLES_MODIFIER_UPPER,
72635
 
+    EXT_VARIABLES_MODIFIER_LOWERFIRST,
72636
 
+    EXT_VARIABLES_MODIFIER_UPPERFIRST,
72637
 
+    EXT_VARIABLES_MODIFIER_QUOTEWILDCARD,
72638
 
+    EXT_VARIABLES_MODIFIER_LENGTH
72639
 
+};
72640
 
+
72641
 
+const struct sieve_variables_modifier *ext_variables_core_modifiers[] = {
72642
 
+       &lower_modifier,
72643
 
+       &upper_modifier,
72644
 
+       &lowerfirst_modifier,
72645
 
+       &upperfirst_modifier,
72646
 
+       &quotewildcard_modifier,
72647
 
+       &length_modifier
72648
 
+};
72649
 
+
72650
 
+const unsigned int ext_variables_core_modifiers_count =
72651
 
+    N_ELEMENTS(ext_variables_core_modifiers);
72652
 
+
72653
 
+/*
72654
 
+ * Modifier registry
72655
 
+ */
72656
 
+
72657
 
+void sieve_variables_modifier_register
72658
 
+(struct sieve_validator *valdtr, const struct sieve_variables_modifier *smodf) 
72659
 
+{
72660
 
+       struct ext_variables_validator_context *ctx = 
72661
 
+               ext_variables_validator_context_get(valdtr);
72662
 
+       
72663
 
+       sieve_validator_object_registry_add(ctx->modifiers, &smodf->object);
72664
 
+}
72665
 
+
72666
 
+const struct sieve_variables_modifier *ext_variables_modifier_find
72667
 
+(struct sieve_validator *valdtr, const char *identifier)
72668
 
+{
72669
 
+       struct ext_variables_validator_context *ctx = 
72670
 
+               ext_variables_validator_context_get(valdtr);
72671
 
+               
72672
 
+       const struct sieve_object *object = 
72673
 
+               sieve_validator_object_registry_find(ctx->modifiers, identifier);
72674
 
+
72675
 
+       return (const struct sieve_variables_modifier *) object;
72676
 
+}
72677
 
+
72678
 
+void ext_variables_register_core_modifiers
72679
 
+(struct ext_variables_validator_context *ctx)
72680
 
+{
72681
 
+       unsigned int i;
72682
 
+       
72683
 
+       /* Register core modifiers*/
72684
 
+       for ( i = 0; i < ext_variables_core_modifiers_count; i++ ) {
72685
 
+               sieve_validator_object_registry_add
72686
 
+                       (ctx->modifiers, &(ext_variables_core_modifiers[i]->object));
72687
 
+       }
72688
 
+}
72689
 
+
72690
 
+/*
72691
 
+ * Modifier coding
72692
 
+ */
72693
 
72694
 
+const struct sieve_operand_class sieve_variables_modifier_operand_class = 
72695
 
+       { "modifier" };
72696
 
+       
72697
 
+static const struct sieve_extension_objects core_modifiers =
72698
 
+       SIEVE_VARIABLES_DEFINE_MODIFIERS(ext_variables_core_modifiers);
72699
 
+
72700
 
+const struct sieve_operand modifier_operand = { 
72701
 
+       "modifier", 
72702
 
+       &variables_extension,
72703
 
+       EXT_VARIABLES_OPERAND_MODIFIER, 
72704
 
+       &sieve_variables_modifier_operand_class,
72705
 
+       &core_modifiers
72706
 
+};
72707
 
+
72708
 
+/* 
72709
 
+ * Core modifiers 
72710
 
+ */
72711
 
72712
 
+/* Forward declarations */
72713
 
+
72714
 
+bool mod_lower_modify(string_t *in, string_t **result);
72715
 
+bool mod_upper_modify(string_t *in, string_t **result);
72716
 
+bool mod_lowerfirst_modify(string_t *in, string_t **result);
72717
 
+bool mod_upperfirst_modify(string_t *in, string_t **result);
72718
 
+bool mod_length_modify(string_t *in, string_t **result);
72719
 
+bool mod_quotewildcard_modify(string_t *in, string_t **result);
72720
 
+
72721
 
+/* Modifier objects */
72722
 
+
72723
 
+const struct sieve_variables_modifier lower_modifier = {
72724
 
+       SIEVE_OBJECT("lower", &modifier_operand, EXT_VARIABLES_MODIFIER_LOWER),
72725
 
+       40,
72726
 
+       mod_lower_modify
72727
 
+};
72728
 
+
72729
 
+const struct sieve_variables_modifier upper_modifier = {
72730
 
+       SIEVE_OBJECT("upper", &modifier_operand, EXT_VARIABLES_MODIFIER_UPPER),
72731
 
+       40,
72732
 
+       mod_upper_modify
72733
 
+};
72734
 
+
72735
 
+const struct sieve_variables_modifier lowerfirst_modifier = {
72736
 
+       SIEVE_OBJECT
72737
 
+               ("lowerfirst", &modifier_operand, EXT_VARIABLES_MODIFIER_LOWERFIRST),
72738
 
+       30,
72739
 
+       mod_lowerfirst_modify
72740
 
+};
72741
 
+
72742
 
+const struct sieve_variables_modifier upperfirst_modifier = {
72743
 
+       SIEVE_OBJECT
72744
 
+               ("upperfirst", &modifier_operand,       EXT_VARIABLES_MODIFIER_UPPERFIRST),
72745
 
+       30,
72746
 
+       mod_upperfirst_modify
72747
 
+};
72748
 
+
72749
 
+const struct sieve_variables_modifier quotewildcard_modifier = {
72750
 
+       SIEVE_OBJECT
72751
 
+               ("quotewildcard", &modifier_operand, EXT_VARIABLES_MODIFIER_QUOTEWILDCARD),
72752
 
+       20,
72753
 
+       mod_quotewildcard_modify
72754
 
+};
72755
 
+
72756
 
+const struct sieve_variables_modifier length_modifier = {
72757
 
+       SIEVE_OBJECT("length", &modifier_operand, EXT_VARIABLES_MODIFIER_LENGTH),
72758
 
+       10,
72759
 
+       mod_length_modify
72760
 
+};
72761
 
+
72762
 
+/* Modifier implementations */
72763
 
+
72764
 
+bool mod_upperfirst_modify(string_t *in, string_t **result)
72765
 
+{
72766
 
+       char *content;
72767
 
+       
72768
 
+       *result = t_str_new(str_len(in));
72769
 
+       str_append_str(*result, in);
72770
 
+               
72771
 
+       content = str_c_modifiable(*result);
72772
 
+       content[0] = i_toupper(content[0]);
72773
 
+
72774
 
+       return TRUE;
72775
 
+}
72776
 
+
72777
 
+bool mod_lowerfirst_modify(string_t *in, string_t **result)
72778
 
+{
72779
 
+       char *content;
72780
 
+       
72781
 
+       *result = t_str_new(str_len(in));
72782
 
+       str_append_str(*result, in);
72783
 
+               
72784
 
+       content = str_c_modifiable(*result);
72785
 
+       content[0] = i_tolower(content[0]);
72786
 
+
72787
 
+       return TRUE;
72788
 
+}
72789
 
+
72790
 
+bool mod_upper_modify(string_t *in, string_t **result)
72791
 
+{
72792
 
+       char *content;
72793
 
+       
72794
 
+       *result = t_str_new(str_len(in));
72795
 
+       str_append_str(*result, in);
72796
 
+
72797
 
+       content = str_c_modifiable(*result);
72798
 
+       content = str_ucase(content);
72799
 
+       
72800
 
+       return TRUE;
72801
 
+}
72802
 
+
72803
 
+bool mod_lower_modify(string_t *in, string_t **result)
72804
 
+{
72805
 
+       char *content;
72806
 
+       
72807
 
+       *result = t_str_new(str_len(in));
72808
 
+       str_append_str(*result, in);
72809
 
+
72810
 
+       content = str_c_modifiable(*result);
72811
 
+       content = str_lcase(content);
72812
 
+
72813
 
+       return TRUE;
72814
 
+}
72815
 
+
72816
 
+bool mod_length_modify(string_t *in, string_t **result)
72817
 
+{
72818
 
+       *result = t_str_new(64);
72819
 
+       str_printfa(*result, "%llu", (unsigned long long) str_len(in));
72820
 
+
72821
 
+       return TRUE;
72822
 
+}
72823
 
+
72824
 
+bool mod_quotewildcard_modify(string_t *in, string_t **result)
72825
 
+{
72826
 
+       unsigned int i;
72827
 
+       const char *content;
72828
 
+       
72829
 
+       *result = t_str_new(str_len(in) * 2);
72830
 
+       content = (const char *) str_data(in);
72831
 
+       
72832
 
+       for ( i = 0; i < str_len(in); i++ ) {
72833
 
+               if ( content[i] == '*' || content[i] == '?' || content[i] == '\\' ) {
72834
 
+                       str_append_c(*result, '\\');
72835
 
+               }
72836
 
+               str_append_c(*result, content[i]);
72837
 
+       }
72838
 
+       
72839
 
+       return TRUE;
72840
 
+}
72841
 
+
72842
 
+
72843
 
+
72844
 
+
72845
 
+
72846
 
+
72847
 
+
72848
 
+
72849
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/variables/ext-variables-modifiers.h dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/variables/ext-variables-modifiers.h
72850
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/variables/ext-variables-modifiers.h    1970-01-01 01:00:00.000000000 +0100
72851
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/variables/ext-variables-modifiers.h     2009-01-06 00:15:52.000000000 +0100
72852
 
@@ -0,0 +1,47 @@
72853
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
72854
 
+ */
72855
 
+
72856
 
+#ifndef __EXT_VARIABLES_MODIFIERS_H
72857
 
+#define __EXT_VARIABLES_MODIFIERS_H
72858
 
+
72859
 
+#include "ext-variables-common.h"
72860
 
+#include "sieve-ext-variables.h"
72861
 
+
72862
 
+/*
72863
 
+ * Modifier registry
72864
 
+ */
72865
 
+
72866
 
+const struct sieve_variables_modifier *ext_variables_modifier_find
72867
 
+       (struct sieve_validator *validator, const char *identifier);
72868
 
+
72869
 
+void ext_variables_register_core_modifiers
72870
 
+       (struct ext_variables_validator_context *ctx);
72871
 
+       
72872
 
+/*
72873
 
+ * Modifier operand
72874
 
+ */
72875
 
+
72876
 
+extern const struct sieve_operand modifier_operand;
72877
 
+
72878
 
+static inline void ext_variables_opr_modifier_emit
72879
 
+(struct sieve_binary *sbin, const struct sieve_variables_modifier *modf)
72880
 
+{ 
72881
 
+       sieve_opr_object_emit(sbin, &modf->object);
72882
 
+}
72883
 
+
72884
 
+static inline const struct sieve_variables_modifier *
72885
 
+       ext_variables_opr_modifier_read
72886
 
+(const struct sieve_runtime_env *renv, sieve_size_t *address)
72887
 
+{
72888
 
+       return (const struct sieve_variables_modifier *) sieve_opr_object_read
72889
 
+               (renv, &sieve_variables_modifier_operand_class, address);
72890
 
+}
72891
 
+
72892
 
+static inline bool ext_variables_opr_modifier_dump
72893
 
+(const struct sieve_dumptime_env *denv, sieve_size_t *address)
72894
 
+{
72895
 
+       return sieve_opr_object_dump
72896
 
+               (denv, &sieve_variables_modifier_operand_class, address, NULL);
72897
 
+}
72898
 
+       
72899
 
+#endif /* __EXT_VARIABLES_MODIFIERS_H */
72900
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/variables/ext-variables-name.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/variables/ext-variables-name.c
72901
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/variables/ext-variables-name.c 1970-01-01 01:00:00.000000000 +0100
72902
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/variables/ext-variables-name.c  2009-01-06 00:15:52.000000000 +0100
72903
 
@@ -0,0 +1,88 @@
72904
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
72905
 
+ */
72906
 
+
72907
 
+#include "lib.h"
72908
 
+#include "str.h"
72909
 
+#include "array.h"
72910
 
+
72911
 
+#include "sieve-common.h"
72912
 
+
72913
 
+#include "ext-variables-common.h"
72914
 
+#include "ext-variables-limits.h"
72915
 
+#include "ext-variables-name.h"
72916
 
+
72917
 
+#include <ctype.h>
72918
 
+
72919
 
+int ext_variable_name_parse
72920
 
+(ARRAY_TYPE(ext_variable_name) *vname, const char **str, const char *strend)
72921
 
+{
72922
 
+       const char *p = *str;
72923
 
+       int nspace_used = 0;
72924
 
+                               
72925
 
+       for (;;) { 
72926
 
+               struct ext_variable_name *cur_element;
72927
 
+               string_t *cur_ident;
72928
 
+
72929
 
+               /* Acquire current position in the substitution structure or allocate 
72930
 
+                * a new one if this substitution consists of more elements than before.
72931
 
+                */
72932
 
+               if ( nspace_used < (int) array_count(vname) ) {
72933
 
+                       cur_element = array_idx_modifiable
72934
 
+                               (vname, (unsigned int) nspace_used);
72935
 
+                       cur_ident = cur_element->identifier;
72936
 
+               } else {
72937
 
+                       if ( nspace_used >= SIEVE_VARIABLES_MAX_NAMESPACE_ELEMENTS )
72938
 
+                               return -1;
72939
 
+                       cur_element = array_append_space(vname);
72940
 
+                       cur_ident = cur_element->identifier = t_str_new(32);
72941
 
+               }
72942
 
+
72943
 
+               /* Identifier */
72944
 
+               if ( *p == '_' || i_isalpha(*p) ) {
72945
 
+                       cur_element->num_variable = -1;
72946
 
+                       str_truncate(cur_ident, 0);
72947
 
+                       str_append_c(cur_ident, *p);
72948
 
+                       p++;
72949
 
+               
72950
 
+                       while ( p < strend && (*p == '_' || i_isalnum(*p)) ) {
72951
 
+                               if ( str_len(cur_ident) >= SIEVE_VARIABLES_MAX_VARIABLE_NAME_LEN )
72952
 
+                                       return -1;
72953
 
+                               str_append_c(cur_ident, *p);
72954
 
+                               p++;
72955
 
+                       }
72956
 
+               
72957
 
+               /* Num-variable */
72958
 
+               } else if ( i_isdigit(*p) ) {
72959
 
+                       cur_element->num_variable = *p - '0';
72960
 
+                       p++;
72961
 
+                       
72962
 
+                       while ( p < strend && i_isdigit(*p) ) {
72963
 
+                               cur_element->num_variable = cur_element->num_variable*10 + (*p - '0');
72964
 
+                               p++;
72965
 
+                       } 
72966
 
+
72967
 
+                       /* If a num-variable is first, no more elements can follow because no
72968
 
+                        * namespace is specified.
72969
 
+                        */
72970
 
+                       if ( nspace_used == 0 ) {
72971
 
+                               *str = p;
72972
 
+                               return 1;
72973
 
+                       }
72974
 
+               } else {
72975
 
+                       *str = p;
72976
 
+                       return -1;
72977
 
+               }
72978
 
+               
72979
 
+               nspace_used++;
72980
 
+               
72981
 
+               if ( p < strend && *p == '.' ) 
72982
 
+                       p++;
72983
 
+               else
72984
 
+                       break;
72985
 
+       }
72986
 
+       
72987
 
+       *str = p;
72988
 
+       return nspace_used;
72989
 
+} 
72990
 
72991
 
+
72992
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/variables/ext-variables-name.h dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/variables/ext-variables-name.h
72993
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/variables/ext-variables-name.h 1970-01-01 01:00:00.000000000 +0100
72994
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/variables/ext-variables-name.h  2009-01-06 00:15:52.000000000 +0100
72995
 
@@ -0,0 +1,57 @@
72996
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
72997
 
+ */
72998
 
+
72999
 
+#ifndef __EXT_VARIABLES_NAME
73000
 
+#define __EXT_VARIABLES_NAME
73001
 
+
73002
 
+/* Variable Substitution
73003
 
+ * ---------------------
73004
 
+ * 
73005
 
+ * The variable strings are preprocessed into an AST list consisting of variable 
73006
 
+ * substitutions and constant parts of the string. The variables to which
73007
 
+ * the substitutions link are looked up and their index in their scope storage
73008
 
+ * is what is added to the list and eventually emitted as byte code. So in byte
73009
 
+ * code a variable string will look as a series of substrings interrupted by
73010
 
+ * integer operands that refer to variables. During execution the strings and 
73011
 
+ * the looked-up variables are concatenated to obtain the desired result. The 
73012
 
+ * the variable references are simple indexes into an array of variables, so
73013
 
+ * looking these up during execution is a trivial process.
73014
 
+ * 
73015
 
+ * However (RFC 5229):
73016
 
+ *   Tests or actions in future extensions may need to access the
73017
 
+ *   unexpanded version of the string argument and, e.g., do the expansion
73018
 
+ *   after setting variables in its namespace.  The design of the
73019
 
+ *   implementation should allow this.
73020
 
+ *
73021
 
+ * Various options exist to provide this feature. If the extension is entirely
73022
 
+ * namespace-based there is actually not very much of a problem. The variable
73023
 
+ * list can easily be extended with new argument-types that refer to a variable
73024
 
+ * identifier in stead of an index in the variable's storage. 
73025
 
+ */
73026
 
+
73027
 
+#include "lib.h"
73028
 
+#include "array.h"
73029
 
+
73030
 
+#include "sieve-common.h"
73031
 
+
73032
 
+#include "ext-variables-common.h"
73033
 
+
73034
 
+/*
73035
 
+ * Types
73036
 
+ */ 
73037
 
+
73038
 
+struct ext_variable_name {
73039
 
+       string_t *identifier;
73040
 
+       int num_variable;
73041
 
+};
73042
 
+
73043
 
+ARRAY_DEFINE_TYPE(ext_variable_name, struct ext_variable_name);
73044
 
+
73045
 
+/*
73046
 
+ * Variable name parsing
73047
 
+ */
73048
 
73049
 
+int ext_variable_name_parse
73050
 
+       (ARRAY_TYPE(ext_variable_name) *vname, const char **str, const char *strend);
73051
 
+
73052
 
+#endif /* __EXT_VARIABLES_NAME */
73053
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/variables/ext-variables-operands.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/variables/ext-variables-operands.c
73054
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/variables/ext-variables-operands.c     1970-01-01 01:00:00.000000000 +0100
73055
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/variables/ext-variables-operands.c      2009-01-06 00:15:52.000000000 +0100
73056
 
@@ -0,0 +1,238 @@
73057
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
73058
 
+ */
73059
 
+
73060
 
+#include "lib.h"
73061
 
+#include "hash.h"
73062
 
+#include "str.h"
73063
 
+#include "array.h"
73064
 
+
73065
 
+#include "sieve-common.h"
73066
 
+
73067
 
+#include "sieve-ast.h"
73068
 
+#include "sieve-binary.h"
73069
 
+#include "sieve-code.h"
73070
 
+#include "sieve-match-types.h"
73071
 
+
73072
 
+#include "sieve-commands.h"
73073
 
+#include "sieve-validator.h"
73074
 
+#include "sieve-generator.h"
73075
 
+#include "sieve-dump.h"
73076
 
+#include "sieve-interpreter.h"
73077
 
+
73078
 
+#include "ext-variables-common.h"
73079
 
+#include "ext-variables-name.h"
73080
 
+#include "ext-variables-dump.h"
73081
 
+
73082
 
+/* 
73083
 
+ * Variable operand 
73084
 
+ */
73085
 
+
73086
 
+static bool opr_variable_read_value
73087
 
+       (const struct sieve_runtime_env *renv, sieve_size_t *address, string_t **str);
73088
 
+static bool opr_variable_dump
73089
 
+       (const struct sieve_dumptime_env *denv, sieve_size_t *address, 
73090
 
+               const char *field_name);
73091
 
+
73092
 
+const struct sieve_opr_string_interface variable_interface = { 
73093
 
+       opr_variable_dump,
73094
 
+       opr_variable_read_value
73095
 
+};
73096
 
+               
73097
 
+const struct sieve_operand variable_operand = { 
73098
 
+       "variable", 
73099
 
+       &variables_extension, 
73100
 
+       EXT_VARIABLES_OPERAND_VARIABLE,
73101
 
+       &string_class,
73102
 
+       &variable_interface
73103
 
+};
73104
 
+
73105
 
+void ext_variables_opr_variable_emit
73106
 
+(struct sieve_binary *sbin, struct sieve_variable *var) 
73107
 
+{
73108
 
+       if ( var->ext == NULL ) {
73109
 
+               /* Default variable storage */
73110
 
+               (void) sieve_operand_emit_code(sbin, &variable_operand);
73111
 
+               (void) sieve_binary_emit_byte(sbin, 0);
73112
 
+               (void) sieve_binary_emit_unsigned(sbin, var->index);
73113
 
+               return;
73114
 
+       } 
73115
 
+
73116
 
+       (void) sieve_operand_emit_code(sbin, &variable_operand);
73117
 
+       (void) sieve_binary_emit_extension(sbin, var->ext, 1);
73118
 
+       (void) sieve_binary_emit_unsigned(sbin, var->index);
73119
 
+}
73120
 
+
73121
 
+static bool opr_variable_dump
73122
 
+(const struct sieve_dumptime_env *denv, sieve_size_t *address,
73123
 
+       const char *field_name) 
73124
 
+{
73125
 
+       unsigned int index = 0;
73126
 
+       const struct sieve_extension *ext;
73127
 
+       unsigned int code = 1; /* Initially set to offset value */
73128
 
+       const char *identifier;
73129
 
+
73130
 
+       if ( !sieve_binary_read_extension(denv->sbin, address, &code, &ext) )
73131
 
+               return FALSE;
73132
 
+       
73133
 
+       if ( !sieve_binary_read_unsigned(denv->sbin, address, &index) )
73134
 
+               return FALSE;
73135
 
+               
73136
 
+       identifier = ext_variables_dump_get_identifier(denv, ext, index);
73137
 
+       identifier = identifier == NULL ? "??" : identifier;
73138
 
+
73139
 
+       if ( ext == NULL ) {            
73140
 
+               if ( field_name != NULL ) 
73141
 
+                       sieve_code_dumpf(denv, "%s: VAR ${%s} (%ld)", 
73142
 
+                               field_name, identifier, (long) index);
73143
 
+               else
73144
 
+                       sieve_code_dumpf(denv, "VAR ${%s} (%ld)", 
73145
 
+                               identifier, (long) index);
73146
 
+       } else {
73147
 
+               if ( field_name != NULL ) 
73148
 
+                       sieve_code_dumpf(denv, "%s: VAR [%s] ${%s} (%ld)", 
73149
 
+                               field_name, ext->name, identifier, (long) index);
73150
 
+               else
73151
 
+                       sieve_code_dumpf(denv, "VAR [%s] ${%s} (%ld)", 
73152
 
+                               ext->name, identifier, (long) index);
73153
 
+       }
73154
 
+       return TRUE;
73155
 
+}
73156
 
+
73157
 
+static bool opr_variable_read_value
73158
 
+(const struct sieve_runtime_env *renv, sieve_size_t *address, string_t **str)
73159
 
+{ 
73160
 
+       const struct sieve_extension *ext;
73161
 
+       unsigned int code = 1; /* Initially set to offset value */
73162
 
+       struct sieve_variable_storage *storage;
73163
 
+       unsigned int index = 0;
73164
 
+       
73165
 
+       if ( !sieve_binary_read_extension(renv->sbin, address, &code, &ext) )
73166
 
+               return FALSE;
73167
 
+
73168
 
+       storage = sieve_ext_variables_get_storage(renv->interp, ext);
73169
 
+       if ( storage == NULL ) 
73170
 
+               return FALSE;
73171
 
+       
73172
 
+       if (sieve_binary_read_unsigned(renv->sbin, address, &index) ) {
73173
 
+               /* Parameter str can be NULL if we are requested to only skip and not 
73174
 
+                * actually read the argument.
73175
 
+                */
73176
 
+               if ( str != NULL ) {
73177
 
+                       if ( !sieve_variable_get(storage, index, str) )
73178
 
+                               return FALSE;
73179
 
+               
73180
 
+                       if ( *str == NULL ) *str = t_str_new(0);
73181
 
+               }
73182
 
+               return TRUE;
73183
 
+       }
73184
 
+       
73185
 
+       return FALSE;
73186
 
+}
73187
 
+               
73188
 
+bool sieve_variable_operand_read_data
73189
 
+(const struct sieve_runtime_env *renv, const struct sieve_operand *operand, 
73190
 
+       sieve_size_t *address, struct sieve_variable_storage **storage, 
73191
 
+       unsigned int *var_index)
73192
 
+{
73193
 
+       const struct sieve_extension *ext;
73194
 
+       unsigned int code = 1; /* Initially set to offset value */
73195
 
+       unsigned int idx = 0;
73196
 
+
73197
 
+       if ( operand != &variable_operand ) {
73198
 
+               return FALSE;
73199
 
+       }
73200
 
+
73201
 
+       if ( !sieve_binary_read_extension(renv->sbin, address, &code, &ext) )
73202
 
+        return FALSE;
73203
 
+               
73204
 
+       *storage = sieve_ext_variables_get_storage(renv->interp, ext);
73205
 
+       if ( *storage == NULL ) 
73206
 
+               return FALSE;
73207
 
+       
73208
 
+       if ( !sieve_binary_read_unsigned(renv->sbin, address, &idx) )
73209
 
+               return FALSE;           
73210
 
+
73211
 
+       *var_index = idx;
73212
 
+       return TRUE;
73213
 
+}
73214
 
+
73215
 
+bool sieve_variable_operand_read
73216
 
+(const struct sieve_runtime_env *renv, sieve_size_t *address, 
73217
 
+       struct sieve_variable_storage **storage, unsigned int *var_index)
73218
 
+{
73219
 
+       const struct sieve_operand *operand = sieve_operand_read(renv->sbin, address);
73220
 
+
73221
 
+       return sieve_variable_operand_read_data
73222
 
+               (renv, operand, address, storage, var_index);
73223
 
+}
73224
 
+       
73225
 
+/* 
73226
 
+ * Match value operand 
73227
 
+ */
73228
 
+
73229
 
+static bool opr_match_value_read
73230
 
+       (const struct sieve_runtime_env *renv, sieve_size_t *address, string_t **str);
73231
 
+static bool opr_match_value_dump
73232
 
+       (const struct sieve_dumptime_env *denv, sieve_size_t *address, 
73233
 
+               const char *field_name);
73234
 
+
73235
 
+const struct sieve_opr_string_interface match_value_interface = { 
73236
 
+       opr_match_value_dump,
73237
 
+       opr_match_value_read
73238
 
+};
73239
 
+               
73240
 
+const struct sieve_operand match_value_operand = { 
73241
 
+       "match-value", 
73242
 
+       &variables_extension, 
73243
 
+       EXT_VARIABLES_OPERAND_MATCH_VALUE,
73244
 
+       &string_class,
73245
 
+       &match_value_interface
73246
 
+};     
73247
 
+
73248
 
+void ext_variables_opr_match_value_emit
73249
 
+(struct sieve_binary *sbin, unsigned int index) 
73250
 
+{
73251
 
+       (void) sieve_operand_emit_code(sbin, &match_value_operand);
73252
 
+       (void) sieve_binary_emit_unsigned(sbin, index);
73253
 
+}
73254
 
+
73255
 
+static bool opr_match_value_dump
73256
 
+(const struct sieve_dumptime_env *denv, sieve_size_t *address,
73257
 
+       const char *field_name) 
73258
 
+{
73259
 
+       unsigned int index = 0;
73260
 
+       
73261
 
+       if (sieve_binary_read_unsigned(denv->sbin, address, &index) ) {
73262
 
+               if ( field_name != NULL )
73263
 
+                       sieve_code_dumpf(denv, "%s: MATCHVAL %lu", field_name, (unsigned long) index);
73264
 
+               else
73265
 
+                       sieve_code_dumpf(denv, "MATCHVAL %lu", (unsigned long) index);
73266
 
+
73267
 
+               return TRUE;
73268
 
+       }
73269
 
+       
73270
 
+       return FALSE;
73271
 
+}
73272
 
+
73273
 
+static bool opr_match_value_read
73274
 
+(const struct sieve_runtime_env *renv, sieve_size_t *address, string_t **str)
73275
 
+{ 
73276
 
+       unsigned int index = 0;
73277
 
+                       
73278
 
+       if (sieve_binary_read_unsigned(renv->sbin, address, &index) ) {
73279
 
+               /* Parameter str can be NULL if we are requested to only skip and not 
73280
 
+                * actually read the argument.
73281
 
+                       */
73282
 
+               if ( str != NULL ) {
73283
 
+                       sieve_match_values_get(renv->interp, index, str);
73284
 
+               
73285
 
+                       if ( *str == NULL ) 
73286
 
+                               *str = t_str_new(0);
73287
 
+                       else if ( str_len(*str) > SIEVE_VARIABLES_MAX_VARIABLE_SIZE ) 
73288
 
+                               str_truncate(*str, SIEVE_VARIABLES_MAX_VARIABLE_SIZE);
73289
 
+               }
73290
 
+               return TRUE;
73291
 
+       }
73292
 
+       
73293
 
+       return FALSE;
73294
 
+}
73295
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/variables/ext-variables-operands.h dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/variables/ext-variables-operands.h
73296
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/variables/ext-variables-operands.h     1970-01-01 01:00:00.000000000 +0100
73297
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/variables/ext-variables-operands.h      2009-01-06 00:15:52.000000000 +0100
73298
 
@@ -0,0 +1,34 @@
73299
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
73300
 
+ */
73301
 
+
73302
 
+#ifndef __EXT_VARIABLES_OPERANDS_H
73303
 
+#define __EXT_VARIABLES_OPERANDS_H
73304
 
+
73305
 
+#include "lib.h"
73306
 
+#include "hash.h"
73307
 
+#include "str.h"
73308
 
+#include "array.h"
73309
 
+
73310
 
+#include "sieve-common.h"
73311
 
+#include "ext-variables-common.h"
73312
 
+
73313
 
+/* 
73314
 
+ * Variable operand 
73315
 
+ */
73316
 
+               
73317
 
+extern const struct sieve_operand variable_operand;    
73318
 
+
73319
 
+void ext_variables_opr_variable_emit
73320
 
+       (struct sieve_binary *sbin, struct sieve_variable *var);
73321
 
+
73322
 
+/* 
73323
 
+ * Match value operand 
73324
 
+ */
73325
 
+               
73326
 
+extern const struct sieve_operand match_value_operand; 
73327
 
+
73328
 
+void ext_variables_opr_match_value_emit
73329
 
+       (struct sieve_binary *sbin, unsigned int index);
73330
 
+       
73331
 
+#endif /* __EXT_VARIABLES_OPERANDS_H */
73332
 
+
73333
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/variables/Makefile.am dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/variables/Makefile.am
73334
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/variables/Makefile.am  1970-01-01 01:00:00.000000000 +0100
73335
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/variables/Makefile.am   2008-10-20 01:35:49.000000000 +0200
73336
 
@@ -0,0 +1,35 @@
73337
 
+noinst_LTLIBRARIES = libsieve_ext_variables.la
73338
 
+
73339
 
+AM_CPPFLAGS = \
73340
 
+       -I../../ \
73341
 
+       -I$(dovecot_incdir) \
73342
 
+       -I$(dovecot_incdir)/src/lib \
73343
 
+       -I$(dovecot_incdir)/src/lib-mail \
73344
 
+       -I$(dovecot_incdir)/src/lib-storage 
73345
 
+
73346
 
+cmds = \
73347
 
+       cmd-set.c
73348
 
+
73349
 
+tsts = \
73350
 
+       tst-string.c
73351
 
+
73352
 
+libsieve_ext_variables_la_SOURCES = \
73353
 
+       ext-variables-common.c \
73354
 
+       ext-variables-name.c \
73355
 
+       ext-variables-arguments.c \
73356
 
+       ext-variables-operands.c \
73357
 
+       ext-variables-modifiers.c \
73358
 
+       ext-variables-dump.c \
73359
 
+       $(cmds) \
73360
 
+       $(tsts) \
73361
 
+       ext-variables.c
73362
 
+
73363
 
+noinst_HEADERS = \
73364
 
+       ext-variables-common.h \
73365
 
+       ext-variables-limits.h \
73366
 
+       ext-variables-name.h \
73367
 
+       ext-variables-arguments.h \
73368
 
+       ext-variables-operands.h \
73369
 
+       ext-variables-modifiers.h \
73370
 
+       ext-variables-dump.h \
73371
 
+       sieve-ext-variables.h 
73372
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/variables/Makefile.in dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/variables/Makefile.in
73373
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/variables/Makefile.in  1970-01-01 01:00:00.000000000 +0100
73374
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/variables/Makefile.in   2009-08-21 00:55:44.000000000 +0200
73375
 
@@ -0,0 +1,495 @@
73376
 
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
73377
 
+# @configure_input@
73378
 
+
73379
 
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
73380
 
+# 2003, 2004, 2005, 2006, 2007, 2008  Free Software Foundation, Inc.
73381
 
+# This Makefile.in is free software; the Free Software Foundation
73382
 
+# gives unlimited permission to copy and/or distribute it,
73383
 
+# with or without modifications, as long as this notice is preserved.
73384
 
+
73385
 
+# This program is distributed in the hope that it will be useful,
73386
 
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
73387
 
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
73388
 
+# PARTICULAR PURPOSE.
73389
 
+
73390
 
+@SET_MAKE@
73391
 
+
73392
 
+
73393
 
+VPATH = @srcdir@
73394
 
+pkgdatadir = $(datadir)/@PACKAGE@
73395
 
+pkglibdir = $(libdir)/@PACKAGE@
73396
 
+pkgincludedir = $(includedir)/@PACKAGE@
73397
 
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
73398
 
+install_sh_DATA = $(install_sh) -c -m 644
73399
 
+install_sh_PROGRAM = $(install_sh) -c
73400
 
+install_sh_SCRIPT = $(install_sh) -c
73401
 
+INSTALL_HEADER = $(INSTALL_DATA)
73402
 
+transform = $(program_transform_name)
73403
 
+NORMAL_INSTALL = :
73404
 
+PRE_INSTALL = :
73405
 
+POST_INSTALL = :
73406
 
+NORMAL_UNINSTALL = :
73407
 
+PRE_UNINSTALL = :
73408
 
+POST_UNINSTALL = :
73409
 
+build_triplet = @build@
73410
 
+host_triplet = @host@
73411
 
+subdir = src/lib-sieve/plugins/variables
73412
 
+DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
73413
 
+       $(srcdir)/Makefile.in
73414
 
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
73415
 
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
73416
 
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
73417
 
+       $(ACLOCAL_M4)
73418
 
+mkinstalldirs = $(install_sh) -d
73419
 
+CONFIG_HEADER = $(top_builddir)/dummy-config.h \
73420
 
+       $(top_builddir)/dsieve-config.h
73421
 
+CONFIG_CLEAN_FILES =
73422
 
+LTLIBRARIES = $(noinst_LTLIBRARIES)
73423
 
+libsieve_ext_variables_la_LIBADD =
73424
 
+am__objects_1 = cmd-set.lo
73425
 
+am__objects_2 = tst-string.lo
73426
 
+am_libsieve_ext_variables_la_OBJECTS = ext-variables-common.lo \
73427
 
+       ext-variables-name.lo ext-variables-arguments.lo \
73428
 
+       ext-variables-operands.lo ext-variables-modifiers.lo \
73429
 
+       ext-variables-dump.lo $(am__objects_1) $(am__objects_2) \
73430
 
+       ext-variables.lo
73431
 
+libsieve_ext_variables_la_OBJECTS =  \
73432
 
+       $(am_libsieve_ext_variables_la_OBJECTS)
73433
 
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
73434
 
+depcomp = $(SHELL) $(top_srcdir)/depcomp
73435
 
+am__depfiles_maybe = depfiles
73436
 
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
73437
 
+       $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
73438
 
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
73439
 
+       --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
73440
 
+       $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
73441
 
+CCLD = $(CC)
73442
 
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
73443
 
+       --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
73444
 
+       $(LDFLAGS) -o $@
73445
 
+SOURCES = $(libsieve_ext_variables_la_SOURCES)
73446
 
+DIST_SOURCES = $(libsieve_ext_variables_la_SOURCES)
73447
 
+HEADERS = $(noinst_HEADERS)
73448
 
+ETAGS = etags
73449
 
+CTAGS = ctags
73450
 
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
73451
 
+ACLOCAL = @ACLOCAL@
73452
 
+AMTAR = @AMTAR@
73453
 
+AR = @AR@
73454
 
+AUTOCONF = @AUTOCONF@
73455
 
+AUTOHEADER = @AUTOHEADER@
73456
 
+AUTOMAKE = @AUTOMAKE@
73457
 
+AWK = @AWK@
73458
 
+CC = @CC@
73459
 
+CCDEPMODE = @CCDEPMODE@
73460
 
+CFLAGS = @CFLAGS@
73461
 
+CPP = @CPP@
73462
 
+CPPFLAGS = @CPPFLAGS@
73463
 
+CYGPATH_W = @CYGPATH_W@
73464
 
+DEFS = @DEFS@
73465
 
+DEPDIR = @DEPDIR@
73466
 
+DSYMUTIL = @DSYMUTIL@
73467
 
+DUMPBIN = @DUMPBIN@
73468
 
+ECHO_C = @ECHO_C@
73469
 
+ECHO_N = @ECHO_N@
73470
 
+ECHO_T = @ECHO_T@
73471
 
+EGREP = @EGREP@
73472
 
+EXEEXT = @EXEEXT@
73473
 
+FGREP = @FGREP@
73474
 
+GREP = @GREP@
73475
 
+INSTALL = @INSTALL@
73476
 
+INSTALL_DATA = @INSTALL_DATA@
73477
 
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
73478
 
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
73479
 
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
73480
 
+LD = @LD@
73481
 
+LDFLAGS = @LDFLAGS@
73482
 
+LIBICONV = @LIBICONV@
73483
 
+LIBOBJS = @LIBOBJS@
73484
 
+LIBS = @LIBS@
73485
 
+LIBTOOL = @LIBTOOL@
73486
 
+LIPO = @LIPO@
73487
 
+LN_S = @LN_S@
73488
 
+LTLIBOBJS = @LTLIBOBJS@
73489
 
+MAINT = @MAINT@
73490
 
+MAKEINFO = @MAKEINFO@
73491
 
+MKDIR_P = @MKDIR_P@
73492
 
+MODULE_LIBS = @MODULE_LIBS@
73493
 
+NM = @NM@
73494
 
+NMEDIT = @NMEDIT@
73495
 
+OBJDUMP = @OBJDUMP@
73496
 
+OBJEXT = @OBJEXT@
73497
 
+OTOOL = @OTOOL@
73498
 
+OTOOL64 = @OTOOL64@
73499
 
+PACKAGE = @PACKAGE@
73500
 
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
73501
 
+PACKAGE_NAME = @PACKAGE_NAME@
73502
 
+PACKAGE_STRING = @PACKAGE_STRING@
73503
 
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
73504
 
+PACKAGE_URL = @PACKAGE_URL@
73505
 
+PACKAGE_VERSION = @PACKAGE_VERSION@
73506
 
+PATH_SEPARATOR = @PATH_SEPARATOR@
73507
 
+RAND_LIBS = @RAND_LIBS@
73508
 
+RANLIB = @RANLIB@
73509
 
+SED = @SED@
73510
 
+SET_MAKE = @SET_MAKE@
73511
 
+SHELL = @SHELL@
73512
 
+STORAGE_LIBS = @STORAGE_LIBS@
73513
 
+STRIP = @STRIP@
73514
 
+VERSION = @VERSION@
73515
 
+abs_builddir = @abs_builddir@
73516
 
+abs_srcdir = @abs_srcdir@
73517
 
+abs_top_builddir = @abs_top_builddir@
73518
 
+abs_top_srcdir = @abs_top_srcdir@
73519
 
+ac_ct_CC = @ac_ct_CC@
73520
 
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
73521
 
+am__include = @am__include@
73522
 
+am__leading_dot = @am__leading_dot@
73523
 
+am__quote = @am__quote@
73524
 
+am__tar = @am__tar@
73525
 
+am__untar = @am__untar@
73526
 
+bindir = @bindir@
73527
 
+build = @build@
73528
 
+build_alias = @build_alias@
73529
 
+build_cpu = @build_cpu@
73530
 
+build_os = @build_os@
73531
 
+build_vendor = @build_vendor@
73532
 
+builddir = @builddir@
73533
 
+datadir = @datadir@
73534
 
+datarootdir = @datarootdir@
73535
 
+docdir = @docdir@
73536
 
+dovecot_incdir = @dovecot_incdir@
73537
 
+dovecotdir = @dovecotdir@
73538
 
+dvidir = @dvidir@
73539
 
+exec_prefix = @exec_prefix@
73540
 
+host = @host@
73541
 
+host_alias = @host_alias@
73542
 
+host_cpu = @host_cpu@
73543
 
+host_os = @host_os@
73544
 
+host_vendor = @host_vendor@
73545
 
+htmldir = @htmldir@
73546
 
+includedir = @includedir@
73547
 
+infodir = @infodir@
73548
 
+install_sh = @install_sh@
73549
 
+libdir = @libdir@
73550
 
+libexecdir = @libexecdir@
73551
 
+localedir = @localedir@
73552
 
+localstatedir = @localstatedir@
73553
 
+lt_ECHO = @lt_ECHO@
73554
 
+mandir = @mandir@
73555
 
+mkdir_p = @mkdir_p@
73556
 
+moduledir = @moduledir@
73557
 
+oldincludedir = @oldincludedir@
73558
 
+pdfdir = @pdfdir@
73559
 
+prefix = @prefix@
73560
 
+program_transform_name = @program_transform_name@
73561
 
+psdir = @psdir@
73562
 
+sbindir = @sbindir@
73563
 
+sharedstatedir = @sharedstatedir@
73564
 
+srcdir = @srcdir@
73565
 
+sysconfdir = @sysconfdir@
73566
 
+target_alias = @target_alias@
73567
 
+top_build_prefix = @top_build_prefix@
73568
 
+top_builddir = @top_builddir@
73569
 
+top_srcdir = @top_srcdir@
73570
 
+noinst_LTLIBRARIES = libsieve_ext_variables.la
73571
 
+AM_CPPFLAGS = \
73572
 
+       -I../../ \
73573
 
+       -I$(dovecot_incdir) \
73574
 
+       -I$(dovecot_incdir)/src/lib \
73575
 
+       -I$(dovecot_incdir)/src/lib-mail \
73576
 
+       -I$(dovecot_incdir)/src/lib-storage 
73577
 
+
73578
 
+cmds = \
73579
 
+       cmd-set.c
73580
 
+
73581
 
+tsts = \
73582
 
+       tst-string.c
73583
 
+
73584
 
+libsieve_ext_variables_la_SOURCES = \
73585
 
+       ext-variables-common.c \
73586
 
+       ext-variables-name.c \
73587
 
+       ext-variables-arguments.c \
73588
 
+       ext-variables-operands.c \
73589
 
+       ext-variables-modifiers.c \
73590
 
+       ext-variables-dump.c \
73591
 
+       $(cmds) \
73592
 
+       $(tsts) \
73593
 
+       ext-variables.c
73594
 
+
73595
 
+noinst_HEADERS = \
73596
 
+       ext-variables-common.h \
73597
 
+       ext-variables-limits.h \
73598
 
+       ext-variables-name.h \
73599
 
+       ext-variables-arguments.h \
73600
 
+       ext-variables-operands.h \
73601
 
+       ext-variables-modifiers.h \
73602
 
+       ext-variables-dump.h \
73603
 
+       sieve-ext-variables.h 
73604
 
+
73605
 
+all: all-am
73606
 
+
73607
 
+.SUFFIXES:
73608
 
+.SUFFIXES: .c .lo .o .obj
73609
 
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
73610
 
+       @for dep in $?; do \
73611
 
+         case '$(am__configure_deps)' in \
73612
 
+           *$$dep*) \
73613
 
+             ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
73614
 
+               && { if test -f $@; then exit 0; else break; fi; }; \
73615
 
+             exit 1;; \
73616
 
+         esac; \
73617
 
+       done; \
73618
 
+       echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign  src/lib-sieve/plugins/variables/Makefile'; \
73619
 
+       cd $(top_srcdir) && \
73620
 
+         $(AUTOMAKE) --foreign  src/lib-sieve/plugins/variables/Makefile
73621
 
+.PRECIOUS: Makefile
73622
 
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
73623
 
+       @case '$?' in \
73624
 
+         *config.status*) \
73625
 
+           cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
73626
 
+         *) \
73627
 
+           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
73628
 
+           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
73629
 
+       esac;
73630
 
+
73631
 
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
73632
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
73633
 
+
73634
 
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
73635
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
73636
 
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
73637
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
73638
 
+
73639
 
+clean-noinstLTLIBRARIES:
73640
 
+       -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
73641
 
+       @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
73642
 
+         dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
73643
 
+         test "$$dir" != "$$p" || dir=.; \
73644
 
+         echo "rm -f \"$${dir}/so_locations\""; \
73645
 
+         rm -f "$${dir}/so_locations"; \
73646
 
+       done
73647
 
+libsieve_ext_variables.la: $(libsieve_ext_variables_la_OBJECTS) $(libsieve_ext_variables_la_DEPENDENCIES) 
73648
 
+       $(LINK)  $(libsieve_ext_variables_la_OBJECTS) $(libsieve_ext_variables_la_LIBADD) $(LIBS)
73649
 
+
73650
 
+mostlyclean-compile:
73651
 
+       -rm -f *.$(OBJEXT)
73652
 
+
73653
 
+distclean-compile:
73654
 
+       -rm -f *.tab.c
73655
 
+
73656
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd-set.Plo@am__quote@
73657
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-variables-arguments.Plo@am__quote@
73658
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-variables-common.Plo@am__quote@
73659
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-variables-dump.Plo@am__quote@
73660
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-variables-modifiers.Plo@am__quote@
73661
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-variables-name.Plo@am__quote@
73662
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-variables-operands.Plo@am__quote@
73663
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-variables.Plo@am__quote@
73664
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tst-string.Plo@am__quote@
73665
 
+
73666
 
+.c.o:
73667
 
+@am__fastdepCC_TRUE@   $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
73668
 
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
73669
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
73670
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
73671
 
+@am__fastdepCC_FALSE@  $(COMPILE) -c $<
73672
 
+
73673
 
+.c.obj:
73674
 
+@am__fastdepCC_TRUE@   $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
73675
 
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
73676
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
73677
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
73678
 
+@am__fastdepCC_FALSE@  $(COMPILE) -c `$(CYGPATH_W) '$<'`
73679
 
+
73680
 
+.c.lo:
73681
 
+@am__fastdepCC_TRUE@   $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
73682
 
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
73683
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
73684
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
73685
 
+@am__fastdepCC_FALSE@  $(LTCOMPILE) -c -o $@ $<
73686
 
+
73687
 
+mostlyclean-libtool:
73688
 
+       -rm -f *.lo
73689
 
+
73690
 
+clean-libtool:
73691
 
+       -rm -rf .libs _libs
73692
 
+
73693
 
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
73694
 
+       list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
73695
 
+       unique=`for i in $$list; do \
73696
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
73697
 
+         done | \
73698
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
73699
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
73700
 
+       mkid -fID $$unique
73701
 
+tags: TAGS
73702
 
+
73703
 
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
73704
 
+               $(TAGS_FILES) $(LISP)
73705
 
+       tags=; \
73706
 
+       here=`pwd`; \
73707
 
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
73708
 
+       unique=`for i in $$list; do \
73709
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
73710
 
+         done | \
73711
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
73712
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
73713
 
+       if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
73714
 
+         test -n "$$unique" || unique=$$empty_fix; \
73715
 
+         $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
73716
 
+           $$tags $$unique; \
73717
 
+       fi
73718
 
+ctags: CTAGS
73719
 
+CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
73720
 
+               $(TAGS_FILES) $(LISP)
73721
 
+       tags=; \
73722
 
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
73723
 
+       unique=`for i in $$list; do \
73724
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
73725
 
+         done | \
73726
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
73727
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
73728
 
+       test -z "$(CTAGS_ARGS)$$tags$$unique" \
73729
 
+         || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
73730
 
+            $$tags $$unique
73731
 
+
73732
 
+GTAGS:
73733
 
+       here=`$(am__cd) $(top_builddir) && pwd` \
73734
 
+         && cd $(top_srcdir) \
73735
 
+         && gtags -i $(GTAGS_ARGS) $$here
73736
 
+
73737
 
+distclean-tags:
73738
 
+       -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
73739
 
+
73740
 
+distdir: $(DISTFILES)
73741
 
+       @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
73742
 
+       topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
73743
 
+       list='$(DISTFILES)'; \
73744
 
+         dist_files=`for file in $$list; do echo $$file; done | \
73745
 
+         sed -e "s|^$$srcdirstrip/||;t" \
73746
 
+             -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
73747
 
+       case $$dist_files in \
73748
 
+         */*) $(MKDIR_P) `echo "$$dist_files" | \
73749
 
+                          sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
73750
 
+                          sort -u` ;; \
73751
 
+       esac; \
73752
 
+       for file in $$dist_files; do \
73753
 
+         if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
73754
 
+         if test -d $$d/$$file; then \
73755
 
+           dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
73756
 
+           if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
73757
 
+             cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
73758
 
+           fi; \
73759
 
+           cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
73760
 
+         else \
73761
 
+           test -f $(distdir)/$$file \
73762
 
+           || cp -p $$d/$$file $(distdir)/$$file \
73763
 
+           || exit 1; \
73764
 
+         fi; \
73765
 
+       done
73766
 
+check-am: all-am
73767
 
+check: check-am
73768
 
+all-am: Makefile $(LTLIBRARIES) $(HEADERS)
73769
 
+installdirs:
73770
 
+install: install-am
73771
 
+install-exec: install-exec-am
73772
 
+install-data: install-data-am
73773
 
+uninstall: uninstall-am
73774
 
+
73775
 
+install-am: all-am
73776
 
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
73777
 
+
73778
 
+installcheck: installcheck-am
73779
 
+install-strip:
73780
 
+       $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
73781
 
+         install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
73782
 
+         `test -z '$(STRIP)' || \
73783
 
+           echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
73784
 
+mostlyclean-generic:
73785
 
+
73786
 
+clean-generic:
73787
 
+
73788
 
+distclean-generic:
73789
 
+       -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
73790
 
+
73791
 
+maintainer-clean-generic:
73792
 
+       @echo "This command is intended for maintainers to use"
73793
 
+       @echo "it deletes files that may require special tools to rebuild."
73794
 
+clean: clean-am
73795
 
+
73796
 
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
73797
 
+       mostlyclean-am
73798
 
+
73799
 
+distclean: distclean-am
73800
 
+       -rm -rf ./$(DEPDIR)
73801
 
+       -rm -f Makefile
73802
 
+distclean-am: clean-am distclean-compile distclean-generic \
73803
 
+       distclean-tags
73804
 
+
73805
 
+dvi: dvi-am
73806
 
+
73807
 
+dvi-am:
73808
 
+
73809
 
+html: html-am
73810
 
+
73811
 
+info: info-am
73812
 
+
73813
 
+info-am:
73814
 
+
73815
 
+install-data-am:
73816
 
+
73817
 
+install-dvi: install-dvi-am
73818
 
+
73819
 
+install-exec-am:
73820
 
+
73821
 
+install-html: install-html-am
73822
 
+
73823
 
+install-info: install-info-am
73824
 
+
73825
 
+install-man:
73826
 
+
73827
 
+install-pdf: install-pdf-am
73828
 
+
73829
 
+install-ps: install-ps-am
73830
 
+
73831
 
+installcheck-am:
73832
 
+
73833
 
+maintainer-clean: maintainer-clean-am
73834
 
+       -rm -rf ./$(DEPDIR)
73835
 
+       -rm -f Makefile
73836
 
+maintainer-clean-am: distclean-am maintainer-clean-generic
73837
 
+
73838
 
+mostlyclean: mostlyclean-am
73839
 
+
73840
 
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
73841
 
+       mostlyclean-libtool
73842
 
+
73843
 
+pdf: pdf-am
73844
 
+
73845
 
+pdf-am:
73846
 
+
73847
 
+ps: ps-am
73848
 
+
73849
 
+ps-am:
73850
 
+
73851
 
+uninstall-am:
73852
 
+
73853
 
+.MAKE: install-am install-strip
73854
 
+
73855
 
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
73856
 
+       clean-libtool clean-noinstLTLIBRARIES ctags distclean \
73857
 
+       distclean-compile distclean-generic distclean-libtool \
73858
 
+       distclean-tags distdir dvi dvi-am html html-am info info-am \
73859
 
+       install install-am install-data install-data-am install-dvi \
73860
 
+       install-dvi-am install-exec install-exec-am install-html \
73861
 
+       install-html-am install-info install-info-am install-man \
73862
 
+       install-pdf install-pdf-am install-ps install-ps-am \
73863
 
+       install-strip installcheck installcheck-am installdirs \
73864
 
+       maintainer-clean maintainer-clean-generic mostlyclean \
73865
 
+       mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
73866
 
+       pdf pdf-am ps ps-am tags uninstall uninstall-am
73867
 
+
73868
 
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
73869
 
+# Otherwise a system limit (for SysV at least) may be exceeded.
73870
 
+.NOEXPORT:
73871
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/variables/sieve-ext-variables.h dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/variables/sieve-ext-variables.h
73872
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/variables/sieve-ext-variables.h        1970-01-01 01:00:00.000000000 +0100
73873
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/variables/sieve-ext-variables.h 2009-01-06 00:15:52.000000000 +0100
73874
 
@@ -0,0 +1,164 @@
73875
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
73876
 
+ */
73877
 
+
73878
 
+/* 
73879
 
+ * Public interface for other extensions to use 
73880
 
+ */
73881
 
73882
 
+#ifndef __SIEVE_EXT_VARIABLES_H
73883
 
+#define __SIEVE_EXT_VARIABLES_H
73884
 
+
73885
 
+#include "sieve-common.h"
73886
 
+#include "sieve-extensions.h"
73887
 
+#include "sieve-objects.h"
73888
 
+
73889
 
+#include "ext-variables-limits.h"
73890
 
+
73891
 
+/*
73892
 
+ * Variable scope
73893
 
+ */
73894
 
+
73895
 
+struct sieve_variable {
73896
 
+       const char *identifier;
73897
 
+       unsigned int index;
73898
 
+
73899
 
+       const struct sieve_extension *ext;
73900
 
+       void *context;
73901
 
+};
73902
 
+
73903
 
+struct sieve_variable_scope;
73904
 
+
73905
 
+struct sieve_variable_scope *sieve_variable_scope_create
73906
 
+       (const struct sieve_extension *ext);
73907
 
+void sieve_variable_scope_ref
73908
 
+       (struct sieve_variable_scope *scope);
73909
 
+void sieve_variable_scope_unref
73910
 
+       (struct sieve_variable_scope **scope);
73911
 
+pool_t sieve_variable_scope_pool
73912
 
+       (struct sieve_variable_scope *scope);
73913
 
+
73914
 
+struct sieve_variable *sieve_variable_scope_declare
73915
 
+       (struct sieve_variable_scope *scope, const char *identifier);
73916
 
+struct sieve_variable *sieve_variable_scope_import
73917
 
+       (struct sieve_variable_scope *scope, struct sieve_variable *var);
73918
 
+struct sieve_variable *sieve_variable_scope_get_variable
73919
 
+       (struct sieve_variable_scope *scope, const char *identifier, bool create);
73920
 
+struct sieve_variable *sieve_variable_scope_get_indexed
73921
 
+       (struct sieve_variable_scope *scope, unsigned int index);
73922
 
+
73923
 
+/* Iteration over all declared variables */
73924
 
+
73925
 
+struct sieve_variable_scope_iter;
73926
 
+
73927
 
+struct sieve_variable_scope_iter *sieve_variable_scope_iterate_init
73928
 
+       (struct sieve_variable_scope *scope);
73929
 
+bool sieve_variable_scope_iterate
73930
 
+       (struct sieve_variable_scope_iter *iter, struct sieve_variable **var_r);
73931
 
+void sieve_variable_scope_iterate_deinit
73932
 
+       (struct sieve_variable_scope_iter **iter);
73933
 
+
73934
 
+/* Statistics */
73935
 
+
73936
 
+unsigned int sieve_variable_scope_declarations
73937
 
+       (struct sieve_variable_scope *scope);
73938
 
+unsigned int sieve_variable_scope_size
73939
 
+       (struct sieve_variable_scope *scope);
73940
 
+
73941
 
+/* Get all native variables */
73942
 
+
73943
 
+struct sieve_variable * const *sieve_variable_scope_get_variables
73944
 
+       (struct sieve_variable_scope *scope, unsigned int *size_r);
73945
 
+
73946
 
+/* 
73947
 
+ * Variable storage
73948
 
+ */    
73949
 
+       
73950
 
+struct sieve_variable_storage;
73951
 
+
73952
 
+struct sieve_variable_storage *sieve_variable_storage_create
73953
 
+       (pool_t pool, struct sieve_variable_scope *scope, unsigned int max_size);
73954
 
+bool sieve_variable_get
73955
 
+       (struct sieve_variable_storage *storage, unsigned int index, 
73956
 
+               string_t **value);
73957
 
+bool sieve_variable_get_modifiable
73958
 
+       (struct sieve_variable_storage *storage, unsigned int index, 
73959
 
+               string_t **value);
73960
 
+bool sieve_variable_assign
73961
 
+       (struct sieve_variable_storage *storage, unsigned int index, 
73962
 
+               const string_t *value);
73963
 
+bool sieve_variable_get_identifier
73964
 
+       (struct sieve_variable_storage *storage, unsigned int index, 
73965
 
+               const char **identifier);
73966
 
+
73967
 
+/*
73968
 
+ * Variables access
73969
 
+ */
73970
 
+
73971
 
+bool sieve_ext_variables_is_active(struct sieve_validator *valdtr);
73972
 
+
73973
 
+struct sieve_variable_scope *sieve_ext_variables_get_main_scope
73974
 
+       (struct sieve_validator *validator);
73975
 
+       
73976
 
+struct sieve_variable_storage *sieve_ext_variables_get_storage
73977
 
+       (struct sieve_interpreter *interp, const struct sieve_extension *ext);
73978
 
+void sieve_ext_variables_set_storage
73979
 
+       (struct sieve_interpreter *interp, struct sieve_variable_storage *storage,
73980
 
+               const struct sieve_extension *ext);     
73981
 
+               
73982
 
+/* 
73983
 
+ * Variable arguments 
73984
 
+ */
73985
 
+
73986
 
+bool sieve_variable_argument_activate
73987
 
+(struct sieve_validator *validator, struct sieve_command_context *cmd, 
73988
 
+       struct sieve_ast_argument *arg, bool assignment);
73989
 
+       
73990
 
+/* 
73991
 
+ * Variable operands 
73992
 
+ */
73993
 
+
73994
 
+extern const struct sieve_operand variable_operand;
73995
 
+
73996
 
+bool sieve_variable_operand_read_data
73997
 
+       (const struct sieve_runtime_env *renv, const struct sieve_operand *operand, 
73998
 
+               sieve_size_t *address, struct sieve_variable_storage **storage, 
73999
 
+               unsigned int *var_index);
74000
 
+bool sieve_variable_operand_read
74001
 
+       (const struct sieve_runtime_env *renv, sieve_size_t *address, 
74002
 
+               struct sieve_variable_storage **storage, unsigned int *var_index);
74003
 
+               
74004
 
+static inline bool sieve_operand_is_variable
74005
 
+(const struct sieve_operand *operand)
74006
 
+{
74007
 
+       return ( operand != NULL && operand == &variable_operand );
74008
 
+}      
74009
 
+
74010
 
+/* 
74011
 
+ * Modifiers 
74012
 
+ */
74013
 
+
74014
 
+struct sieve_variables_modifier {
74015
 
+       struct sieve_object object;
74016
 
+       
74017
 
+       unsigned int precedence;
74018
 
+       
74019
 
+       bool (*modify)(string_t *in, string_t **result);
74020
 
+};
74021
 
+
74022
 
+extern const struct sieve_operand_class sieve_variables_modifier_operand_class;
74023
 
+
74024
 
+#define SIEVE_VARIABLES_DEFINE_MODIFIER(OP) SIEVE_EXT_DEFINE_OBJECT(OP)
74025
 
+#define SIEVE_VARIABLES_DEFINE_MODIFIERS(OPS) SIEVE_EXT_DEFINE_OBJECTS(OPS)
74026
 
+
74027
 
+void sieve_variables_modifier_register
74028
 
+       (struct sieve_validator *valdtr, const struct sieve_variables_modifier *smodf);
74029
 
+
74030
 
+/*
74031
 
+ * Code dumping
74032
 
+ */
74033
 
+
74034
 
+void sieve_ext_variables_dump_set_scope
74035
 
+(const struct sieve_dumptime_env *denv, const struct sieve_extension *ext, 
74036
 
+       struct sieve_variable_scope *scope);
74037
 
+
74038
 
+#endif /* __SIEVE_EXT_VARIABLES_H */
74039
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/variables/tst-string.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/variables/tst-string.c
74040
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/plugins/variables/tst-string.c 1970-01-01 01:00:00.000000000 +0100
74041
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/plugins/variables/tst-string.c  2009-07-30 00:44:58.000000000 +0200
74042
 
@@ -0,0 +1,242 @@
74043
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
74044
 
+ */
74045
 
+
74046
 
+#include "sieve-common.h"
74047
 
+#include "sieve-commands.h"
74048
 
+#include "sieve-code.h"
74049
 
+#include "sieve-comparators.h"
74050
 
+#include "sieve-match-types.h"
74051
 
+#include "sieve-validator.h"
74052
 
+#include "sieve-generator.h"
74053
 
+#include "sieve-interpreter.h"
74054
 
+#include "sieve-dump.h"
74055
 
+#include "sieve-match.h"
74056
 
+
74057
 
+#include "ext-variables-common.h"
74058
 
+
74059
 
+/* 
74060
 
+ * String test 
74061
 
+ *
74062
 
+ * Syntax:
74063
 
+ *   string [COMPARATOR] [MATCH-TYPE]
74064
 
+ *     <source: string-list> <key-list: string-list>
74065
 
+ */
74066
 
+
74067
 
+static bool tst_string_registered
74068
 
+       (struct sieve_validator *validator, struct sieve_command_registration *cmd_reg);
74069
 
+static bool tst_string_validate
74070
 
+       (struct sieve_validator *validator, struct sieve_command_context *tst);
74071
 
+static bool tst_string_generate
74072
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx);
74073
 
+
74074
 
+const struct sieve_command tst_string = { 
74075
 
+       "string", 
74076
 
+       SCT_TEST, 
74077
 
+       2, 0, FALSE, FALSE,
74078
 
+       tst_string_registered, 
74079
 
+       NULL,
74080
 
+       tst_string_validate, 
74081
 
+       tst_string_generate, 
74082
 
+       NULL 
74083
 
+};
74084
 
+
74085
 
+/* 
74086
 
+ * String operation
74087
 
+ */
74088
 
+
74089
 
+static bool tst_string_operation_dump
74090
 
+       (const struct sieve_operation *op, 
74091
 
+               const struct sieve_dumptime_env *denv, sieve_size_t *address);
74092
 
+static int tst_string_operation_execute
74093
 
+       (const struct sieve_operation *op, 
74094
 
+               const struct sieve_runtime_env *renv, sieve_size_t *address);
74095
 
+
74096
 
+const struct sieve_operation tst_string_operation = { 
74097
 
+       "STRING",
74098
 
+       &variables_extension, 
74099
 
+       EXT_VARIABLES_OPERATION_STRING, 
74100
 
+       tst_string_operation_dump, 
74101
 
+       tst_string_operation_execute 
74102
 
+};
74103
 
+
74104
 
+/* 
74105
 
+ * Optional arguments 
74106
 
+ */
74107
 
+
74108
 
+enum tst_string_optional {     
74109
 
+       OPT_END,
74110
 
+       OPT_COMPARATOR,
74111
 
+       OPT_MATCH_TYPE
74112
 
+};
74113
 
+
74114
 
+/* 
74115
 
+ * Test registration 
74116
 
+ */
74117
 
+
74118
 
+static bool tst_string_registered
74119
 
+       (struct sieve_validator *validator, struct sieve_command_registration *cmd_reg) 
74120
 
+{
74121
 
+       /* The order of these is not significant */
74122
 
+       sieve_comparators_link_tag(validator, cmd_reg, OPT_COMPARATOR);
74123
 
+       sieve_match_types_link_tags(validator, cmd_reg, OPT_MATCH_TYPE);
74124
 
+
74125
 
+       return TRUE;
74126
 
+}
74127
 
+
74128
 
+/* 
74129
 
+ * Test validation 
74130
 
+ */
74131
 
+
74132
 
+static bool tst_string_validate
74133
 
+       (struct sieve_validator *validator, struct sieve_command_context *tst) 
74134
 
+{              
74135
 
+       struct sieve_ast_argument *arg = tst->first_positional;
74136
 
+       
74137
 
+       if ( !sieve_validate_positional_argument
74138
 
+               (validator, tst, arg, "source", 1, SAAT_STRING_LIST) ) {
74139
 
+               return FALSE;
74140
 
+       }
74141
 
+       
74142
 
+       if ( !sieve_validator_argument_activate(validator, tst, arg, FALSE) )
74143
 
+               return FALSE;
74144
 
+       
74145
 
+       arg = sieve_ast_argument_next(arg);
74146
 
+
74147
 
+       if ( !sieve_validate_positional_argument
74148
 
+               (validator, tst, arg, "key list", 2, SAAT_STRING_LIST) ) {
74149
 
+               return FALSE;
74150
 
+       }
74151
 
+       
74152
 
+       if ( !sieve_validator_argument_activate(validator, tst, arg, FALSE) )
74153
 
+               return FALSE;
74154
 
+
74155
 
+       /* Validate the key argument to a specified match type */
74156
 
+       return sieve_match_type_validate
74157
 
+               (validator, tst, arg, &is_match_type, &i_octet_comparator);
74158
 
+}
74159
 
+
74160
 
+/* 
74161
 
+ * Test generation 
74162
 
+ */
74163
 
+
74164
 
+static bool tst_string_generate
74165
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx) 
74166
 
+{
74167
 
+       sieve_operation_emit_code(cgenv->sbin, &tst_string_operation);
74168
 
+
74169
 
+       /* Generate arguments */
74170
 
+       if ( !sieve_generate_arguments(cgenv, ctx, NULL) )
74171
 
+               return FALSE;
74172
 
+       
74173
 
+       return TRUE;
74174
 
+}
74175
 
+
74176
 
+/* 
74177
 
+ * Code dump 
74178
 
+ */
74179
 
+
74180
 
+static bool tst_string_operation_dump
74181
 
+(const struct sieve_operation *op ATTR_UNUSED,
74182
 
+       const struct sieve_dumptime_env *denv, sieve_size_t *address)
74183
 
+{
74184
 
+       int opt_code = 0;
74185
 
+
74186
 
+       sieve_code_dumpf(denv, "STRING-TEST");
74187
 
+       sieve_code_descend(denv);
74188
 
+
74189
 
+       /* Handle any optional arguments */
74190
 
+       if ( !sieve_match_dump_optional_operands(denv, address, &opt_code) )
74191
 
+               return FALSE;
74192
 
+
74193
 
+       if ( opt_code != SIEVE_MATCH_OPT_END )
74194
 
+               return FALSE;
74195
 
+               
74196
 
+       return
74197
 
+               sieve_opr_stringlist_dump(denv, address, "source") &&
74198
 
+               sieve_opr_stringlist_dump(denv, address, "key list");
74199
 
+}
74200
 
+
74201
 
+/* 
74202
 
+ * Code execution 
74203
 
+ */
74204
 
+
74205
 
+static int tst_string_operation_execute
74206
 
+(const struct sieve_operation *op ATTR_UNUSED, 
74207
 
+       const struct sieve_runtime_env *renv, sieve_size_t *address)
74208
 
+{
74209
 
+       int ret, mret;
74210
 
+       bool result = TRUE;
74211
 
+       int opt_code = 0;
74212
 
+       const struct sieve_comparator *cmp = &i_octet_comparator;
74213
 
+       const struct sieve_match_type *mtch = &is_match_type;
74214
 
+       struct sieve_match_context *mctx;
74215
 
+       struct sieve_coded_stringlist *source;
74216
 
+       struct sieve_coded_stringlist *key_list;
74217
 
+       string_t *src_item;
74218
 
+       bool matched;
74219
 
+
74220
 
+       /*
74221
 
+        * Read operands 
74222
 
+        */
74223
 
+       
74224
 
+       /* Handle match-type and comparator operands */
74225
 
+       if ( (ret=sieve_match_read_optional_operands
74226
 
+               (renv, address, &opt_code, &cmp, &mtch)) <= 0 )
74227
 
+               return ret;
74228
 
+       
74229
 
+       /* Check whether we neatly finished the list of optional operands*/
74230
 
+       if ( opt_code != SIEVE_MATCH_OPT_END) {
74231
 
+               sieve_runtime_trace_error(renv, "invalid optional operand");
74232
 
+               return SIEVE_EXEC_BIN_CORRUPT;
74233
 
+       }
74234
 
+
74235
 
+       /* Read source */
74236
 
+       if ( (source=sieve_opr_stringlist_read(renv, address)) == NULL ) {
74237
 
+               sieve_runtime_trace_error(renv, "invalid source operand");
74238
 
+               return SIEVE_EXEC_BIN_CORRUPT;
74239
 
+       }
74240
 
+       
74241
 
+       /* Read key-list */
74242
 
+       if ( (key_list=sieve_opr_stringlist_read(renv, address)) == NULL ) {
74243
 
+               sieve_runtime_trace_error(renv, "invalid key-list operand");
74244
 
+               return SIEVE_EXEC_BIN_CORRUPT;
74245
 
+       }
74246
 
+
74247
 
+       /*
74248
 
+        * Perform operation
74249
 
+        */
74250
 
+
74251
 
+       sieve_runtime_trace(renv, "STRING test");
74252
 
+
74253
 
+       mctx = sieve_match_begin(renv->interp, mtch, cmp, NULL, key_list);      
74254
 
+
74255
 
+       /* Iterate through all requested strings to match */
74256
 
+       src_item = NULL;
74257
 
+       matched = FALSE;
74258
 
+       while ( result && !matched && 
74259
 
+               (result=sieve_coded_stringlist_next_item(source, &src_item)) 
74260
 
+               && src_item != NULL ) {
74261
 
+               const char *src = str_len(src_item) > 0 ? str_c(src_item) : NULL;
74262
 
+
74263
 
+               if ( (mret=sieve_match_value
74264
 
+                       (mctx, src, str_len(src_item))) < 0 ) {
74265
 
+                       result = FALSE;
74266
 
+                       break;
74267
 
+               }
74268
 
+               
74269
 
+               matched = ( mret > 0 );                         
74270
 
+       }
74271
 
+
74272
 
+       if ( (mret=sieve_match_end(&mctx)) < 0 ) 
74273
 
+               result = FALSE;
74274
 
+       else
74275
 
+               matched = ( mret > 0 || matched );      
74276
 
+       
74277
 
+       if ( result ) {
74278
 
+               sieve_interpreter_set_test_result(renv->interp, matched);
74279
 
+               return SIEVE_EXEC_OK;
74280
 
+       }
74281
 
+       
74282
 
+       sieve_runtime_trace_error(renv, "invalid string list item");
74283
 
+       return SIEVE_EXEC_BIN_CORRUPT;
74284
 
+}
74285
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/rfc2822.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/rfc2822.c
74286
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/rfc2822.c      1970-01-01 01:00:00.000000000 +0100
74287
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/rfc2822.c       2009-07-15 19:34:45.000000000 +0200
74288
 
@@ -0,0 +1,207 @@
74289
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file 
74290
 
+ */
74291
 
+
74292
 
+/* NOTE: much of the functionality implemented here should eventually appear
74293
 
+ * somewhere in Dovecot itself.
74294
 
+ */
74295
 
+
74296
 
+#include "lib.h"
74297
 
+#include "str.h"
74298
 
+
74299
 
+#include "rfc2822.h"
74300
 
+
74301
 
+#include <stdio.h>
74302
 
+#include <ctype.h>
74303
 
74304
 
+bool rfc2822_header_field_name_verify
74305
 
+(const char *field_name, unsigned int len) 
74306
 
+{
74307
 
+       const char *p = field_name;
74308
 
+       const char *pend = p + len;
74309
 
+
74310
 
+       /* field-name   =   1*ftext
74311
 
+        * ftext        =   %d33-57 /               ; Any character except
74312
 
+        *                  %d59-126                ;  controls, SP, and
74313
 
+        *                                          ;  ":".
74314
 
+        */
74315
 
+        
74316
 
+       while ( p < pend ) {
74317
 
+               if ( *p < 33 || *p == ':' )
74318
 
+                       return FALSE;
74319
 
+
74320
 
+               p++;
74321
 
+       }       
74322
 
+       
74323
 
+       return TRUE;
74324
 
+}
74325
 
+
74326
 
+bool rfc2822_header_field_body_verify
74327
 
+(const char *field_body, unsigned int len) 
74328
 
+{
74329
 
+       const char *p = field_body;
74330
 
+       const char *pend = p + len;
74331
 
+
74332
 
+       /* unstructured    =       *([FWS] utext) [FWS]
74333
 
+        * FWS             =       ([*WSP CRLF] 1*WSP) /   ; Folding white space
74334
 
+        *                         obs-FWS
74335
 
+        * utext           =       NO-WS-CTL /     ; Non white space controls
74336
 
+        *                         %d33-126 /      ; The rest of US-ASCII
74337
 
+        *                         obs-utext
74338
 
+        * NO-WS-CTL       =       %d1-8 /         ; US-ASCII control characters
74339
 
+        *                         %d11 /          ;  that do not include the
74340
 
+        *                         %d12 /          ;  carriage return, line feed,
74341
 
+        *                         %d14-31 /       ;  and white space characters
74342
 
+        *                         %d127
74343
 
+        * WSP             =  SP / HTAB
74344
 
+        */
74345
 
+
74346
 
+       /* This verification does not allow content to be folded. This should done
74347
 
+        * automatically upon message composition.
74348
 
+        */
74349
 
+
74350
 
+       while ( p < pend ) {
74351
 
+               if ( *p == '\0' || *p == '\r' || *p == '\n' || ((unsigned char)*p) > 127 )
74352
 
+                       return FALSE;
74353
 
+
74354
 
+               p++;
74355
 
+       }       
74356
 
+       
74357
 
+       return TRUE;
74358
 
+}
74359
 
+
74360
 
+/*
74361
 
+ *
74362
 
+ */
74363
 
+
74364
 
+const char *rfc2822_header_field_name_sanitize(const char *name)
74365
 
+{
74366
 
+       char *result = t_strdup_noconst(name);
74367
 
+       char *p;
74368
 
+       
74369
 
+       /* Make the whole name lower case ... */
74370
 
+       result = str_lcase(result);
74371
 
+
74372
 
+       /* ... except for the first letter and those that follow '-' */
74373
 
+       p = result;
74374
 
+       *p = i_toupper(*p);
74375
 
+       while ( *p != '\0' ) {
74376
 
+               if ( *p == '-' ) {
74377
 
+                       p++;
74378
 
+                       
74379
 
+                       if ( *p != '\0' )
74380
 
+                               *p = i_toupper(*p);
74381
 
+                       
74382
 
+                       continue;
74383
 
+               }
74384
 
+               
74385
 
+               p++;
74386
 
+       }
74387
 
+       
74388
 
+       return result;
74389
 
+}
74390
 
+
74391
 
+/*
74392
 
+ * Message construction
74393
 
+ */
74394
 
74395
 
+/* FIXME: This should be collected into a Dovecot API for composing internet
74396
 
+ * mail messages. These functions now use FILE * output streams, but this should
74397
 
+ * be changed to proper dovecot streams.
74398
 
+ */
74399
 
+
74400
 
+static inline bool rfc2822_write(FILE *f, const char *data, size_t len)
74401
 
+{
74402
 
+       return ( fwrite(data, len, 1, f) == 1 );
74403
 
+}
74404
 
+
74405
 
+int rfc2822_header_field_write
74406
 
+(FILE *f, const char *name, const char *body)
74407
 
+{
74408
 
+       static const unsigned int max_line = 80;
74409
 
+       
74410
 
+       const char *bp = body;  /* Pointer */ 
74411
 
+       const char *sp = body;  /* Start pointer */
74412
 
+       const char *wp = NULL;  /* Whitespace pointer */ 
74413
 
+       const char *nlp = NULL; /* New-line pointer */
74414
 
+       unsigned int line_len = strlen(name);
74415
 
+       int len = 0;
74416
 
+       
74417
 
+       /* Write header field name first */
74418
 
+       if ( !rfc2822_write(f, name, line_len) || !rfc2822_write(f, ": ", 2) )
74419
 
+               return -1;
74420
 
+
74421
 
+       line_len +=  2;
74422
 
+       len += line_len;
74423
 
+               
74424
 
+       /* Add field body; fold it if necessary and account for existing folding */
74425
 
+       while ( *bp != '\0' ) {
74426
 
+               while ( *bp != '\0' && nlp == NULL && (wp == NULL || line_len < max_line) ) {
74427
 
+                       if ( *bp == ' ' || *bp == '\t' ) {
74428
 
+                               wp = bp;
74429
 
+                       } else if ( *bp == '\r' || *bp == '\n' ) {
74430
 
+                               nlp = bp;                       
74431
 
+                               break;
74432
 
+                       }
74433
 
+
74434
 
+                       bp++; line_len++;
74435
 
+               }
74436
 
+               
74437
 
+               if ( *bp == '\0' ) break;
74438
 
+               
74439
 
+               /* Existing newline ? */
74440
 
+               if ( nlp != NULL ) {
74441
 
+                       /* Replace any sort of newline with LF */
74442
 
+                       while ( *bp == '\r' || *bp == '\n' )
74443
 
+                               bp++;
74444
 
+                       
74445
 
+                       if ( !rfc2822_write(f, sp, nlp-sp) )
74446
 
+                               return -1;
74447
 
+                       len += nlp-sp;
74448
 
+                       
74449
 
+                       if ( *bp != '\0' && *bp != ' ' && *bp != '\t' ) {
74450
 
+                               if ( !rfc2822_write(f, "\r\n\t", 3) )
74451
 
+                                       return -1;
74452
 
+                               len += 3;
74453
 
+                       } else {
74454
 
+                               if ( !rfc2822_write(f, "\r\n", 2) )
74455
 
+                                       return -1;
74456
 
+                               len += 2;
74457
 
+                       }
74458
 
+
74459
 
+                       sp = bp;
74460
 
+               } else {
74461
 
+                       /* Insert newline at last whitespace within the max_line limit */
74462
 
+                       if ( !rfc2822_write(f, sp, wp-sp) || !rfc2822_write(f, "\r\n", 2) )
74463
 
+                               return -1;
74464
 
+                       len += (wp-sp) + 2;
74465
 
+               
74466
 
+                       sp = wp;
74467
 
+               }
74468
 
+               
74469
 
+               line_len = bp - sp;             
74470
 
+               wp = NULL;
74471
 
+               nlp = NULL;
74472
 
+       }
74473
 
+       
74474
 
+       if ( bp != sp ) {
74475
 
+               if ( !rfc2822_write(f, sp, bp-sp) || !rfc2822_write(f, "\r\n", 2) )
74476
 
+                       return -1;
74477
 
+               len += (bp-sp) + 2;
74478
 
+       }
74479
 
+
74480
 
+       return len;
74481
 
+}
74482
 
+
74483
 
+int rfc2822_header_field_printf
74484
 
+(FILE *f, const char *name, const char *body_fmt, ...)
74485
 
+{
74486
 
+       string_t *body = t_str_new(256);
74487
 
+       va_list args;
74488
 
+
74489
 
+       va_start(args, body_fmt);
74490
 
+       str_vprintfa(body, body_fmt, args);
74491
 
+       va_end(args);
74492
 
+       
74493
 
+       return rfc2822_header_field_write(f, name, str_c(body));
74494
 
+}
74495
 
+
74496
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/rfc2822.h dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/rfc2822.h
74497
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/rfc2822.h      1970-01-01 01:00:00.000000000 +0100
74498
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/rfc2822.h       2009-07-15 19:32:31.000000000 +0200
74499
 
@@ -0,0 +1,36 @@
74500
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file 
74501
 
+ */
74502
 
+
74503
 
+#ifndef __RFC2822_H
74504
 
+#define __RFC2822_H
74505
 
+
74506
 
+#include "lib.h"
74507
 
+
74508
 
+#include <stdio.h>
74509
 
+
74510
 
+/*
74511
 
+ * Verification
74512
 
+ */ 
74513
 
74514
 
+bool rfc2822_header_field_name_verify
74515
 
+       (const char *field_name, unsigned int len);
74516
 
+bool rfc2822_header_field_body_verify
74517
 
+(const char *field_body, unsigned int len);
74518
 
+
74519
 
+/*
74520
 
+ *
74521
 
+ */
74522
 
+
74523
 
+const char *rfc2822_header_field_name_sanitize(const char *name);
74524
 
+
74525
 
+/*
74526
 
+ * Message composition
74527
 
+ */
74528
 
+
74529
 
+int rfc2822_header_field_write
74530
 
+       (FILE *f, const char *name, const char *body);
74531
 
+       
74532
 
+int rfc2822_header_field_printf
74533
 
+       (FILE *f, const char *name, const char *body_fmt, ...) ATTR_FORMAT(3, 4);
74534
 
+
74535
 
+#endif /* __RFC2822_H */
74536
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-actions.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-actions.c
74537
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-actions.c        1970-01-01 01:00:00.000000000 +0100
74538
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-actions.c 2009-07-27 13:30:18.000000000 +0200
74539
 
@@ -0,0 +1,604 @@
74540
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file 
74541
 
+ */
74542
 
+
74543
 
+#include "lib.h"
74544
 
+#include "strfuncs.h"
74545
 
+#include "str-sanitize.h"
74546
 
+#include "mail-storage.h"
74547
 
+#include "mail-namespace.h"
74548
 
+
74549
 
+#include "sieve-code.h"
74550
 
+#include "sieve-extensions.h"
74551
 
+#include "sieve-binary.h"
74552
 
+#include "sieve-interpreter.h"
74553
 
+#include "sieve-dump.h"
74554
 
+#include "sieve-result.h"
74555
 
+#include "sieve-actions.h"
74556
 
+
74557
 
+#include <ctype.h>
74558
 
+
74559
 
+/*
74560
 
+ * Action execution environment
74561
 
+ */
74562
 
+
74563
 
+const char *sieve_action_get_location(const struct sieve_action_exec_env *aenv)
74564
 
+{
74565
 
+       return t_strdup_printf("msgid=%s", aenv->msgdata->id == NULL ?
74566
 
+               "unspecified" : str_sanitize(aenv->msgdata->id, 80));
74567
 
+}
74568
 
+
74569
 
+/*
74570
 
+ * Side-effect operand
74571
 
+ */
74572
 
74573
 
+const struct sieve_operand_class sieve_side_effect_operand_class = 
74574
 
+       { "SIDE-EFFECT" };
74575
 
+
74576
 
+bool sieve_opr_side_effect_dump
74577
 
+(const struct sieve_dumptime_env *denv, sieve_size_t *address)
74578
 
+{
74579
 
+       const struct sieve_object *obj;
74580
 
+       const struct sieve_side_effect *seffect;
74581
 
+       
74582
 
+       if ( !sieve_opr_object_dump
74583
 
+               (denv, &sieve_side_effect_operand_class, address, &obj) )
74584
 
+               return FALSE;
74585
 
+       
74586
 
+       seffect = (const struct sieve_side_effect *) obj;
74587
 
+
74588
 
+       if ( seffect->dump_context != NULL ) {
74589
 
+               sieve_code_descend(denv);
74590
 
+               if ( !seffect->dump_context(seffect, denv, address) ) {
74591
 
+                       return FALSE;   
74592
 
+               }
74593
 
+               sieve_code_ascend(denv);
74594
 
+       }
74595
 
+
74596
 
+       return TRUE;
74597
 
+}
74598
 
+
74599
 
+/*
74600
 
+ * Store action
74601
 
+ */
74602
 
74603
 
+/* Forward declarations */
74604
 
+
74605
 
+static bool act_store_equals
74606
 
+       (const struct sieve_script_env *senv, const void *ctx1, const void *ctx2);
74607
 
+       
74608
 
+static int act_store_check_duplicate
74609
 
+       (const struct sieve_runtime_env *renv, 
74610
 
+               const struct sieve_action_data *act, 
74611
 
+               const struct sieve_action_data *act_other);
74612
 
+static void act_store_print
74613
 
+       (const struct sieve_action *action, 
74614
 
+               const struct sieve_result_print_env *rpenv, void *context, bool *keep);
74615
 
+
74616
 
+static bool act_store_start
74617
 
+       (const struct sieve_action *action,
74618
 
+               const struct sieve_action_exec_env *aenv, void *context, void **tr_context);
74619
 
+static bool act_store_execute
74620
 
+       (const struct sieve_action *action, 
74621
 
+               const struct sieve_action_exec_env *aenv, void *tr_context);
74622
 
+static bool act_store_commit
74623
 
+       (const struct sieve_action *action, 
74624
 
+               const struct sieve_action_exec_env *aenv, void *tr_context, bool *keep);
74625
 
+static void act_store_rollback
74626
 
+       (const struct sieve_action *action, 
74627
 
+               const struct sieve_action_exec_env *aenv, void *tr_context, bool success);
74628
 
+               
74629
 
+/* Action object */
74630
 
+
74631
 
+const struct sieve_action act_store = {
74632
 
+       "store",
74633
 
+       SIEVE_ACTFLAG_TRIES_DELIVER,
74634
 
+       act_store_equals,
74635
 
+       act_store_check_duplicate, 
74636
 
+       NULL, 
74637
 
+       act_store_print,
74638
 
+       act_store_start,
74639
 
+       act_store_execute,
74640
 
+       act_store_commit,
74641
 
+       act_store_rollback,
74642
 
+};
74643
 
+
74644
 
+/* API */
74645
 
+
74646
 
+int sieve_act_store_add_to_result
74647
 
+(const struct sieve_runtime_env *renv, 
74648
 
+       struct sieve_side_effects_list *seffects, const char *mailbox,
74649
 
+       unsigned int source_line)
74650
 
+{
74651
 
+       pool_t pool;
74652
 
+       struct act_store_context *act;
74653
 
+       
74654
 
+       /* Add redirect action to the result */
74655
 
+       pool = sieve_result_pool(renv->result);
74656
 
+       act = p_new(pool, struct act_store_context, 1);
74657
 
+       act->mailbox = p_strdup(pool, mailbox);
74658
 
+
74659
 
+       return sieve_result_add_action(renv, &act_store, seffects, 
74660
 
+               source_line, (void *) act, 0);
74661
 
+}
74662
 
+
74663
 
+void sieve_act_store_add_flags
74664
 
+(const struct sieve_action_exec_env *aenv, void *tr_context,
74665
 
+       const char *const *keywords, enum mail_flags flags)
74666
 
+{
74667
 
+       struct act_store_transaction *trans = 
74668
 
+               (struct act_store_transaction *) tr_context;
74669
 
+
74670
 
+       /* Assign mail keywords for subsequent mailbox_copy() */
74671
 
+       if ( *keywords != NULL ) {
74672
 
+               const char *const *kw;
74673
 
+
74674
 
+               if ( !array_is_created(&trans->keywords) ) {
74675
 
+                       pool_t pool = sieve_result_pool(aenv->result); 
74676
 
+                       p_array_init(&trans->keywords, pool, 2);
74677
 
+               }
74678
 
+               
74679
 
+               kw = keywords;
74680
 
+               while ( *kw != NULL ) {
74681
 
+
74682
 
+                       const char *kw_error;
74683
 
+
74684
 
+                       if ( trans->box != NULL ) {
74685
 
+                               if ( mailbox_keyword_is_valid(trans->box, *kw, &kw_error) )
74686
 
+                                       array_append(&trans->keywords, kw, 1);
74687
 
+                               else {
74688
 
+                                       char *error = "";
74689
 
+                                       if ( kw_error != NULL && *kw_error != '\0' ) {
74690
 
+                                               error = t_strdup_noconst(kw_error);
74691
 
+                                               error[0] = i_tolower(error[0]);
74692
 
+                                       }
74693
 
+                               
74694
 
+                                       sieve_result_warning(aenv, 
74695
 
+                                               "specified IMAP keyword '%s' is invalid (ignored): %s", 
74696
 
+                                               str_sanitize(*kw, 64), error);
74697
 
+                               }
74698
 
+                       }
74699
 
+
74700
 
+                       kw++;
74701
 
+               }
74702
 
+       }
74703
 
+
74704
 
+       /* Assign mail flags for subsequent mailbox_copy() */
74705
 
+       trans->flags |= flags;
74706
 
+
74707
 
+       trans->flags_altered = TRUE;
74708
 
+}
74709
 
+
74710
 
+void sieve_act_store_get_storage_error
74711
 
+(const struct sieve_action_exec_env *aenv, struct act_store_transaction *trans)
74712
 
+{
74713
 
+       pool_t pool = sieve_result_pool(aenv->result);
74714
 
+       
74715
 
+       trans->error = p_strdup(pool, 
74716
 
+               mail_storage_get_last_error(trans->namespace->storage, &trans->error_code));
74717
 
+}
74718
 
+
74719
 
+
74720
 
+/* Equality */
74721
 
+
74722
 
+static bool act_store_equals
74723
 
+(const struct sieve_script_env *senv, const void *ctx1, const void *ctx2)
74724
 
+{
74725
 
+       struct act_store_context *st_ctx1 = (struct act_store_context *) ctx1;
74726
 
+       struct act_store_context *st_ctx2 = (struct act_store_context *) ctx2;
74727
 
+       const char *mailbox1, *mailbox2;
74728
 
+       
74729
 
+       /* FIXME: consider namespace aliases */
74730
 
+
74731
 
+       if ( st_ctx1 == NULL && st_ctx2 == NULL )
74732
 
+               return TRUE;
74733
 
+               
74734
 
+       mailbox1 = ( st_ctx1 == NULL ? 
74735
 
+               SIEVE_SCRIPT_DEFAULT_MAILBOX(senv) : st_ctx1->mailbox );
74736
 
+       mailbox2 = ( st_ctx2 == NULL ? 
74737
 
+               SIEVE_SCRIPT_DEFAULT_MAILBOX(senv) : st_ctx2->mailbox );
74738
 
+       
74739
 
+       if ( strcmp(mailbox1, mailbox2) == 0 ) 
74740
 
+               return TRUE;
74741
 
+               
74742
 
+       return 
74743
 
+               ( strcasecmp(mailbox1, "INBOX") == 0 && strcasecmp(mailbox2, "INBOX") == 0 ); 
74744
 
+
74745
 
+}
74746
 
+
74747
 
+/* Result verification */
74748
 
+
74749
 
+static int act_store_check_duplicate
74750
 
+(const struct sieve_runtime_env *renv,
74751
 
+       const struct sieve_action_data *act, 
74752
 
+       const struct sieve_action_data *act_other)
74753
 
+{
74754
 
+       return ( act_store_equals(renv->scriptenv, act->context, act_other->context)
74755
 
+               ? 1 : 0 );
74756
 
+}
74757
 
+
74758
 
+/* Result printing */
74759
 
+
74760
 
+static void act_store_print
74761
 
+(const struct sieve_action *action ATTR_UNUSED, 
74762
 
+       const struct sieve_result_print_env *rpenv, void *context, bool *keep)  
74763
 
+{
74764
 
+       struct act_store_context *ctx = (struct act_store_context *) context;
74765
 
+       const char *mailbox;
74766
 
+
74767
 
+       mailbox = ( ctx == NULL ? 
74768
 
+               SIEVE_SCRIPT_DEFAULT_MAILBOX(rpenv->scriptenv) : ctx->mailbox );        
74769
 
+
74770
 
+       sieve_result_action_printf(rpenv, "store message in folder: %s", 
74771
 
+               str_sanitize(mailbox, 128));
74772
 
+       
74773
 
+       *keep = FALSE;
74774
 
+}
74775
 
+
74776
 
+/* Action implementation */
74777
 
+
74778
 
+static struct mailbox *act_store_mailbox_open
74779
 
+(const struct sieve_action_exec_env *aenv, const char **mailbox,
74780
 
+       struct mail_namespace **ns_r, const char **folder_r)
74781
 
+{
74782
 
+       struct mail_storage **storage = &(aenv->exec_status->last_storage);
74783
 
+       enum mailbox_open_flags open_flags = 
74784
 
+               MAILBOX_OPEN_FAST | MAILBOX_OPEN_KEEP_RECENT | 
74785
 
+               MAILBOX_OPEN_SAVEONLY | MAILBOX_OPEN_POST_SESSION;
74786
 
+       struct mailbox *box;
74787
 
+       enum mail_error error;
74788
 
+
74789
 
+       if (strcasecmp(*mailbox, "INBOX") == 0) {
74790
 
+               /* Deliveries to INBOX must always succeed, regardless of ACLs */
74791
 
+               open_flags |= MAILBOX_OPEN_IGNORE_ACLS;
74792
 
+       }
74793
 
+
74794
 
+       *folder_r = *mailbox;
74795
 
+       *ns_r = mail_namespace_find(aenv->scriptenv->namespaces, folder_r);
74796
 
+       if ( *ns_r == NULL) {
74797
 
+               *storage = NULL;
74798
 
+               return NULL;
74799
 
+       }
74800
 
+
74801
 
+       *storage = (*ns_r)->storage;
74802
 
+
74803
 
+       if ( **folder_r == '\0' ) {
74804
 
+               /* Delivering to a namespace prefix means we actually want to
74805
 
+                * deliver to the INBOX instead 
74806
 
+                */
74807
 
+               *folder_r = *mailbox = "INBOX";
74808
 
+               open_flags |= MAILBOX_OPEN_IGNORE_ACLS;
74809
 
+
74810
 
+               *ns_r = mail_namespace_find(aenv->scriptenv->namespaces, folder_r);
74811
 
+               if ( *ns_r == NULL) {
74812
 
+                       *storage = NULL;
74813
 
+                       return NULL;
74814
 
+               }
74815
 
+
74816
 
+               *storage = (*ns_r)->storage;
74817
 
+       }
74818
 
+
74819
 
+       box = mailbox_open(storage, *folder_r, NULL, open_flags);
74820
 
+               
74821
 
+       if ( box == NULL && aenv->scriptenv->mailbox_autocreate ) {     
74822
 
+               (void)mail_storage_get_last_error(*storage, &error);
74823
 
+               if ( error != MAIL_ERROR_NOTFOUND )
74824
 
+                       return NULL;
74825
 
+
74826
 
+               /* Try creating it */
74827
 
+               if ( mail_storage_mailbox_create(*storage, *folder_r, FALSE) < 0 )
74828
 
+                       return NULL;
74829
 
+   
74830
 
+               if ( aenv->scriptenv->mailbox_autosubscribe ) {
74831
 
+                       /* Subscribe to it */
74832
 
+                       (void)mailbox_list_set_subscribed((*ns_r)->list, *folder_r, TRUE);
74833
 
+               }
74834
 
+
74835
 
+               /* Try opening again */
74836
 
+               box = mailbox_open(storage, *folder_r, NULL, open_flags);
74837
 
+    
74838
 
+               if (box == NULL)
74839
 
+                       return NULL;
74840
 
+
74841
 
+               if (mailbox_sync(box, 0, 0, NULL) < 0) {
74842
 
+                       mailbox_close(&box);
74843
 
+                       return NULL;
74844
 
+               }
74845
 
+       }
74846
 
+
74847
 
+       return box;
74848
 
+}
74849
 
+
74850
 
+static bool act_store_start
74851
 
+(const struct sieve_action *action ATTR_UNUSED, 
74852
 
+       const struct sieve_action_exec_env *aenv, void *context, void **tr_context)
74853
 
+{  
74854
 
+       struct act_store_context *ctx = (struct act_store_context *) context;
74855
 
+       const struct sieve_script_env *senv = aenv->scriptenv;
74856
 
+       const struct sieve_message_data *msgdata = aenv->msgdata;
74857
 
+       struct act_store_transaction *trans;
74858
 
+       struct mail_namespace *ns = NULL;
74859
 
+       struct mailbox *box = NULL;
74860
 
+       const char *folder;
74861
 
+       pool_t pool = sieve_result_pool(aenv->result);
74862
 
+       bool disabled = FALSE, redundant = FALSE;
74863
 
+
74864
 
+       /* If context is NULL, the store action is the result of (implicit) keep */     
74865
 
+       if ( ctx == NULL ) {
74866
 
+               ctx = p_new(pool, struct act_store_context, 1);
74867
 
+               ctx->mailbox = p_strdup(pool, SIEVE_SCRIPT_DEFAULT_MAILBOX(senv));
74868
 
+       }
74869
 
+
74870
 
+       /* Open the requested mailbox */
74871
 
+
74872
 
+       /* NOTE: The caller of the sieve library is allowed to leave namespaces set 
74873
 
+        * to NULL. This implementation will then skip actually storing the message.
74874
 
+        */
74875
 
+       if ( senv->namespaces != NULL ) {
74876
 
+               box = act_store_mailbox_open(aenv, &ctx->mailbox, &ns, &folder);
74877
 
+
74878
 
+               /* Check whether we are trying to store the message in the folder it
74879
 
+                * originates from. In that case we skip actually storing it.
74880
 
+          */
74881
 
+               if ( box != NULL && mailbox_backends_equal(box, msgdata->mail->box) ) {
74882
 
+                       mailbox_close(&box);
74883
 
+                       box = NULL;
74884
 
+                       ns = NULL;
74885
 
+                       redundant = TRUE;               
74886
 
+               }
74887
 
+       } else {
74888
 
+               disabled = TRUE;
74889
 
+       }
74890
 
+                               
74891
 
+       /* Create transaction context */
74892
 
+       trans = p_new(pool, struct act_store_transaction, 1);
74893
 
+
74894
 
+       trans->context = ctx;
74895
 
+       trans->namespace = ns;
74896
 
+       trans->folder = folder;
74897
 
+       trans->box = box;
74898
 
+       trans->flags = 0;
74899
 
+
74900
 
+       trans->disabled = disabled;
74901
 
+       trans->redundant = redundant;
74902
 
+               
74903
 
+       if ( ns != NULL && box == NULL ) 
74904
 
+               sieve_act_store_get_storage_error(aenv, trans); 
74905
 
+       
74906
 
+       *tr_context = (void *)trans;
74907
 
+
74908
 
+       return ( (box != NULL) 
74909
 
+               || (trans->error_code == MAIL_ERROR_NOTFOUND) 
74910
 
+               || disabled || redundant );
74911
 
+}
74912
 
+
74913
 
+static struct mail_keywords *act_store_keywords_create
74914
 
+(const struct sieve_action_exec_env *aenv, ARRAY_TYPE(const_string) *keywords, 
74915
 
+       struct mailbox *box)
74916
 
+{
74917
 
+       struct mail_keywords *box_keywords = NULL;
74918
 
+       
74919
 
+       if ( array_is_created(keywords) && array_count(keywords) > 0 ) 
74920
 
+       {
74921
 
+               const char *const *kwds;
74922
 
+               
74923
 
+               (void)array_append_space(keywords);
74924
 
+               kwds = array_idx(keywords, 0);
74925
 
+                               
74926
 
+               /* FIXME: Do we need to clear duplicates? */
74927
 
+               if ( mailbox_keywords_create(box, kwds, &box_keywords) < 0) {
74928
 
+                       sieve_result_error(aenv, "invalid keywords set for stored message");
74929
 
+                       return NULL;
74930
 
+               }
74931
 
+       }
74932
 
+
74933
 
+       return box_keywords;    
74934
 
+}
74935
 
+
74936
 
+static bool act_store_execute
74937
 
+(const struct sieve_action *action ATTR_UNUSED, 
74938
 
+       const struct sieve_action_exec_env *aenv, void *tr_context)
74939
 
+{   
74940
 
+       struct act_store_transaction *trans = 
74941
 
+               (struct act_store_transaction *) tr_context;
74942
 
+       const struct sieve_message_data *msgdata = aenv->msgdata;
74943
 
+       struct mail_save_context *save_ctx;
74944
 
+       struct mail_keywords *keywords = NULL;
74945
 
+       bool result = TRUE;
74946
 
+       
74947
 
+       /* Verify transaction */
74948
 
+       if ( trans == NULL ) return FALSE;
74949
 
+
74950
 
+       /* Check whether we need to do anything */
74951
 
+       if ( trans->disabled ) return TRUE;
74952
 
+
74953
 
+       /* If the message originates from the target mailbox, only update the flags 
74954
 
+        * and keywords 
74955
 
+        */
74956
 
+       if ( trans->redundant ) {
74957
 
+               if ( trans->flags_altered ) {
74958
 
+                       keywords = act_store_keywords_create
74959
 
+                               (aenv, &trans->keywords, msgdata->mail->box);
74960
 
+
74961
 
+                       if ( keywords != NULL ) {
74962
 
+                               mail_update_keywords(msgdata->mail, MODIFY_REPLACE, keywords);
74963
 
+                               mailbox_keywords_free(trans->box, &keywords);
74964
 
+                       }
74965
 
+
74966
 
+                       mail_update_flags(msgdata->mail, MODIFY_REPLACE, trans->flags);
74967
 
+               }
74968
 
+
74969
 
+               return TRUE;
74970
 
+       }
74971
 
+
74972
 
+       /* Exit early if namespace or mailbox are not available */
74973
 
+       if ( trans->namespace == NULL )
74974
 
+               return FALSE;
74975
 
+       else if ( trans->box == NULL ) 
74976
 
+               return FALSE;
74977
 
+
74978
 
+       /* Mark attempt to store in default mailbox */
74979
 
+       if ( strcmp(trans->context->mailbox, 
74980
 
+               SIEVE_SCRIPT_DEFAULT_MAILBOX(aenv->scriptenv)) == 0 ) 
74981
 
+               aenv->exec_status->tried_default_save = TRUE;
74982
 
+
74983
 
+       /* Mark attempt to use storage. Can only get here when all previous actions
74984
 
+        * succeeded. 
74985
 
+        */
74986
 
+       aenv->exec_status->last_storage = trans->namespace->storage;
74987
 
+       
74988
 
+       /* Start mail transaction */
74989
 
+       trans->mail_trans = mailbox_transaction_begin
74990
 
+               (trans->box, MAILBOX_TRANSACTION_FLAG_EXTERNAL);
74991
 
+
74992
 
+       /* Create mail object for stored message */
74993
 
+       trans->dest_mail = mail_alloc(trans->mail_trans, 0, NULL);
74994
 
74995
 
+       /* Store the message */
74996
 
+       save_ctx = mailbox_save_alloc(trans->mail_trans);
74997
 
+       mailbox_save_set_dest_mail(save_ctx, trans->dest_mail);
74998
 
+
74999
 
+       /* Apply keywords and flags that side-effects may have added */
75000
 
+       if ( trans->flags_altered ) {
75001
 
+               keywords = act_store_keywords_create(aenv, &trans->keywords, trans->box);
75002
 
+               
75003
 
+               mailbox_save_set_flags(save_ctx, trans->flags, keywords);
75004
 
+       }
75005
 
+
75006
 
+       if ( mailbox_copy(&save_ctx, aenv->msgdata->mail) < 0 ) {
75007
 
+               sieve_act_store_get_storage_error(aenv, trans);
75008
 
+               result = FALSE;
75009
 
+       }
75010
 
+       
75011
 
+       /* Deallocate keywords */
75012
 
+       if ( keywords != NULL ) {
75013
 
+               mailbox_keywords_free(trans->box, &keywords);
75014
 
+       }
75015
 
+                       
75016
 
+       return result;
75017
 
+}
75018
 
+
75019
 
+static void act_store_log_status
75020
 
+(struct act_store_transaction *trans, 
75021
 
+       const struct sieve_action_exec_env *aenv, bool rolled_back, bool status )
75022
 
+{
75023
 
+       const char *mailbox_name;
75024
 
+       
75025
 
+       mailbox_name = str_sanitize(trans->context->mailbox, 128);
75026
 
+
75027
 
+       /* Store disabled? */
75028
 
+       if ( trans->disabled ) {
75029
 
+               sieve_result_log(aenv, "store into mailbox '%s' skipped", mailbox_name);
75030
 
+       
75031
 
+       /* Store redundant? */
75032
 
+       } else if ( trans->redundant ) {
75033
 
+               sieve_result_log(aenv, "left message in mailbox '%s'", mailbox_name);
75034
 
+
75035
 
+       /* Namespace not set? */
75036
 
+       } else if ( trans->namespace == NULL ) {
75037
 
+               sieve_result_error
75038
 
+                       (aenv, "failed to find namespace for mailbox '%s'", mailbox_name);
75039
 
+
75040
 
+       /* Store failed? */
75041
 
+       } else if ( !status ) {
75042
 
+               const char *errstr;
75043
 
+               enum mail_error error;
75044
 
+
75045
 
+               if ( trans->error != NULL )
75046
 
+                       errstr = trans->error;
75047
 
+               else
75048
 
+                       errstr = mail_storage_get_last_error(trans->namespace->storage, &error);
75049
 
+       
75050
 
+               sieve_result_error(aenv, "failed to store into mailbox '%s': %s", 
75051
 
+                       mailbox_name, errstr);
75052
 
+
75053
 
+       /* Store aborted? */
75054
 
+       } else if ( rolled_back ) {
75055
 
+               sieve_result_log(aenv, "store into mailbox '%s' aborted", mailbox_name);
75056
 
+
75057
 
+       /* Succeeded */
75058
 
+       } else {
75059
 
+               sieve_result_log(aenv, "stored mail into mailbox '%s'", mailbox_name);
75060
 
+
75061
 
+       }
75062
 
+}
75063
 
+
75064
 
+static bool act_store_commit
75065
 
+(const struct sieve_action *action ATTR_UNUSED, 
75066
 
+       const struct sieve_action_exec_env *aenv, void *tr_context, bool *keep)
75067
 
+{  
75068
 
+       struct act_store_transaction *trans = 
75069
 
+               (struct act_store_transaction *) tr_context;
75070
 
+       bool status = TRUE;
75071
 
+
75072
 
+       /* Verify transaction */
75073
 
+       if ( trans == NULL ) return FALSE;
75074
 
+
75075
 
+       /* Check whether we need to do anything */
75076
 
+       if ( trans->disabled ) {
75077
 
+               act_store_log_status(trans, aenv, FALSE, status);
75078
 
+               *keep = FALSE;
75079
 
+               return TRUE;
75080
 
+       } else if ( trans->redundant ) {
75081
 
+               act_store_log_status(trans, aenv, FALSE, status);
75082
 
+               aenv->exec_status->keep_original = TRUE;
75083
 
+               aenv->exec_status->message_saved = TRUE;
75084
 
+               return TRUE;    
75085
 
+       }
75086
 
+
75087
 
+       /* Exit early if namespace is not available */
75088
 
+       if ( trans->namespace == NULL )
75089
 
+               return FALSE;
75090
 
+       else if ( trans->box == NULL ) 
75091
 
+               return FALSE;
75092
 
+
75093
 
+       /* Mark attempt to use storage. Can only get here when all previous actions
75094
 
+        * succeeded. 
75095
 
+        */
75096
 
+       aenv->exec_status->last_storage = trans->namespace->storage;
75097
 
+
75098
 
+       /* Free mail object for stored message */
75099
 
+       if ( trans->dest_mail != NULL ) 
75100
 
+               mail_free(&trans->dest_mail);   
75101
 
+
75102
 
+       /* Commit mailbox transaction */        
75103
 
+       status = ( mailbox_transaction_commit(&trans->mail_trans) == 0 );
75104
 
+
75105
 
+       /* Note the fact that the message was stored at least once */
75106
 
+       if ( status )
75107
 
+               aenv->exec_status->message_saved = TRUE;
75108
 
+       
75109
 
+       /* Log our status */
75110
 
+       act_store_log_status(trans, aenv, FALSE, status);
75111
 
+       
75112
 
+       /* Cancel implicit keep if all went well */
75113
 
+       *keep = !status;
75114
 
+       
75115
 
+       /* Close mailbox */     
75116
 
+       if ( trans->box != NULL )
75117
 
+               mailbox_close(&trans->box);
75118
 
+
75119
 
+       return status;
75120
 
+}
75121
 
+
75122
 
+static void act_store_rollback
75123
 
+(const struct sieve_action *action ATTR_UNUSED, 
75124
 
+       const struct sieve_action_exec_env *aenv, void *tr_context, bool success)
75125
 
+{
75126
 
+       struct act_store_transaction *trans = 
75127
 
+               (struct act_store_transaction *) tr_context;
75128
 
+
75129
 
+       /* Log status */
75130
 
+       act_store_log_status(trans, aenv, TRUE, success);
75131
 
+
75132
 
+       /* Free mailobject for stored message */
75133
 
+       if ( trans->dest_mail != NULL ) 
75134
 
+               mail_free(&trans->dest_mail);   
75135
 
+
75136
 
+       /* Rollback mailbox transaction */
75137
 
+       if ( trans->mail_trans != NULL )
75138
 
+               mailbox_transaction_rollback(&trans->mail_trans);
75139
 
+  
75140
 
+       /* Close the mailbox */
75141
 
+       if ( trans->box != NULL )  
75142
 
+               mailbox_close(&trans->box);
75143
 
+}
75144
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-actions.h dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-actions.h
75145
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-actions.h        1970-01-01 01:00:00.000000000 +0100
75146
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-actions.h 2009-08-05 12:43:18.000000000 +0200
75147
 
@@ -0,0 +1,226 @@
75148
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file 
75149
 
+ */
75150
 
+
75151
 
+#ifndef __SIEVE_ACTIONS_H
75152
 
+#define __SIEVE_ACTIONS_H
75153
 
+
75154
 
+#include "lib.h"
75155
 
+#include "mail-storage.h"
75156
 
+
75157
 
+#include "sieve-common.h"
75158
 
+#include "sieve-objects.h"
75159
 
+#include "sieve-extensions.h"
75160
 
+
75161
 
+/*
75162
 
+ * Action execution environment
75163
 
+ */
75164
 
+
75165
 
+struct sieve_action_exec_env { 
75166
 
+       struct sieve_result *result;
75167
 
+       const struct sieve_message_data *msgdata;
75168
 
+       struct sieve_message_context *msgctx;
75169
 
+       const struct sieve_script_env *scriptenv;
75170
 
+       struct sieve_exec_status *exec_status;
75171
 
+};
75172
 
+
75173
 
+const char *sieve_action_get_location(const struct sieve_action_exec_env *aenv);
75174
 
+
75175
 
+/*
75176
 
+ * Action flags
75177
 
+ */
75178
 
+
75179
 
+enum sieve_action_flags {
75180
 
+       SIEVE_ACTFLAG_TRIES_DELIVER = (1 << 0),
75181
 
+       SIEVE_ACTFLAG_SENDS_RESPONSE = (1 << 1)
75182
 
+};
75183
 
+
75184
 
+/*
75185
 
+ *
75186
 
+ */
75187
 
75188
 
+struct sieve_action_data {
75189
 
+       const struct sieve_action *action;
75190
 
+       const char *location;
75191
 
+       void *context;
75192
 
+       bool executed;
75193
 
+};
75194
 
+
75195
 
+/* 
75196
 
+ * Action object
75197
 
+ */
75198
 
+
75199
 
+struct sieve_action {
75200
 
+       const char *name;
75201
 
+       unsigned int flags;
75202
 
+       
75203
 
+       bool (*equals)
75204
 
+               (const struct sieve_script_env *senv, const void *ctx1, const void *ctx2);
75205
 
+
75206
 
+       /* Result verification */
75207
 
+       
75208
 
+       int (*check_duplicate)  
75209
 
+               (const struct sieve_runtime_env *renv,
75210
 
+                       const struct sieve_action_data *act, 
75211
 
+                       const struct sieve_action_data *act_other);     
75212
 
+       int (*check_conflict)
75213
 
+               (const struct sieve_runtime_env *renv, 
75214
 
+                       const struct sieve_action_data *act, 
75215
 
+                       const struct sieve_action_data *act_other);     
75216
 
+
75217
 
+       /* Result printing */
75218
 
+       
75219
 
+       void (*print)
75220
 
+               (const struct sieve_action *action, 
75221
 
+                       const struct sieve_result_print_env *penv, void *context, bool *keep);  
75222
 
+               
75223
 
+       /* Result execution */  
75224
 
+               
75225
 
+       bool (*start)
75226
 
+               (const struct sieve_action *action, 
75227
 
+                       const struct sieve_action_exec_env *aenv, void *context, 
75228
 
+                       void **tr_context);             
75229
 
+       bool (*execute)
75230
 
+               (const struct sieve_action *action, 
75231
 
+                       const struct sieve_action_exec_env *aenv, void *tr_context);
75232
 
+       bool (*commit)
75233
 
+               (const struct sieve_action *action, 
75234
 
+                       const struct sieve_action_exec_env *aenv, void *tr_context, bool *keep);
75235
 
+       void (*rollback)
75236
 
+               (const struct sieve_action *action, 
75237
 
+                       const struct sieve_action_exec_env *aenv, void *tr_context, bool success);
75238
 
+};
75239
 
+
75240
 
+/* 
75241
 
+ * Action side effects 
75242
 
+ */
75243
 
+
75244
 
+/* Side effect object */
75245
 
+
75246
 
+struct sieve_side_effect {
75247
 
+       struct sieve_object object;
75248
 
+       
75249
 
+       /* The action it is supposed to link to */
75250
 
+       
75251
 
+       const struct sieve_action *to_action;
75252
 
+               
75253
 
+       /* Context coding */
75254
 
+       
75255
 
+       bool (*dump_context)
75256
 
+               (const struct sieve_side_effect *seffect, 
75257
 
+                       const struct sieve_dumptime_env *renv, sieve_size_t *address);
75258
 
+       bool (*read_context)
75259
 
+               (const struct sieve_side_effect *seffect, 
75260
 
+                       const struct sieve_runtime_env *renv, sieve_size_t *address,
75261
 
+                       void **se_context);
75262
 
+               
75263
 
+       /* Result verification */
75264
 
+       
75265
 
+       int (*merge)
75266
 
+               (const struct sieve_runtime_env *renv, const struct sieve_action *action, 
75267
 
+                       const struct sieve_side_effect *seffect, 
75268
 
+                       void **old_context, void *new_context);
75269
 
+
75270
 
+       /* Result printing */   
75271
 
+                       
75272
 
+       void (*print)
75273
 
+               (const struct sieve_side_effect *seffect, const struct sieve_action *action, 
75274
 
+                       const struct sieve_result_print_env *penv, void *se_context, bool *keep);
75275
 
+
75276
 
+       /* Result execution */
75277
 
+
75278
 
+       bool (*pre_execute)
75279
 
+               (const struct sieve_side_effect *seffect, const struct sieve_action *action, 
75280
 
+                       const struct sieve_action_exec_env *aenv, void **se_context, 
75281
 
+                       void *tr_context);
75282
 
+       bool (*post_execute)
75283
 
+               (const struct sieve_side_effect *seffect, const struct sieve_action *action, 
75284
 
+                       const struct sieve_action_exec_env *aenv, void *se_context, 
75285
 
+                       void *tr_context);
75286
 
+       void (*post_commit)
75287
 
+               (const struct sieve_side_effect *seffect, const struct sieve_action *action, 
75288
 
+                       const struct sieve_action_exec_env *aenv, void *se_context,
75289
 
+                       void *tr_context, bool *keep);
75290
 
+       void (*rollback)
75291
 
+               (const struct sieve_side_effect *seffect, const struct sieve_action *action, 
75292
 
+                       const struct sieve_action_exec_env *aenv, void *se_context,
75293
 
+                       void *tr_context, bool success);
75294
 
+};
75295
 
+
75296
 
+/*
75297
 
+ * Side effect operand
75298
 
+ */
75299
 
75300
 
+#define SIEVE_EXT_DEFINE_SIDE_EFFECT(SEF) SIEVE_EXT_DEFINE_OBJECT(SEF)
75301
 
+#define SIEVE_EXT_DEFINE_SIDE_EFFECTS(SEFS) SIEVE_EXT_DEFINE_OBJECTS(SEFS)
75302
 
+
75303
 
+#define SIEVE_OPT_SIDE_EFFECT (-1)
75304
 
+
75305
 
+extern const struct sieve_operand_class sieve_side_effect_operand_class;
75306
 
+
75307
 
+static inline void sieve_opr_side_effect_emit
75308
 
+(struct sieve_binary *sbin, const struct sieve_side_effect *seff)
75309
 
+{ 
75310
 
+       sieve_opr_object_emit(sbin, &seff->object);
75311
 
+}
75312
 
+
75313
 
+static inline const struct sieve_side_effect *sieve_opr_side_effect_read
75314
 
+(const struct sieve_runtime_env *renv, sieve_size_t *address)
75315
 
+{
75316
 
+       return (const struct sieve_side_effect *) sieve_opr_object_read
75317
 
+               (renv, &sieve_side_effect_operand_class, address);
75318
 
+}
75319
 
+
75320
 
+bool sieve_opr_side_effect_dump
75321
 
+       (const struct sieve_dumptime_env *denv, sieve_size_t *address);
75322
 
+
75323
 
+/* 
75324
 
+ * Core actions 
75325
 
+ */
75326
 
+
75327
 
+extern const struct sieve_action act_redirect;
75328
 
+extern const struct sieve_action act_store;
75329
 
+extern const struct sieve_action act_discard;
75330
 
+
75331
 
+/* 
75332
 
+ * Store action
75333
 
+ */
75334
 
+
75335
 
+struct act_store_context {
75336
 
+       /* Folder name represented in modified utf-7 */
75337
 
+       const char *mailbox; 
75338
 
+};
75339
 
+
75340
 
+struct act_store_transaction {
75341
 
+       struct act_store_context *context;
75342
 
+       struct mail_namespace *namespace;
75343
 
+       struct mailbox *box;
75344
 
+       struct mailbox_transaction_context *mail_trans;
75345
 
+       struct mail *dest_mail;
75346
 
+
75347
 
+       const char *folder;
75348
 
+
75349
 
+       const char *error;
75350
 
+       enum mail_error error_code;
75351
 
+       
75352
 
+       enum mail_flags flags;
75353
 
+       ARRAY_TYPE(const_string) keywords;
75354
 
+
75355
 
+       unsigned int flags_altered:1;
75356
 
+       unsigned int disabled:1;
75357
 
+       unsigned int redundant:1;
75358
 
+};
75359
 
+
75360
 
+int sieve_act_store_add_to_result
75361
 
+       (const struct sieve_runtime_env *renv, 
75362
 
+               struct sieve_side_effects_list *seffects, const char *mailbox,
75363
 
+               unsigned int source_line);
75364
 
+
75365
 
+void sieve_act_store_add_flags
75366
 
+       (const struct sieve_action_exec_env *aenv, void *tr_context,
75367
 
+               const char *const *keywords, enum mail_flags flags);
75368
 
+
75369
 
+void sieve_act_store_get_storage_error
75370
 
+       (const struct sieve_action_exec_env *aenv, 
75371
 
+               struct act_store_transaction *trans);
75372
 
+               
75373
 
+#endif /* __SIEVE_ACTIONS_H */
75374
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-address.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-address.c
75375
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-address.c        1970-01-01 01:00:00.000000000 +0100
75376
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-address.c 2009-07-21 00:34:04.000000000 +0200
75377
 
@@ -0,0 +1,785 @@
75378
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file 
75379
 
+ */
75380
 
75381
 
+#include "lib.h"
75382
 
+#include "str.h"
75383
 
+#include "str-sanitize.h"
75384
 
+#include "rfc822-parser.h"
75385
 
+
75386
 
+#include "sieve-common.h"
75387
 
+#include "sieve-address.h"
75388
 
+
75389
 
+#include <ctype.h>
75390
 
+
75391
 
+/*
75392
 
+ * RFC 2822 addresses
75393
 
+ */
75394
 
+
75395
 
+/* Mail message address according to RFC 2822 and implemented in the Dovecot 
75396
 
+ * message address parser:
75397
 
+ *
75398
 
+ *   address         =       mailbox / group
75399
 
+ *   mailbox         =       name-addr / addr-spec
75400
 
+ *   name-addr       =       [display-name] angle-addr
75401
 
+ *   angle-addr      =       [CFWS] "<" addr-spec ">" [CFWS] / obs-angle-addr
75402
 
+ *   group           =       display-name ":" [mailbox-list / CFWS] ";" [CFWS]
75403
 
+ *   display-name    =       phrase
75404
 
+ *
75405
 
+ *   addr-spec       =       local-part "@" domain
75406
 
+ *   local-part      =       dot-atom / quoted-string / obs-local-part
75407
 
+ *   domain          =       dot-atom / domain-literal / obs-domain
75408
 
+ *   domain-literal  =       [CFWS] "[" *([FWS] dcontent) [FWS] "]" [CFWS]
75409
 
+ *   dcontent        =       dtext / quoted-pair
75410
 
+ *   dtext           =       NO-WS-CTL /     ; Non white space controls
75411
 
+ *                           %d33-90 /       ; The rest of the US-ASCII
75412
 
+ *                           %d94-126        ;  characters not including "[",
75413
 
+ *                                           ;  "]", or "\"
75414
 
+ *
75415
 
+ *   atext           =       ALPHA / DIGIT / ; Any character except controls,
75416
 
+ *                           "!" / "#" /     ;  SP, and specials.
75417
 
+ *                           "$" / "%" /     ;  Used for atoms
75418
 
+ *                           "&" / "'" /
75419
 
+ *                           "*" / "+" /
75420
 
+ *                           "-" / "/" /
75421
 
+ *                           "=" / "?" /
75422
 
+ *                           "^" / "_" /
75423
 
+ *                           "`" / "{" /
75424
 
+ *                           "|" / "}" /
75425
 
+ *                           "~"
75426
 
+ *   atom            =       [CFWS] 1*atext [CFWS]
75427
 
+ *   dot-atom        =       [CFWS] dot-atom-text [CFWS]
75428
 
+ *   dot-atom-text   =       1*atext *("." 1*atext)
75429
 
+ *   word            =       atom / quoted-string
75430
 
+ *   phrase          =       1*word / obs-phrase
75431
 
+ *
75432
 
+ * Message address specification as allowed bij the RFC 5228 SIEVE 
75433
 
+ * specification:
75434
 
+ *   sieve-address   =       addr-spec                  ; simple address
75435
 
+ *                           / phrase "<" addr-spec ">" ; name & addr-spec\
75436
 
+ *
75437
 
+ * Which concisely is about equal to:
75438
 
+ *   sieve-address   =       mailbox
75439
 
+ */ 
75440
 
+
75441
 
+/*
75442
 
+ * Address parse context
75443
 
+ */
75444
 
75445
 
+struct sieve_message_address_parser {
75446
 
+       struct rfc822_parser_context parser;
75447
 
+
75448
 
+       string_t *str;
75449
 
+       string_t *local_part;
75450
 
+       string_t *domain;
75451
 
+       
75452
 
+       string_t *error;
75453
 
+};
75454
 
+
75455
 
+/*
75456
 
+ * Error handling
75457
 
+ */
75458
 
+
75459
 
+static inline void sieve_address_error
75460
 
+       (struct sieve_message_address_parser *ctx, const char *fmt, ...) 
75461
 
+               ATTR_FORMAT(2, 3);
75462
 
+
75463
 
+static inline void sieve_address_error
75464
 
+       (struct sieve_message_address_parser *ctx, const char *fmt, ...)
75465
 
+{
75466
 
+       va_list args;
75467
 
+       
75468
 
+       if ( str_len(ctx->error) == 0 ) {
75469
 
+               va_start(args, fmt);
75470
 
+               str_vprintfa(ctx->error, fmt, args);
75471
 
+               va_end(args);
75472
 
+       }
75473
 
+}
75474
 
+
75475
 
+/*
75476
 
+ * Partial RFC 2822 address parser
75477
 
+ *
75478
 
+ *   FIXME: lots of overlap with dovecot/src/lib-mail/message-parser.c
75479
 
+ *          --> this implementation adds textual error reporting
75480
 
+ *          MERGE!
75481
 
+ */
75482
 
+       
75483
 
+static int parse_local_part(struct sieve_message_address_parser *ctx)
75484
 
+{
75485
 
+       int ret;
75486
 
+
75487
 
+       /*
75488
 
+          local-part      = dot-atom / quoted-string / obs-local-part
75489
 
+          obs-local-part  = word *("." word)
75490
 
+       */
75491
 
+       if (ctx->parser.data == ctx->parser.end) {
75492
 
+               sieve_address_error(ctx, "empty local part");
75493
 
+               return -1;
75494
 
+       }
75495
 
+
75496
 
+       str_truncate(ctx->local_part, 0);
75497
 
+       if (*ctx->parser.data == '"')
75498
 
+               ret = rfc822_parse_quoted_string(&ctx->parser, ctx->local_part);
75499
 
+       else
75500
 
+               ret = rfc822_parse_dot_atom(&ctx->parser, ctx->local_part);
75501
 
+               
75502
 
+       if (ret < 0) {
75503
 
+               sieve_address_error(ctx, "invalid local part");
75504
 
+               return -1;
75505
 
+       }
75506
 
+
75507
 
+       return ret;
75508
 
+}
75509
 
+
75510
 
+static int parse_domain(struct sieve_message_address_parser *ctx)
75511
 
+{
75512
 
+       int ret;
75513
 
+
75514
 
+       str_truncate(ctx->domain, 0);
75515
 
+       if ((ret = rfc822_parse_domain(&ctx->parser, ctx->domain)) < 0) {
75516
 
+               sieve_address_error(ctx, "invalid or missing domain");
75517
 
+               return -1;
75518
 
+       }
75519
 
+
75520
 
+       return ret;
75521
 
+}
75522
 
+
75523
 
+static int parse_addr_spec(struct sieve_message_address_parser *ctx)
75524
 
+{
75525
 
+       /* addr-spec       = local-part "@" domain */
75526
 
+       int ret;
75527
 
+
75528
 
+       if ((ret = parse_local_part(ctx)) < 0)
75529
 
+               return ret;
75530
 
+       
75531
 
+       if ( ret > 0 && *ctx->parser.data == '@') {
75532
 
+               return parse_domain(ctx);
75533
 
+       } 
75534
 
+
75535
 
+       sieve_address_error(ctx, "invalid or lonely local part '%s' (expecting '@')", 
75536
 
+               str_sanitize(str_c(ctx->local_part), 80));
75537
 
+       return -1;
75538
 
+}
75539
 
+
75540
 
+static int parse_mailbox(struct sieve_message_address_parser *ctx)
75541
 
+{
75542
 
+       int ret;
75543
 
+       const unsigned char *start;
75544
 
+       
75545
 
+       /* sieve-address   =       addr-spec                  ; simple address
75546
 
+        *                         / phrase "<" addr-spec ">" ; name & addr-spec
75547
 
+        */
75548
 
75549
 
+       /* Record parser state in case we fail at our first attempt */
75550
 
+       start = ctx->parser.data;   
75551
 
75552
 
+       /* First try: phrase "<" addr-spec ">" ; name & addr-spec */    
75553
 
+       str_truncate(ctx->str, 0);
75554
 
+       if (rfc822_parse_phrase(&ctx->parser, ctx->str) <= 0 ||
75555
 
+           *ctx->parser.data != '<') {
75556
 
+         /* Failed; try just bare addr-spec */
75557
 
+         ctx->parser.data = start;
75558
 
+         return parse_addr_spec(ctx);
75559
 
+       } 
75560
 
+
75561
 
+       /* "<" addr-spec ">" */
75562
 
+       ctx->parser.data++;
75563
 
+
75564
 
+       if ((ret = rfc822_skip_lwsp(&ctx->parser)) <= 0 ) {
75565
 
+               if ( ret < 0 )  
75566
 
+                       sieve_address_error(ctx, "invalid characters after <");         
75567
 
+               return ret;
75568
 
+       } 
75569
 
+
75570
 
+       if ((ret = parse_addr_spec(ctx)) < 0)
75571
 
+               return -1;
75572
 
+
75573
 
+       if (*ctx->parser.data != '>') {
75574
 
+               sieve_address_error(ctx, "missing '>'");
75575
 
+               return -1;
75576
 
+       }
75577
 
+       ctx->parser.data++;
75578
 
+
75579
 
+       if ( (ret=rfc822_skip_lwsp(&ctx->parser)) < 0 )
75580
 
+               sieve_address_error(ctx, "address ends with invalid characters");
75581
 
+               
75582
 
+       return ret;
75583
 
+}
75584
 
+
75585
 
+static bool parse_mailbox_address
75586
 
+(struct sieve_message_address_parser *ctx, const unsigned char *address, 
75587
 
+       unsigned int addr_size)
75588
 
+{
75589
 
+       int ret;
75590
 
+       
75591
 
+       /* Initialize parser */
75592
 
+       
75593
 
+       rfc822_parser_init(&ctx->parser, address, addr_size, NULL);
75594
 
+
75595
 
+       /* Parse */
75596
 
+       
75597
 
+       rfc822_skip_lwsp(&ctx->parser);
75598
 
+
75599
 
+       if (ctx->parser.data == ctx->parser.end) {
75600
 
+               sieve_address_error(ctx, "empty address");
75601
 
+               return FALSE;
75602
 
+       }
75603
 
+       
75604
 
+       if ((ret = parse_mailbox(ctx)) < 0) {
75605
 
+               return FALSE;
75606
 
+       }
75607
 
+
75608
 
+       if (ctx->parser.data != ctx->parser.end) {
75609
 
+               if ( *ctx->parser.data == ',' ) 
75610
 
+                       sieve_address_error(ctx, "not a single addres (found ',')");
75611
 
+               else
75612
 
+                       sieve_address_error(ctx, "address ends in invalid characters");
75613
 
+               return FALSE;
75614
 
+       }
75615
 
+                       
75616
 
+       if ( str_len(ctx->domain) == 0 ) {
75617
 
+               /* Not gonna happen */
75618
 
+               sieve_address_error(ctx, "missing domain");
75619
 
+               return FALSE;
75620
 
+       }
75621
 
+
75622
 
+       if ( str_len(ctx->local_part) == 0 ) {
75623
 
+               sieve_address_error(ctx, "missing local part");
75624
 
+               return FALSE;
75625
 
+       }
75626
 
+
75627
 
+       return TRUE;
75628
 
+}
75629
 
+
75630
 
+/* FIXME: change the names of these functions */
75631
 
+bool sieve_rfc2822_mailbox_validate(const char *address, const char **error_r)
75632
 
+{
75633
 
+       struct sieve_message_address_parser ctx;
75634
 
+
75635
 
+       if ( address == NULL ) {
75636
 
+               *error_r = "null address";
75637
 
+               return FALSE;
75638
 
+       }
75639
 
+
75640
 
+       memset(&ctx, 0, sizeof(ctx));
75641
 
+       
75642
 
+       ctx.local_part = t_str_new(128);
75643
 
+       ctx.domain = t_str_new(128);
75644
 
+       ctx.str = t_str_new(128);
75645
 
+       ctx.error = t_str_new(128);
75646
 
+
75647
 
+       if ( !parse_mailbox_address(&ctx, (const unsigned char *) address, 
75648
 
+               strlen(address)) ) {
75649
 
+               if ( error_r != NULL )  
75650
 
+                       *error_r = str_c(ctx.error);
75651
 
+               return FALSE;
75652
 
+       }
75653
 
+
75654
 
+       if ( error_r != NULL )
75655
 
+               *error_r = NULL;
75656
 
+
75657
 
+       return TRUE;
75658
 
+}
75659
 
+
75660
 
+const char *sieve_rfc2822_mailbox_normalize
75661
 
+(const char *address, const char **error_r)
75662
 
+{
75663
 
+       struct sieve_message_address_parser ctx;
75664
 
+
75665
 
+       if ( error_r != NULL )
75666
 
+               *error_r = NULL;
75667
 
+
75668
 
+       if ( address == NULL ) return NULL;
75669
 
+
75670
 
+       memset(&ctx, 0, sizeof(ctx));
75671
 
+       
75672
 
+       ctx.local_part = t_str_new(128);
75673
 
+       ctx.domain = t_str_new(128);
75674
 
+       ctx.str = t_str_new(128);
75675
 
+       ctx.error = t_str_new(128);
75676
 
+
75677
 
+       if ( !parse_mailbox_address(&ctx, (const unsigned char *) address, 
75678
 
+               strlen(address)) ) {
75679
 
+               if ( error_r != NULL )  
75680
 
+                       *error_r = str_c(ctx.error);
75681
 
+               return NULL;
75682
 
+       }
75683
 
+               
75684
 
+       (void)str_lcase(str_c_modifiable(ctx.domain));
75685
 
+
75686
 
+       return t_strconcat(str_c(ctx.local_part), "@", str_c(ctx.domain), NULL);
75687
 
+}
75688
 
+
75689
 
+/*
75690
 
+ * Sieve address
75691
 
+ */
75692
 
+
75693
 
+const char *sieve_address_normalize
75694
 
+(string_t *address, const char **error_r)
75695
 
+{
75696
 
+       struct sieve_message_address_parser ctx;
75697
 
+
75698
 
+       memset(&ctx, 0, sizeof(ctx));
75699
 
+       
75700
 
+       ctx.local_part = t_str_new(128);
75701
 
+       ctx.domain = t_str_new(128);
75702
 
+       ctx.str = t_str_new(128);
75703
 
+       ctx.error = t_str_new(128);
75704
 
+
75705
 
+       if ( !parse_mailbox_address(&ctx, str_data(address), str_len(address)) )
75706
 
+       {
75707
 
+               *error_r = str_c(ctx.error);
75708
 
+               return NULL;
75709
 
+       }
75710
 
+       
75711
 
+       *error_r = NULL;
75712
 
+       (void)str_lcase(str_c_modifiable(ctx.domain));
75713
 
+
75714
 
+       return t_strconcat(str_c(ctx.local_part), "@", str_c(ctx.domain), NULL);
75715
 
+}
75716
 
+
75717
 
+bool sieve_address_validate
75718
 
+(string_t *address, const char **error_r)
75719
 
+{
75720
 
+       struct sieve_message_address_parser ctx;
75721
 
+
75722
 
+       memset(&ctx, 0, sizeof(ctx));
75723
 
+
75724
 
+       ctx.local_part = ctx.domain = ctx.str = t_str_new(128);
75725
 
+       ctx.error = t_str_new(128);
75726
 
+
75727
 
+       if ( !parse_mailbox_address(&ctx, str_data(address), str_len(address)) )
75728
 
+       {
75729
 
+               *error_r = str_c(ctx.error);
75730
 
+               return FALSE;
75731
 
+       }
75732
 
+       
75733
 
+       *error_r = NULL;
75734
 
+       return TRUE;
75735
 
+}
75736
 
+
75737
 
+int sieve_address_compare
75738
 
+(const char *address1, const char *address2, bool normalized ATTR_UNUSED)
75739
 
+{
75740
 
+       /* NOTE: this deviates from RFC specification in that it compares the local 
75741
 
+        * part of the address case-insensitively. This however conforms to the 
75742
 
+        * consensus in mail software.
75743
 
+        */
75744
 
+        
75745
 
+       /* FIXME: provided addresses are currently assumed to be normalized to 
75746
 
+        * local_part@domain
75747
 
+        */
75748
 
+
75749
 
+       i_assert(address1 != NULL);
75750
 
+       i_assert(address2 != NULL);
75751
 
+        
75752
 
+       return strcasecmp(address1, address2);
75753
 
+}
75754
 
+
75755
 
+/*
75756
 
+ * RFC 2821 addresses (envelope paths)
75757
 
+ */
75758
 
75759
 
+/* FIXME: Quite a bit of this will overlap with the rfc822 parser
75760
 
+ * dovecot already has and the rfc2821 parser that it probably will
75761
 
+ * have once it implements LMTP. For now we implement things separately. 
75762
 
+ */
75763
 
+
75764
 
+#define AB (1<<0)
75765
 
+#define DB (1<<1)
75766
 
+#define QB (1<<2)
75767
 
+
75768
 
+/* atext = ALPHA / DIGIT / "!" / "#" / "$" / "%"
75769
 
+ *         / "&" / "'" / "*" / "+" / "-" / "/" / "="
75770
 
+ *         / "?" / "^" / "_" / "`" / "{" / "|" / "}" / "~" 
75771
 
+ */
75772
 
+//#define IS_ATEXT(C) ((rfc2821_chars[C] & AB) != 0) 
75773
 
+
75774
 
+/* dtext = NO-WS-CTL / %d33-90 / %d94-126 
75775
 
+ * NO-WS-CTL = %d1-8 / %d11 / %d12 / %d14-31 / %d127 
75776
 
+ */
75777
 
+#define IS_DTEXT(C) ((rfc2821_chars[C] & DB) != 0) 
75778
 
+
75779
 
+/* qtext= NO-WS-CTL  / %d33 / %d35-91 / %d93-126 */
75780
 
+#define IS_QTEXT(C) ((rfc2821_chars[C] & QB) == 0) 
75781
 
+
75782
 
+/* text        = %d1-9 / %d11 / %d12 / %d14-127 / obs-text*/
75783
 
+#define IS_TEXT(C) ((C) != '\r' && (C) != '\n' && (C) < 128)
75784
 
+
75785
 
+static unsigned char rfc2821_chars[256] = {
75786
 
+          DB,    DB,    DB,    DB,    DB,    DB,    DB,    DB, // 0
75787
 
+          DB,    QB,    QB,    DB,    DB,    QB,    DB,    DB, // 8
75788
 
+          DB,    DB,    DB,    DB,    DB,    DB,    DB,    DB, // 16
75789
 
+          DB,    DB,    DB,    DB,    DB,    DB,    DB,    DB, // 24
75790
 
+          QB, DB|AB, QB|DB, DB|AB, DB|AB, DB|AB, DB|AB, DB|AB, // 32
75791
 
+          DB,    DB, DB|AB, DB|AB,    DB, DB|AB,    DB, DB|AB, // 40
75792
 
+          DB,    DB,    DB,    DB,    DB,    DB,    DB,    DB, // 48
75793
 
+          DB,    DB,    DB,    DB,    DB, DB|AB,    DB, DB|AB, // 56
75794
 
+          DB, DB|AB, DB|AB, DB|AB, DB|AB, DB|AB, DB|AB, DB|AB, // 64
75795
 
+       DB|AB, DB|AB, DB|AB, DB|AB, DB|AB, DB|AB, DB|AB, DB|AB, // 72
75796
 
+       DB|AB, DB|AB, DB|AB, DB|AB, DB|AB, DB|AB, DB|AB, DB|AB, // 80
75797
 
+       DB|AB, DB|AB, DB|AB,     0,    QB,     0, DB|AB, DB|AB, // 88
75798
 
+       DB|AB, DB|AB, DB|AB, DB|AB, DB|AB, DB|AB, DB|AB, DB|AB, // 96
75799
 
+       DB|AB, DB|AB, DB|AB, DB|AB, DB|AB, DB|AB, DB|AB, DB|AB, // 104
75800
 
+       DB|AB, DB|AB, DB|AB, DB|AB, DB|AB, DB|AB, DB|AB, DB|AB, // 112
75801
 
+       DB|AB, DB|AB, DB|AB, DB|AB, DB|AB, DB|AB, DB|AB, DB|QB, // 120
75802
 
+
75803
 
+       0, 0, 0, 0, 0, 0, 0, 0, // 128
75804
 
+       0, 0, 0, 0, 0, 0, 0, 0, // 136
75805
 
+       0, 0, 0, 0, 0, 0, 0, 0, // 144
75806
 
+       0, 0, 0, 0, 0, 0, 0, 0, // 152
75807
 
+       0, 0, 0, 0, 0, 0, 0, 0, // 160
75808
 
+       0, 0, 0, 0, 0, 0, 0, 0, // 168
75809
 
+       0, 0, 0, 0, 0, 0, 0, 0, // 176
75810
 
+       0, 0, 0, 0, 0, 0, 0, 0, // 184
75811
 
+       0, 0, 0, 0, 0, 0, 0, 0, // 192
75812
 
+       0, 0, 0, 0, 0, 0, 0, 0, // 200
75813
 
+       0, 0, 0, 0, 0, 0, 0, 0, // 208
75814
 
+       0, 0, 0, 0, 0, 0, 0, 0, // 216
75815
 
+       0, 0, 0, 0, 0, 0, 0, 0, // 224
75816
 
+       0, 0, 0, 0, 0, 0, 0, 0, // 232
75817
 
+       0, 0, 0, 0, 0, 0, 0, 0, // 240
75818
 
+       0, 0, 0, 0, 0, 0, 0, 0, // 248
75819
 
+
75820
 
+};
75821
 
+
75822
 
+struct sieve_envelope_address_parser {
75823
 
+       pool_t pool;
75824
 
+
75825
 
+       const unsigned char *data;
75826
 
+       const unsigned char *end;
75827
 
+
75828
 
+       string_t *str;
75829
 
+
75830
 
+       struct sieve_address *address;
75831
 
+};
75832
 
+
75833
 
+static int path_skip_white_space(struct sieve_envelope_address_parser *parser)
75834
 
+{
75835
 
+       /* Not mentioned anywhere in the specification, but we do it any way
75836
 
+        * (e.g. Exim does so too)
75837
 
+        */
75838
 
+       while ( parser->data < parser->end && 
75839
 
+               (*parser->data == ' ' || *parser->data == '\t') )
75840
 
+               parser->data++;
75841
 
+
75842
 
+       return parser->data < parser->end;
75843
 
+}
75844
 
+
75845
 
+static int path_skip_address_literal
75846
 
+(struct sieve_envelope_address_parser *parser)
75847
 
+{
75848
 
+       int count = 0;
75849
 
+
75850
 
+       /* Currently we are oblivious to address syntax:
75851
 
+        * address-literal = "[" 1*dcontent "]"
75852
 
+        * dcontent     = dtext / quoted-pair
75853
 
+        */
75854
 
+
75855
 
+       i_assert ( *parser->data == '[' );
75856
 
+
75857
 
+       str_append_c(parser->str, *parser->data);
75858
 
+       parser->data++;
75859
 
+
75860
 
+       while ( parser->data < parser->end ) {
75861
 
+               if ( *parser->data == '\\' ) {
75862
 
+                       str_append_c(parser->str, *parser->data);
75863
 
+                       parser->data++;
75864
 
+                               
75865
 
+                       if ( parser->data < parser->end ) {
75866
 
+                               if ( !IS_TEXT(*parser->data) ) 
75867
 
+                                       return -1;
75868
 
+
75869
 
+                               str_append_c(parser->str, *parser->data);
75870
 
+                               parser->data++;
75871
 
+                       } else return -1;
75872
 
+               } else {
75873
 
+                       if ( !IS_DTEXT(*parser->data) )
75874
 
+                               break;
75875
 
+
75876
 
+                       str_append_c(parser->str, *parser->data);
75877
 
+                       parser->data++;
75878
 
+               }
75879
 
+
75880
 
+               count++;
75881
 
+       }
75882
 
+
75883
 
+               
75884
 
+       if ( count == 0 || parser->data >= parser->end || *parser->data != ']' )
75885
 
+               return -1;
75886
 
+
75887
 
+       str_append_c(parser->str, *parser->data);
75888
 
+       parser->data++;
75889
 
+
75890
 
+       return parser->data < parser->end;
75891
 
+}
75892
 
+
75893
 
+static int path_parse_domain
75894
 
+(struct sieve_envelope_address_parser *parser, bool skip)
75895
 
+{
75896
 
+       int ret;
75897
 
+
75898
 
+       /* Domain = (sub-domain 1*("." sub-domain)) / address-literal
75899
 
+        * sub-domain = Let-dig [Ldh-str]
75900
 
+        * Let-dig = ALPHA / DIGIT
75901
 
+        * Ldh-str = *( ALPHA / DIGIT / "-" ) Let-dig
75902
 
+        */
75903
 
+       
75904
 
+       str_truncate(parser->str, 0);
75905
 
+       if ( *parser->data == '[' ) {
75906
 
+               ret = path_skip_address_literal(parser);
75907
 
+
75908
 
+               if ( ret < 0 ) return ret;
75909
 
+       } else {
75910
 
+               for (;;) {
75911
 
+                       if ( !i_isalnum(*parser->data) )
75912
 
+                               return -1;
75913
 
+
75914
 
+                       str_append_c(parser->str, *parser->data);
75915
 
+                       parser->data++;
75916
 
+
75917
 
+                       while ( parser->data < parser->end ) {
75918
 
+                               if ( !i_isalnum(*parser->data) && *parser->data != '-' )
75919
 
+                                       break;
75920
 
+
75921
 
+                               str_append_c(parser->str, *parser->data);
75922
 
+                               parser->data++;
75923
 
+                       }
75924
 
+
75925
 
+                       if ( !i_isalnum(*(parser->data-1)) )
75926
 
+                               return -1;
75927
 
+                       
75928
 
+                       if ( (ret=path_skip_white_space(parser)) < 0 )
75929
 
+                               return ret;
75930
 
+
75931
 
+                       if ( *parser->data != '.' )
75932
 
+                               break;
75933
 
+
75934
 
+                       str_append_c(parser->str, *parser->data);
75935
 
+                       parser->data++;
75936
 
+
75937
 
+                       if ( (ret=path_skip_white_space(parser)) <= 0 )
75938
 
+                               return -1;
75939
 
+               }
75940
 
+       }
75941
 
+
75942
 
+       if ( !skip )
75943
 
+               parser->address->domain = p_strdup(parser->pool, str_c(parser->str));
75944
 
+
75945
 
+       return path_skip_white_space(parser);
75946
 
+}
75947
 
+
75948
 
+static int path_skip_source_route(struct sieve_envelope_address_parser *parser)
75949
 
+{
75950
 
+       int ret;
75951
 
+
75952
 
+       /* Source-route = [ A-d-l ":" ] 
75953
 
+        * A-d-l = At-domain *( "," A-d-l )
75954
 
+        * At-domain = "@" domain
75955
 
+        */
75956
 
+
75957
 
+       if ( *parser->data == '@' ) {
75958
 
+               parser->data++;
75959
 
+       
75960
 
+               for (;;) {
75961
 
+                       if ( (ret=path_skip_white_space(parser)) <= 0 )
75962
 
+                               return -1;      
75963
 
+
75964
 
+                       if ( (ret=path_parse_domain(parser, TRUE)) <= 0 )
75965
 
+                               return -1;      
75966
 
+
75967
 
+                       if ( (ret=path_skip_white_space(parser)) <= 0 )
75968
 
+                               return ret;
75969
 
+
75970
 
+                       /* Next? */
75971
 
+                       if ( *parser->data != ',' )
75972
 
+                               break;
75973
 
+                       parser->data++;
75974
 
+
75975
 
+                       if ( (ret=path_skip_white_space(parser)) <= 0 )
75976
 
+                               return -1;
75977
 
+
75978
 
+                       if ( *parser->data != '@' )
75979
 
+                               return -1;
75980
 
+                       parser->data++;
75981
 
+               }
75982
 
+
75983
 
+               if ( *parser->data != ':' )
75984
 
+                       return -1;
75985
 
+               parser->data++;
75986
 
+       }
75987
 
+
75988
 
+       return path_skip_white_space(parser);
75989
 
+}
75990
 
+
75991
 
+static int path_parse_local_part(struct sieve_envelope_address_parser *parser)
75992
 
+{
75993
 
+       int ret;
75994
 
+       /* Local-part = Dot-string / Quoted-string
75995
 
+        * Dot-string = Atom *("." Atom)
75996
 
+        * Atom = 1*atext
75997
 
+        * Quoted-string = DQUOTE *qcontent DQUOTE
75998
 
+        * qcontent = qtext / quoted-pair
75999
 
+        * quoted-pair  =   ("\" text)
76000
 
+        */
76001
 
+
76002
 
+       str_truncate(parser->str, 0);
76003
 
+       if ( *parser->data == '"' ) {
76004
 
+               str_append_c(parser->str, *parser->data);
76005
 
+               parser->data++;
76006
 
+
76007
 
+               while ( parser->data < parser->end ) {
76008
 
+                       if ( *parser->data == '\\' ) {
76009
 
+                               str_append_c(parser->str, *parser->data);
76010
 
+                               parser->data++;
76011
 
+
76012
 
+                               if ( parser->data < parser->end ) {
76013
 
+                                       if ( !IS_TEXT(*parser->data) )
76014
 
+                                               return -1;
76015
 
+
76016
 
+                                       str_append_c(parser->str, *parser->data);
76017
 
+                                       parser->data++;
76018
 
+                               } else return -1;
76019
 
+                       } else {
76020
 
+                               if ( !IS_QTEXT(*parser->data) )
76021
 
+                                       break;
76022
 
+
76023
 
+                               str_append_c(parser->str, *parser->data);
76024
 
+                               parser->data++;
76025
 
+                       }
76026
 
+               }
76027
 
+               
76028
 
+               if ( *parser->data != '"' )
76029
 
+                       return -1;
76030
 
+
76031
 
+               str_append_c(parser->str, *parser->data);
76032
 
+               parser->data++;
76033
 
+               
76034
 
+               if ( (ret=path_skip_white_space(parser)) < 0 )
76035
 
+                       return ret;
76036
 
+       } else {
76037
 
+               for (;;) {
76038
 
+                       if ( !IS_ATEXT(*parser->data) ) 
76039
 
+                               return -1;
76040
 
+                       str_append_c(parser->str, *parser->data);
76041
 
+                       parser->data++;
76042
 
+
76043
 
+                       while ( parser->data < parser->end && IS_ATEXT(*parser->data)) {
76044
 
+                               str_append_c(parser->str, *parser->data);
76045
 
+                               parser->data++;
76046
 
+                       }
76047
 
+                       
76048
 
+                       if ( (ret=path_skip_white_space(parser)) < 0 )
76049
 
+                               return ret;
76050
 
+
76051
 
+                       if ( *parser->data != '.' )
76052
 
+                               break;
76053
 
+
76054
 
+                       str_append_c(parser->str, *parser->data);
76055
 
+                               parser->data++;
76056
 
+       
76057
 
+                       if ( (ret=path_skip_white_space(parser)) <= 0 )
76058
 
+                               return -1;
76059
 
+               }
76060
 
+       }
76061
 
+
76062
 
+       parser->address->local_part = p_strdup(parser->pool, str_c(parser->str));
76063
 
+       return parser->data < parser->end;
76064
 
+}
76065
 
+
76066
 
+static int path_parse_mailbox(struct sieve_envelope_address_parser *parser)
76067
 
+{
76068
 
+       int ret;
76069
 
+
76070
 
+       /* Mailbox = Local-part "@" Domain */
76071
 
+       
76072
 
+       if ( (ret=path_parse_local_part(parser)) <= 0 )
76073
 
+               return -1;
76074
 
+
76075
 
+       if ( (ret=path_skip_white_space(parser)) <= 0 )
76076
 
+               return -1;
76077
 
+
76078
 
+       if ( *parser->data != '@' )
76079
 
+               return -1;
76080
 
+       parser->data++;
76081
 
+
76082
 
+       if ( (ret=path_skip_white_space(parser)) <= 0 )
76083
 
+               return -1;
76084
 
+
76085
 
+       return path_parse_domain(parser, FALSE);
76086
 
+}
76087
 
+
76088
 
+static int path_parse(struct sieve_envelope_address_parser *parser)
76089
 
+{
76090
 
+       int ret;
76091
 
+       bool brackets = FALSE;
76092
 
+
76093
 
+       /* Path = "<" [ A-d-l ":" ] Mailbox ">" */
76094
 
+
76095
 
+       if ( (ret=path_skip_white_space(parser)) <= 0 ) 
76096
 
+               return ret;
76097
 
+       
76098
 
+       /* We allow angle brackets to be missing */
76099
 
+       if ( *parser->data == '<' ) {
76100
 
+               parser->data++;
76101
 
+               brackets = TRUE;
76102
 
+
76103
 
+               if ( (ret=path_skip_white_space(parser)) <= 0 ) 
76104
 
+                       return -1;
76105
 
+
76106
 
+               /* Null path? */
76107
 
+               if ( *parser->data == '>' ) {
76108
 
+                       parser->data++;
76109
 
+                       return path_skip_white_space(parser);
76110
 
+               }
76111
 
+       }
76112
 
+
76113
 
+       /*  [ A-d-l ":" ] Mailbox */
76114
 
+       if ( (ret=path_skip_source_route(parser)) <= 0 )
76115
 
+               return -1;
76116
 
+
76117
 
+       if ( (ret=path_parse_mailbox(parser)) < 0 )
76118
 
+               return -1;
76119
 
+
76120
 
+       if ( ret > 0 && (ret=path_skip_white_space(parser)) < 0 ) 
76121
 
+               return -1;
76122
 
+
76123
 
+       if ( brackets ) {
76124
 
+               if ( ret <= 0 ) return -1;
76125
 
+
76126
 
+               if ( *parser->data != '>' )
76127
 
+                       return -1;
76128
 
+               parser->data++;
76129
 
+       }
76130
 
+
76131
 
+       return parser->data < parser->end;
76132
 
+}
76133
 
+
76134
 
+const struct sieve_address *sieve_address_parse_envelope_path
76135
 
+(pool_t pool, const char *field_value)
76136
 
+{
76137
 
+       struct sieve_envelope_address_parser parser;
76138
 
+       int ret;
76139
 
+
76140
 
+       if ( field_value == NULL ) {
76141
 
+               return p_new(pool, struct sieve_address, 1);
76142
 
+       }
76143
 
+
76144
 
+       parser.pool = pool;
76145
 
+       parser.data = (const unsigned char *) field_value;
76146
 
+       parser.end = (const unsigned char *) field_value + strlen(field_value);
76147
 
+       parser.address = p_new(pool, struct sieve_address, 1);
76148
 
+       parser.str = t_str_new(256); /* IMPORTAINT: maintain datastack level */
76149
 
+
76150
 
+       if ( (ret=path_parse(&parser)) < 0 )
76151
 
+               return NULL;
76152
 
+       
76153
 
+       if ( ret > 0 && path_skip_white_space(&parser) < 0 )
76154
 
+               return NULL;
76155
 
+
76156
 
+       if ( parser.data != parser.end )
76157
 
+               return NULL;
76158
 
+
76159
 
+       return parser.address;
76160
 
+}
76161
 
+
76162
 
+
76163
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-address.h dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-address.h
76164
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-address.h        1970-01-01 01:00:00.000000000 +0100
76165
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-address.h 2009-07-21 00:26:19.000000000 +0200
76166
 
@@ -0,0 +1,52 @@
76167
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file 
76168
 
+ */
76169
 
76170
 
+#ifndef __SIEVE_ADDRESS_H
76171
 
+#define __SIEVE_ADDRESS_H
76172
 
76173
 
+#include "lib.h"
76174
 
+#include "strfuncs.h"
76175
 
+
76176
 
+/*
76177
 
+ * Generic address representation
76178
 
+ */ 
76179
 
76180
 
+struct sieve_address {
76181
 
+       const char *local_part;
76182
 
+       const char *domain;
76183
 
+};
76184
 
+
76185
 
+static inline const char *sieve_address_to_string(const struct sieve_address *address) 
76186
 
+{
76187
 
+    if ( address == NULL || address->local_part == NULL || address->domain == NULL )
76188
 
+        return NULL;
76189
 
+
76190
 
+    return t_strconcat(address->local_part, "@", address->domain, NULL);
76191
 
+}
76192
 
+
76193
 
+/* 
76194
 
+ * RFC 2822 addresses
76195
 
+ */ 
76196
 
+
76197
 
+bool sieve_rfc2822_mailbox_validate
76198
 
+       (const char *address, const char **error_r);
76199
 
+const char *sieve_rfc2822_mailbox_normalize
76200
 
+       (const char *address, const char **error_r);
76201
 
+
76202
 
+
76203
 
+const char *sieve_address_normalize
76204
 
+       (string_t *address, const char **error_r);
76205
 
+bool sieve_address_validate
76206
 
+       (string_t *address, const char **error_r);
76207
 
+       
76208
 
+int sieve_address_compare
76209
 
+       (const char *address1, const char *address2, bool normalized);
76210
 
+
76211
 
+/*
76212
 
+ * RFC 2821 addresses (paths)
76213
 
+ */
76214
 
+
76215
 
+const struct sieve_address *sieve_address_parse_envelope_path
76216
 
+       (pool_t pool, const char *field_value);
76217
 
+
76218
 
+#endif
76219
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-address-parts.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-address-parts.c
76220
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-address-parts.c  1970-01-01 01:00:00.000000000 +0100
76221
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-address-parts.c   2009-04-10 14:10:55.000000000 +0200
76222
 
@@ -0,0 +1,376 @@
76223
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file 
76224
 
+ */
76225
 
+
76226
 
+#include "lib.h"
76227
 
+#include "compat.h"
76228
 
+#include "mempool.h"
76229
 
+#include "hash.h"
76230
 
+#include "array.h"
76231
 
+#include "message-address.h"
76232
 
+
76233
 
+#include "sieve-extensions.h"
76234
 
+#include "sieve-code.h"
76235
 
+#include "sieve-address.h"
76236
 
+#include "sieve-commands.h"
76237
 
+#include "sieve-binary.h"
76238
 
+#include "sieve-comparators.h"
76239
 
+#include "sieve-match-types.h"
76240
 
+#include "sieve-validator.h"
76241
 
+#include "sieve-generator.h"
76242
 
+#include "sieve-interpreter.h"
76243
 
+#include "sieve-dump.h"
76244
 
+#include "sieve-match.h"
76245
 
+
76246
 
+#include "sieve-address-parts.h"
76247
 
+
76248
 
+#include <string.h>
76249
 
+
76250
 
+/* 
76251
 
+ * Default address parts
76252
 
+ */
76253
 
+
76254
 
+const struct sieve_address_part *sieve_core_address_parts[] = {
76255
 
+       &all_address_part, &local_address_part, &domain_address_part
76256
 
+};
76257
 
+
76258
 
+const unsigned int sieve_core_address_parts_count = 
76259
 
+       N_ELEMENTS(sieve_core_address_parts);
76260
 
+
76261
 
+/* 
76262
 
+ * Address-part 'extension' 
76263
 
+ */
76264
 
+
76265
 
+static int ext_my_id = -1;
76266
 
+
76267
 
+static bool addrp_validator_load(struct sieve_validator *validator);
76268
 
+
76269
 
+const struct sieve_extension address_part_extension = {
76270
 
+       "@address-parts",
76271
 
+       &ext_my_id,
76272
 
+       NULL, NULL,
76273
 
+       addrp_validator_load,
76274
 
+       NULL, NULL, NULL, NULL, NULL,
76275
 
+       SIEVE_EXT_DEFINE_NO_OPERATIONS,
76276
 
+       SIEVE_EXT_DEFINE_NO_OPERANDS /* Defined as core operand */
76277
 
+};
76278
 
+
76279
 
+static const struct sieve_extension *ext_this = &address_part_extension;
76280
 
+       
76281
 
+/* 
76282
 
+ * Validator context:
76283
 
+ *   name-based address-part registry. 
76284
 
+ */
76285
 
76286
 
+void sieve_address_part_register
76287
 
+(struct sieve_validator *validator, const struct sieve_address_part *addrp) 
76288
 
+{
76289
 
+       struct sieve_validator_object_registry *regs = 
76290
 
+               sieve_validator_object_registry_get(validator, ext_this);
76291
 
+       
76292
 
+       sieve_validator_object_registry_add(regs, &addrp->object);
76293
 
+}
76294
 
+
76295
 
+const struct sieve_address_part *sieve_address_part_find
76296
 
+(struct sieve_validator *validator, const char *identifier) 
76297
 
+{
76298
 
+       struct sieve_validator_object_registry *regs = 
76299
 
+               sieve_validator_object_registry_get(validator, ext_this);
76300
 
+       const struct sieve_object *object = 
76301
 
+               sieve_validator_object_registry_find(regs, identifier);
76302
 
+
76303
 
+  return (const struct sieve_address_part *) object;
76304
 
+}
76305
 
+
76306
 
+bool addrp_validator_load(struct sieve_validator *validator)
76307
 
+{
76308
 
+       struct sieve_validator_object_registry *regs = 
76309
 
+               sieve_validator_object_registry_init(validator, ext_this);
76310
 
+       unsigned int i;
76311
 
+
76312
 
+       /* Register core address-parts */
76313
 
+       for ( i = 0; i < sieve_core_address_parts_count; i++ ) {
76314
 
+               sieve_validator_object_registry_add
76315
 
+                       (regs, &(sieve_core_address_parts[i]->object));
76316
 
+       }
76317
 
+
76318
 
+       return TRUE;
76319
 
+}
76320
 
+
76321
 
+void sieve_address_parts_link_tags
76322
 
+       (struct sieve_validator *validator, 
76323
 
+               struct sieve_command_registration *cmd_reg, int id_code) 
76324
 
+{      
76325
 
+       sieve_validator_register_tag
76326
 
+               (validator, cmd_reg, &address_part_tag, id_code);       
76327
 
+}
76328
 
+
76329
 
+/* 
76330
 
+ * Address-part tagged argument 
76331
 
+ */
76332
 
76333
 
+/* Forward declarations */
76334
 
+
76335
 
+static bool tag_address_part_is_instance_of
76336
 
+       (struct sieve_validator *validator, struct sieve_command_context *cmd,
76337
 
+               struct sieve_ast_argument *arg);
76338
 
+static bool tag_address_part_validate
76339
 
+       (struct sieve_validator *validator, struct sieve_ast_argument **arg, 
76340
 
+               struct sieve_command_context *cmd);
76341
 
+static bool tag_address_part_generate
76342
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, 
76343
 
+               struct sieve_command_context *cmd);
76344
 
+
76345
 
+/* Argument object */
76346
 
+
76347
 
+const struct sieve_argument address_part_tag = { 
76348
 
+       "ADDRESS-PART",
76349
 
+       tag_address_part_is_instance_of, 
76350
 
+       NULL,
76351
 
+       tag_address_part_validate,
76352
 
+       NULL, 
76353
 
+       tag_address_part_generate 
76354
 
+};
76355
 
+
76356
 
+/* Argument implementation */
76357
 
+  
76358
 
+static bool tag_address_part_is_instance_of
76359
 
+(struct sieve_validator *validator, struct sieve_command_context *cmd,
76360
 
+       struct sieve_ast_argument *arg)
76361
 
+{
76362
 
+       struct sieve_address_part_context *adpctx;
76363
 
+       const struct sieve_address_part *addrp = sieve_address_part_find
76364
 
+               (validator, sieve_ast_argument_tag(arg));
76365
 
+
76366
 
+       if ( addrp == NULL ) return FALSE;
76367
 
+
76368
 
+       adpctx = p_new(sieve_command_pool(cmd), struct sieve_address_part_context, 1);
76369
 
+       adpctx->command_ctx = cmd;
76370
 
+       adpctx->address_part = addrp;
76371
 
+
76372
 
+       /* Store address-part in context */
76373
 
+       arg->context = (void *) adpctx;
76374
 
+
76375
 
+       return TRUE;
76376
 
+}
76377
 
76378
 
+static bool tag_address_part_validate
76379
 
+(struct sieve_validator *validator ATTR_UNUSED, struct sieve_ast_argument **arg, 
76380
 
+       struct sieve_command_context *cmd ATTR_UNUSED)
76381
 
+{
76382
 
+       /* FIXME: Currenly trivial, but might need to allow for further validation for
76383
 
+        * future extensions.
76384
 
+        */
76385
 
+        
76386
 
+       /* Syntax:   
76387
 
+        *   ":localpart" / ":domain" / ":all" (subject to extension)
76388
 
+   */
76389
 
+       
76390
 
+       /* Skip tag */
76391
 
+       *arg = sieve_ast_argument_next(*arg);
76392
 
+
76393
 
+       return TRUE;
76394
 
+}
76395
 
+
76396
 
+static bool tag_address_part_generate
76397
 
+(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, 
76398
 
+       struct sieve_command_context *cmd ATTR_UNUSED)
76399
 
+{
76400
 
+       struct sieve_address_part_context *adpctx =
76401
 
+               (struct sieve_address_part_context *) arg->context;
76402
 
+               
76403
 
+       sieve_opr_address_part_emit(cgenv->sbin, adpctx->address_part); 
76404
 
+               
76405
 
+       return TRUE;
76406
 
+}
76407
 
+
76408
 
+/*
76409
 
+ * Address-part operand
76410
 
+ */
76411
 
76412
 
+const struct sieve_operand_class sieve_address_part_operand_class = 
76413
 
+       { "address part" };
76414
 
+
76415
 
+static const struct sieve_extension_objects core_address_parts =
76416
 
+       SIEVE_EXT_DEFINE_MATCH_TYPES(sieve_core_address_parts);
76417
 
+
76418
 
+const struct sieve_operand address_part_operand = { 
76419
 
+       "address-part", 
76420
 
+       NULL, SIEVE_OPERAND_ADDRESS_PART,
76421
 
+       &sieve_address_part_operand_class,
76422
 
+       &core_address_parts
76423
 
+};
76424
 
+
76425
 
+/*
76426
 
+ * Address Matching
76427
 
+ */
76428
 
76429
 
+int sieve_address_match
76430
 
+(const struct sieve_address_part *addrp, struct sieve_match_context *mctx,             
76431
 
+       const char *data)
76432
 
+{
76433
 
+       int result = FALSE;
76434
 
+       const struct message_address *addr;
76435
 
+
76436
 
+       T_BEGIN {
76437
 
+               bool valid = TRUE;
76438
 
+               const struct message_address *aitem;
76439
 
+
76440
 
+               addr = message_address_parse
76441
 
+                       (pool_datastack_create(), (const unsigned char *) data, 
76442
 
+                               strlen(data), 256, FALSE);
76443
 
+
76444
 
+               /* Check validity of all addresses simultaneously. Unfortunately,
76445
 
+                * errorneous addresses cannot be extracted from the address list
76446
 
+                * and therefore :all will match against the whole header value
76447
 
+                * which is not entirely standard.
76448
 
+                */
76449
 
+               aitem = addr;
76450
 
+               while ( aitem != NULL) {
76451
 
+                       if ( aitem->invalid_syntax )
76452
 
+                               valid = FALSE;
76453
 
+                       aitem = aitem->next;
76454
 
+               }
76455
 
+
76456
 
+               if ( !valid || addr == NULL ) {
76457
 
+                       if ( addrp == &all_address_part )
76458
 
+                               result = sieve_match_value(mctx, data, strlen(data));
76459
 
+                       else 
76460
 
+                               result = FALSE;
76461
 
+               } else {
76462
 
+                       while ( result == 0 && addr != NULL) {
76463
 
+                               /* mailbox@domain */
76464
 
+                               struct sieve_address address;
76465
 
+                               const char *part;
76466
 
+                       
76467
 
+                               if ( addr->domain != NULL ) {
76468
 
+                                       address.local_part = addr->mailbox;
76469
 
+                                       address.domain = addr->domain;
76470
 
+       
76471
 
+                                       part = addrp->extract_from(&address);
76472
 
+
76473
 
+                                       if ( part != NULL )
76474
 
+                                               result = sieve_match_value(mctx, part, strlen(part));
76475
 
+                               }
76476
 
+                               addr = addr->next;
76477
 
+                       }
76478
 
+               }
76479
 
+       } T_END;
76480
 
+       
76481
 
+       return result;
76482
 
+}
76483
 
+
76484
 
+/* 
76485
 
+ * Default ADDRESS-PART, MATCH-TYPE, COMPARATOR access
76486
 
+ */
76487
 
76488
 
+bool sieve_addrmatch_default_dump_optionals
76489
 
+(const struct sieve_dumptime_env *denv, sieve_size_t *address) 
76490
 
+{
76491
 
+       int opt_code = 1;
76492
 
+       
76493
 
+       if ( sieve_operand_optional_present(denv->sbin, address) ) {
76494
 
+               while ( opt_code != 0 ) {
76495
 
+                       if ( !sieve_operand_optional_read(denv->sbin, address, &opt_code) ) 
76496
 
+                               return FALSE;
76497
 
+
76498
 
+                       switch ( opt_code ) {
76499
 
+                       case 0:
76500
 
+                               break;
76501
 
+                       case SIEVE_AM_OPT_COMPARATOR:
76502
 
+                               if ( !sieve_opr_comparator_dump(denv, address) )
76503
 
+                                       return FALSE;
76504
 
+                               break;
76505
 
+                       case SIEVE_AM_OPT_MATCH_TYPE:
76506
 
+                               if ( !sieve_opr_match_type_dump(denv, address) )
76507
 
+                                       return FALSE;
76508
 
+                               break;
76509
 
+                       case SIEVE_AM_OPT_ADDRESS_PART:
76510
 
+                               if ( !sieve_opr_address_part_dump(denv, address) )
76511
 
+                                       return FALSE;
76512
 
+                               break;
76513
 
+                       default:
76514
 
+                               return FALSE;
76515
 
+                       }
76516
 
+               }
76517
 
+       }
76518
 
+       
76519
 
+       return TRUE;
76520
 
+}
76521
 
+
76522
 
+bool sieve_addrmatch_default_get_optionals
76523
 
+(const struct sieve_runtime_env *renv, sieve_size_t *address, 
76524
 
+       const struct sieve_address_part **addrp, const struct sieve_match_type **mtch, 
76525
 
+       const struct sieve_comparator **cmp) 
76526
 
+{
76527
 
+       int opt_code = 1;
76528
 
+       
76529
 
+       
76530
 
+       if ( sieve_operand_optional_present(renv->sbin, address) ) {
76531
 
+               while ( opt_code != 0 ) {
76532
 
+                       if ( !sieve_operand_optional_read(renv->sbin, address, &opt_code) )
76533
 
+                               return FALSE;
76534
 
+                                 
76535
 
+                       switch ( opt_code ) {
76536
 
+                       case 0:
76537
 
+                               break;
76538
 
+                       case SIEVE_AM_OPT_COMPARATOR:
76539
 
+                               if ( (*cmp = sieve_opr_comparator_read(renv, address)) == NULL )
76540
 
+                                       return FALSE;
76541
 
+                               break;
76542
 
+                       case SIEVE_AM_OPT_MATCH_TYPE:
76543
 
+                               if ( (*mtch = sieve_opr_match_type_read(renv, address)) == NULL )
76544
 
+                                       return FALSE;
76545
 
+                               break;
76546
 
+                       case SIEVE_AM_OPT_ADDRESS_PART:
76547
 
+                               if ( (*addrp = sieve_opr_address_part_read(renv, address)) == NULL )
76548
 
+                                       return FALSE;
76549
 
+                               break;
76550
 
+                       default:
76551
 
+                               return FALSE;
76552
 
+                       }
76553
 
+               }
76554
 
+       }
76555
 
+       
76556
 
+       return TRUE;
76557
 
+}
76558
 
+
76559
 
+/* 
76560
 
+ * Core address-part modifiers
76561
 
+ */
76562
 
76563
 
+static const char *addrp_all_extract_from
76564
 
+       (const struct sieve_address *address)
76565
 
+{
76566
 
+       const char *local_part = address->local_part;
76567
 
+       const char *domain = address->domain;
76568
 
+
76569
 
+       return t_strconcat(local_part, "@", domain, NULL);
76570
 
+}
76571
 
+
76572
 
+static const char *addrp_domain_extract_from
76573
 
+       (const struct sieve_address *address)
76574
 
+{
76575
 
+       return address->domain;
76576
 
+}
76577
 
+
76578
 
+static const char *addrp_localpart_extract_from
76579
 
+       (const struct sieve_address *address)
76580
 
+{
76581
 
+       return address->local_part;
76582
 
+}
76583
 
+
76584
 
+const struct sieve_address_part all_address_part = {
76585
 
+       SIEVE_OBJECT("all", &address_part_operand, SIEVE_ADDRESS_PART_ALL),
76586
 
+       addrp_all_extract_from
76587
 
+};
76588
 
+
76589
 
+const struct sieve_address_part local_address_part = {
76590
 
+       SIEVE_OBJECT("localpart", &address_part_operand, SIEVE_ADDRESS_PART_LOCAL),
76591
 
+       addrp_localpart_extract_from
76592
 
+};
76593
 
+
76594
 
+const struct sieve_address_part domain_address_part = {
76595
 
+       SIEVE_OBJECT("domain", &address_part_operand,   SIEVE_ADDRESS_PART_DOMAIN),
76596
 
+       addrp_domain_extract_from
76597
 
+};
76598
 
+
76599
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-address-parts.h dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-address-parts.h
76600
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-address-parts.h  1970-01-01 01:00:00.000000000 +0100
76601
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-address-parts.h   2009-02-24 13:39:14.000000000 +0100
76602
 
@@ -0,0 +1,116 @@
76603
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file 
76604
 
+ */
76605
 
76606
 
+#ifndef __SIEVE_ADDRESS_PARTS_H
76607
 
+#define __SIEVE_ADDRESS_PARTS_H
76608
 
+
76609
 
+#include "message-address.h"
76610
 
+
76611
 
+#include "sieve-common.h"
76612
 
+#include "sieve-extensions.h"
76613
 
+#include "sieve-objects.h"
76614
 
+
76615
 
+/*
76616
 
+ * Address part object 
76617
 
+ */
76618
 
+
76619
 
+struct sieve_address_part {
76620
 
+       struct sieve_object object;             
76621
 
+
76622
 
+       const char *(*extract_from)(const struct sieve_address *address);
76623
 
+};
76624
 
+
76625
 
+/*
76626
 
+ * Core address parts
76627
 
+ */
76628
 
76629
 
+enum sieve_address_part_code {
76630
 
+       SIEVE_ADDRESS_PART_ALL,
76631
 
+       SIEVE_ADDRESS_PART_LOCAL,
76632
 
+       SIEVE_ADDRESS_PART_DOMAIN,
76633
 
+       SIEVE_ADDRESS_PART_CUSTOM
76634
 
+};
76635
 
+
76636
 
+extern const struct sieve_address_part all_address_part;
76637
 
+extern const struct sieve_address_part local_address_part;
76638
 
+extern const struct sieve_address_part domain_address_part;
76639
 
+
76640
 
+/*
76641
 
+ * Address part tagged argument
76642
 
+ */
76643
 
76644
 
+extern const struct sieve_argument address_part_tag;
76645
 
+
76646
 
+struct sieve_address_part_context {
76647
 
+       struct sieve_command_context *command_ctx;
76648
 
+       const struct sieve_address_part *address_part;
76649
 
+};
76650
 
+
76651
 
+void sieve_address_parts_link_tags
76652
 
+       (struct sieve_validator *validator, 
76653
 
+               struct sieve_command_registration *cmd_reg, int id_code);
76654
 
+
76655
 
+/*
76656
 
+ * Address part registry
76657
 
+ */
76658
 
+               
76659
 
+void sieve_address_part_register
76660
 
+       (struct sieve_validator *validator, 
76661
 
+               const struct sieve_address_part *addrp);
76662
 
+const struct sieve_address_part *sieve_address_part_find
76663
 
+       (struct sieve_validator *validator, const char *identifier);
76664
 
+               
76665
 
+/*
76666
 
+ * Address part operand
76667
 
+ */
76668
 
+
76669
 
+extern const struct sieve_operand address_part_operand;
76670
 
+extern const struct sieve_operand_class sieve_address_part_operand_class;
76671
 
+
76672
 
+#define SIEVE_EXT_DEFINE_ADDRESS_PART(OP) SIEVE_EXT_DEFINE_OBJECT(OP)
76673
 
+#define SIEVE_EXT_DEFINE_ADDRESS_PARTS(OPS) SIEVE_EXT_DEFINE_OBJECTS(OPS)
76674
 
+
76675
 
+static inline void sieve_opr_address_part_emit
76676
 
+(struct sieve_binary *sbin, const struct sieve_address_part *addrp)
76677
 
+{ 
76678
 
+       sieve_opr_object_emit(sbin, &addrp->object);
76679
 
+}
76680
 
+
76681
 
+static inline const struct sieve_address_part *sieve_opr_address_part_read
76682
 
+  (const struct sieve_runtime_env *renv, sieve_size_t *address)
76683
 
+{
76684
 
+       return (const struct sieve_address_part *) sieve_opr_object_read
76685
 
+               (renv, &sieve_address_part_operand_class, address);
76686
 
+}
76687
 
+
76688
 
+static inline bool sieve_opr_address_part_dump
76689
 
+       (const struct sieve_dumptime_env *denv, sieve_size_t *address)
76690
 
+{
76691
 
+       return sieve_opr_object_dump
76692
 
+               (denv, &sieve_address_part_operand_class, address, NULL);
76693
 
+}
76694
 
+
76695
 
+/* 
76696
 
+ * Match utility 
76697
 
+ */
76698
 
+
76699
 
+int sieve_address_match
76700
 
+(const struct sieve_address_part *addrp, struct sieve_match_context *mctx,
76701
 
+    const char *data);
76702
 
+
76703
 
+enum sieve_addrmatch_opt_operand {
76704
 
+       SIEVE_AM_OPT_END,
76705
 
+       SIEVE_AM_OPT_COMPARATOR,
76706
 
+       SIEVE_AM_OPT_ADDRESS_PART,
76707
 
+       SIEVE_AM_OPT_MATCH_TYPE
76708
 
+};
76709
 
+
76710
 
+bool sieve_addrmatch_default_dump_optionals
76711
 
+       (const struct sieve_dumptime_env *denv, sieve_size_t *address);
76712
 
+
76713
 
+bool sieve_addrmatch_default_get_optionals
76714
 
+       (const struct sieve_runtime_env *renv, sieve_size_t *address, 
76715
 
+               const struct sieve_address_part **addp, 
76716
 
+               const struct sieve_match_type **mtch, const struct sieve_comparator **cmp);
76717
 
+
76718
 
+#endif /* __SIEVE_ADDRESS_PARTS_H */
76719
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-ast.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-ast.c
76720
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-ast.c    1970-01-01 01:00:00.000000000 +0100
76721
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-ast.c     2009-07-08 19:23:13.000000000 +0200
76722
 
@@ -0,0 +1,1061 @@
76723
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
76724
 
+ */
76725
 
76726
 
+#include "lib.h"
76727
 
+#include "str.h"
76728
 
+#include "mempool.h"
76729
 
+#include "array.h"
76730
 
+
76731
 
+#include "sieve-common.h"
76732
 
+#include "sieve-script.h"
76733
 
+#include "sieve-extensions.h"
76734
 
+
76735
 
+#include "sieve-ast.h"
76736
 
+
76737
 
+#include <stdio.h>
76738
 
+
76739
 
+/* 
76740
 
+ * Forward declarations 
76741
 
+ */
76742
 
+
76743
 
+static struct sieve_ast_node *sieve_ast_node_create
76744
 
+       (struct sieve_ast *ast, struct sieve_ast_node *parent, 
76745
 
+               enum sieve_ast_type type, unsigned int source_line);
76746
 
+
76747
 
+/*
76748
 
+ * Types
76749
 
+ */
76750
 
+
76751
 
+/* Extensions to the AST */
76752
 
+
76753
 
+struct sieve_ast_extension_reg {
76754
 
+       const struct sieve_ast_extension *ast_ext;
76755
 
+       void *context;
76756
 
+};
76757
 
+
76758
 
+/* 
76759
 
+ * AST object 
76760
 
+ */
76761
 
+
76762
 
+struct sieve_ast {
76763
 
+       pool_t pool;
76764
 
+       int refcount;
76765
 
+               
76766
 
+       struct sieve_script *script;
76767
 
+               
76768
 
+       struct sieve_ast_node *root;
76769
 
+       
76770
 
+       ARRAY_DEFINE(linked_extensions, const struct sieve_extension *);
76771
 
+       ARRAY_DEFINE(extensions, struct sieve_ast_extension_reg);
76772
 
+};
76773
 
+
76774
 
+struct sieve_ast *sieve_ast_create(struct sieve_script *script) 
76775
 
+{
76776
 
+       pool_t pool;
76777
 
+       struct sieve_ast *ast;
76778
 
+       
76779
 
+       pool = pool_alloconly_create("sieve_ast", 16384);       
76780
 
+       ast = p_new(pool, struct sieve_ast, 1);
76781
 
+       ast->pool = pool;
76782
 
+       ast->refcount = 1;
76783
 
+       
76784
 
+       ast->script = script;
76785
 
+       sieve_script_ref(script);
76786
 
+               
76787
 
+       ast->root = sieve_ast_node_create(ast, NULL, SAT_ROOT, 0);
76788
 
+       ast->root->identifier = "ROOT";
76789
 
+       
76790
 
+       p_array_init(&ast->linked_extensions, pool, sieve_extensions_get_count());
76791
 
+       p_array_init(&ast->extensions, pool, sieve_extensions_get_count());
76792
 
+       
76793
 
+       return ast;
76794
 
+}
76795
 
+
76796
 
+void sieve_ast_ref(struct sieve_ast *ast) 
76797
 
+{
76798
 
+       ast->refcount++;
76799
 
+}
76800
 
+
76801
 
+void sieve_ast_unref(struct sieve_ast **ast) 
76802
 
+{
76803
 
+       unsigned int i, ext_count;
76804
 
+       const struct sieve_ast_extension_reg *extrs;
76805
 
+       
76806
 
+       i_assert((*ast)->refcount > 0);
76807
 
+
76808
 
+       if (--(*ast)->refcount != 0)
76809
 
+               return;
76810
 
+       
76811
 
+       /* Release script reference */
76812
 
+       sieve_script_unref(&(*ast)->script);
76813
 
+       
76814
 
+       /* Signal registered extensions that the AST is being destroyed */
76815
 
+       extrs = array_get(&(*ast)->extensions, &ext_count);
76816
 
+       for ( i = 0; i < ext_count; i++ ) {
76817
 
+               if ( extrs[i].ast_ext != NULL && 
76818
 
+                       extrs[i].ast_ext->free != NULL )
76819
 
+                       extrs[i].ast_ext->free(*ast, extrs[i].context);
76820
 
+       }
76821
 
+
76822
 
+       /* Destroy AST */
76823
 
+       pool_unref(&(*ast)->pool);
76824
 
+       
76825
 
+       *ast = NULL;
76826
 
+}
76827
 
+
76828
 
+struct sieve_ast_node *sieve_ast_root(struct sieve_ast *ast)
76829
 
+{
76830
 
+       return ast->root;
76831
 
+}
76832
 
+
76833
 
+pool_t sieve_ast_pool(struct sieve_ast *ast)
76834
 
+{
76835
 
+       return ast->pool;
76836
 
+}
76837
 
+
76838
 
+struct sieve_script *sieve_ast_script(struct sieve_ast *ast)
76839
 
+{
76840
 
+       return ast->script;
76841
 
+}
76842
 
+
76843
 
+/* 
76844
 
+ * Extension support 
76845
 
+ */
76846
 
+
76847
 
+void sieve_ast_extension_link
76848
 
+(struct sieve_ast *ast, const struct sieve_extension *ext)
76849
 
+{
76850
 
+       int ext_id = SIEVE_EXT_ID(ext);
76851
 
+       unsigned int i, ext_count;
76852
 
+       const struct sieve_extension *const *extensions;
76853
 
+       
76854
 
+       if ( ext_id < 0 ) return;
76855
 
+        
76856
 
+       /* Prevent duplicates */
76857
 
+       extensions = array_get(&ast->linked_extensions, &ext_count);
76858
 
+       for ( i = 0; i < ext_count; i++ ) {
76859
 
+               if ( extensions[i] == ext )
76860
 
+                       return;
76861
 
+       }
76862
 
+
76863
 
+       /* Add extension */
76864
 
+       array_append(&ast->linked_extensions, &ext, 1); 
76865
 
+}
76866
 
+
76867
 
+const struct sieve_extension * const *sieve_ast_extensions_get
76868
 
+(struct sieve_ast *ast, unsigned int *count_r)
76869
 
+{
76870
 
+       return array_get(&ast->linked_extensions, count_r);
76871
 
+}
76872
 
+
76873
 
+void sieve_ast_extension_register
76874
 
+(struct sieve_ast *ast, const struct sieve_ast_extension *ast_ext, 
76875
 
+       void *context)
76876
 
+{
76877
 
+       int ext_id = SIEVE_EXT_ID(ast_ext->ext);
76878
 
+       struct sieve_ast_extension_reg reg;
76879
 
+
76880
 
+       if ( ext_id < 0 ) return;
76881
 
+
76882
 
+       /* Initialize registration */
76883
 
+       reg.ast_ext = ast_ext;
76884
 
+       reg.context = context;  
76885
 
+       array_idx_set(&ast->extensions, (unsigned int) ext_id, &reg);
76886
 
+}
76887
 
+
76888
 
+void *sieve_ast_extension_get_context
76889
 
+(struct sieve_ast *ast, const struct sieve_extension *ext) 
76890
 
+{
76891
 
+       int ext_id = SIEVE_EXT_ID(ext);
76892
 
+       const struct sieve_ast_extension_reg *reg;
76893
 
+
76894
 
+       if  ( ext_id < 0 || ext_id >= (int) array_count(&ast->extensions) )
76895
 
+               return NULL;
76896
 
+       
76897
 
+       reg = array_idx(&ast->extensions, (unsigned int) ext_id);               
76898
 
+
76899
 
+       return reg->context;
76900
 
+}
76901
 
+
76902
 
+/*
76903
 
+ * AST list implementations
76904
 
+ */
76905
 
76906
 
+/* Very simplistic linked list implementation
76907
 
+ * FIXME: Move to separate file
76908
 
+ */
76909
 
+#define __LIST_CREATE(pool, type) { \
76910
 
+               type *list = p_new(pool, type, 1); \
76911
 
+               list->head = NULL; \
76912
 
+               list->tail = NULL; \
76913
 
+               list->len = 0;          \
76914
 
+               return list; \
76915
 
+       }
76916
 
+
76917
 
+#define __LIST_ADD(list, node) { \
76918
 
+               if ( list->len + 1 < list->len ) \
76919
 
+                       return FALSE; \
76920
 
+               \
76921
 
+               node->next = NULL; \
76922
 
+               if ( list->head == NULL ) { \
76923
 
+                       node->prev = NULL; \
76924
 
+                       list->head = node; \
76925
 
+                       list->tail = node; \
76926
 
+               } else { \
76927
 
+                       list->tail->next = node; \
76928
 
+                       node->prev = list->tail; \
76929
 
+                       list->tail = node; \
76930
 
+               } \
76931
 
+               list->len++; \
76932
 
+               node->list = list; \
76933
 
+               return TRUE; \
76934
 
+       }        
76935
 
+       
76936
 
+#define __LIST_INSERT(list, before, node) { \
76937
 
+               if ( list->len + 1 < list->len ) \
76938
 
+                       return FALSE; \
76939
 
+               \
76940
 
+               node->next = before; \
76941
 
+               if ( list->head == before ) { \
76942
 
+                       node->prev = NULL; \
76943
 
+                       list->head = node; \
76944
 
+               } else { \
76945
 
+                       before->prev->next = node; \
76946
 
+               } \
76947
 
+               node->prev = before->prev; \
76948
 
+               before->prev = node; \
76949
 
+               list->len++; \
76950
 
+               node->list = list; \
76951
 
+               \
76952
 
+               return TRUE; \
76953
 
+       }
76954
 
+
76955
 
+#define __LIST_JOIN(list, node_type, items) { \
76956
 
+               node_type *node; \
76957
 
+               \
76958
 
+               if ( list->len + items->len < list->len ) \
76959
 
+                       return FALSE; \
76960
 
+               \
76961
 
+               if ( items->len == 0 ) return TRUE; \
76962
 
+               \
76963
 
+               if ( list->head == NULL ) { \
76964
 
+                       list->head = items->head; \
76965
 
+                       list->tail = items->tail; \
76966
 
+               } else { \
76967
 
+                       list->tail->next = items->head; \
76968
 
+                       items->head->prev = list->tail; \
76969
 
+                       list->tail = items->tail; \
76970
 
+               } \
76971
 
+               list->len += items->len; \
76972
 
+               \
76973
 
+               node = items->head; \
76974
 
+               while ( node != NULL ) { \
76975
 
+                       node->list = list; \
76976
 
+                       node = node->next; \
76977
 
+               } \
76978
 
+               return TRUE; \
76979
 
+       }        
76980
 
+
76981
 
+#define __LIST_DETACH(first, node_type, count) { \
76982
 
+               node_type *last, *result; \
76983
 
+               unsigned int left; \
76984
 
+               \
76985
 
+               i_assert(first->list != NULL); \
76986
 
+               \
76987
 
+               left = count - 1; \
76988
 
+               last = first; \
76989
 
+               while ( left > 0 && last->next != NULL ) { \
76990
 
+                       left--; \
76991
 
+                       last = last->next; \
76992
 
+               } \
76993
 
+               \
76994
 
+               if ( first->list->head == first ) \
76995
 
+                       first->list->head = last->next; \
76996
 
+               if ( first->list->tail == last ) \
76997
 
+                       first->list->tail = first->prev; \
76998
 
+               \
76999
 
+               if ( first->prev != NULL ) \
77000
 
+                       first->prev->next = last->next; \
77001
 
+               if ( last->next != NULL ) \
77002
 
+                       last->next->prev = first->prev; \
77003
 
+               \
77004
 
+               first->list->len -= count - left; \
77005
 
+               \
77006
 
+               result = last->next; \
77007
 
+               first->prev = NULL; \
77008
 
+               last->next = NULL; \
77009
 
+               \
77010
 
+               return result; \
77011
 
+       }
77012
 
+
77013
 
+/* List of AST nodes */
77014
 
+
77015
 
+static struct sieve_ast_list *sieve_ast_list_create(pool_t pool) 
77016
 
+       __LIST_CREATE(pool, struct sieve_ast_list)
77017
 
+
77018
 
+static bool sieve_ast_list_add
77019
 
+(struct sieve_ast_list *list, struct sieve_ast_node *node) 
77020
 
+       __LIST_ADD(list, node)
77021
 
+
77022
 
+static struct sieve_ast_node *sieve_ast_list_detach
77023
 
+(struct sieve_ast_node *first, unsigned int count) 
77024
 
+       __LIST_DETACH(first, struct sieve_ast_node, count)
77025
 
+
77026
 
+/* List of argument AST nodes */
77027
 
+
77028
 
+struct sieve_ast_arg_list *sieve_ast_arg_list_create(pool_t pool) 
77029
 
+       __LIST_CREATE(pool, struct sieve_ast_arg_list)
77030
 
+       
77031
 
+bool sieve_ast_arg_list_add
77032
 
+(struct sieve_ast_arg_list *list, struct sieve_ast_argument *argument)
77033
 
+       __LIST_ADD(list, argument)
77034
 
+
77035
 
+bool sieve_ast_arg_list_insert
77036
 
+(struct sieve_ast_arg_list *list, struct sieve_ast_argument *before,
77037
 
+       struct sieve_ast_argument *argument)
77038
 
+       __LIST_INSERT(list, before, argument)
77039
 
+
77040
 
+static bool sieve_ast_arg_list_join
77041
 
+(struct sieve_ast_arg_list *list, struct sieve_ast_arg_list *items)
77042
 
+       __LIST_JOIN(list, struct sieve_ast_argument, items)
77043
 
+
77044
 
+static struct sieve_ast_argument *sieve_ast_arg_list_detach
77045
 
+(struct sieve_ast_argument *first, const unsigned int count)
77046
 
+       __LIST_DETACH(first, struct sieve_ast_argument, count)
77047
 
+
77048
 
+void sieve_ast_arg_list_substitute
77049
 
+(struct sieve_ast_arg_list *list, struct sieve_ast_argument *argument, 
77050
 
+       struct sieve_ast_argument *replacement)
77051
 
+{
77052
 
+       if ( list->head == argument )
77053
 
+               list->head = replacement;
77054
 
+       if ( list->tail == argument )
77055
 
+               list->tail = replacement;
77056
 
+               
77057
 
+       if ( argument->prev != NULL )
77058
 
+               argument->prev->next = replacement;
77059
 
+       if ( argument->next != NULL )
77060
 
+               argument->next->prev = replacement;
77061
 
+       
77062
 
+       replacement->prev = argument->prev;
77063
 
+       replacement->next = argument->next;
77064
 
+       replacement->list = argument->list;
77065
 
+       
77066
 
+       argument->next = NULL;
77067
 
+       argument->prev = NULL;
77068
 
+}
77069
 
+       
77070
 
+/* 
77071
 
+ * AST node 
77072
 
+ */
77073
 
+
77074
 
+static struct sieve_ast_node *sieve_ast_node_create
77075
 
+(struct sieve_ast *ast, struct sieve_ast_node *parent, enum sieve_ast_type type, 
77076
 
+       unsigned int source_line) 
77077
 
+{
77078
 
+       struct sieve_ast_node *node = p_new(ast->pool, struct sieve_ast_node, 1);
77079
 
+       
77080
 
+       node->ast = ast;
77081
 
+       node->parent = parent;
77082
 
+       node->type = type;
77083
 
+       
77084
 
+       node->prev = NULL;
77085
 
+       node->next = NULL;
77086
 
+       
77087
 
+       node->arguments = NULL;
77088
 
+       node->tests = NULL;
77089
 
+       node->commands = NULL;          
77090
 
+       
77091
 
+       node->test_list = FALSE;
77092
 
+       node->block = FALSE;
77093
 
+       
77094
 
+       node->source_line = source_line;
77095
 
+       
77096
 
+       return node;
77097
 
+}
77098
 
+
77099
 
+static bool sieve_ast_node_add_command
77100
 
+(struct sieve_ast_node *node, struct sieve_ast_node *command) 
77101
 
+{
77102
 
+       i_assert( command->type == SAT_COMMAND && 
77103
 
+               (node->type == SAT_ROOT || node->type == SAT_COMMAND) );
77104
 
+       
77105
 
+       if (node->commands == NULL) 
77106
 
+               node->commands = sieve_ast_list_create(node->ast->pool);
77107
 
+       
77108
 
+       return sieve_ast_list_add(node->commands, command);
77109
 
+}
77110
 
+
77111
 
+static bool sieve_ast_node_add_test
77112
 
+(struct sieve_ast_node *node, struct sieve_ast_node *test) 
77113
 
+{
77114
 
+       i_assert( test->type == SAT_TEST && 
77115
 
+               (node->type == SAT_TEST || node->type == SAT_COMMAND) );
77116
 
+       
77117
 
+       if (node->tests == NULL) 
77118
 
+               node->tests = sieve_ast_list_create(node->ast->pool);
77119
 
+       
77120
 
+       return sieve_ast_list_add(node->tests, test);
77121
 
+}
77122
 
+
77123
 
+static bool sieve_ast_node_add_argument
77124
 
+(struct sieve_ast_node *node, struct sieve_ast_argument *argument) 
77125
 
+{
77126
 
+       i_assert( node->type == SAT_TEST || node->type == SAT_COMMAND );
77127
 
+       
77128
 
+       if (node->arguments == NULL) 
77129
 
+               node->arguments = sieve_ast_arg_list_create(node->ast->pool);
77130
 
+       
77131
 
+       return sieve_ast_arg_list_add(node->arguments, argument);
77132
 
+}
77133
 
+
77134
 
+struct sieve_ast_node *sieve_ast_node_detach
77135
 
+(struct sieve_ast_node *first) 
77136
 
+{      
77137
 
+       return sieve_ast_list_detach(first, 1);
77138
 
+}
77139
 
+
77140
 
+const char *sieve_ast_type_name
77141
 
+(enum sieve_ast_type ast_type) 
77142
 
+{
77143
 
+       switch ( ast_type ) {
77144
 
+       
77145
 
+       case SAT_NONE: return "none";
77146
 
+       case SAT_ROOT: return "ast root node";
77147
 
+       case SAT_COMMAND: return "command";
77148
 
+       case SAT_TEST: return "test";
77149
 
+       
77150
 
+       default: return "??AST NODE??";
77151
 
+       }
77152
 
+}
77153
 
+
77154
 
+/* 
77155
 
+ * Argument AST node 
77156
 
+ */
77157
 
+
77158
 
+struct sieve_ast_argument *sieve_ast_argument_create
77159
 
+(struct sieve_ast *ast, unsigned int source_line) 
77160
 
+{      
77161
 
+       struct sieve_ast_argument *arg = 
77162
 
+               p_new(ast->pool, struct sieve_ast_argument, 1);
77163
 
+       
77164
 
+       arg->ast = ast;
77165
 
+       
77166
 
+       arg->prev = NULL;
77167
 
+       arg->next = NULL;
77168
 
+       
77169
 
+       arg->source_line = source_line;
77170
 
+       arg->context = NULL;
77171
 
+       
77172
 
+       arg->argument = NULL;
77173
 
+       arg->arg_id_code = 0;
77174
 
+                       
77175
 
+       return arg;
77176
 
+}
77177
 
+
77178
 
+static void sieve_ast_argument_substitute
77179
 
+(struct sieve_ast_argument *argument, struct sieve_ast_argument *replacement) 
77180
 
+{
77181
 
+       sieve_ast_arg_list_substitute(argument->list, argument, replacement);
77182
 
+}
77183
 
+
77184
 
+struct sieve_ast_argument *sieve_ast_argument_string_create_raw
77185
 
+(struct sieve_ast *ast, string_t *str, unsigned int source_line) 
77186
 
+{
77187
 
+       struct sieve_ast_argument *argument = sieve_ast_argument_create
77188
 
+               (ast, source_line);
77189
 
+               
77190
 
+       argument->type = SAAT_STRING;
77191
 
+       argument->_value.str = str;
77192
 
+
77193
 
+       return argument;
77194
 
+}
77195
 
+
77196
 
+struct sieve_ast_argument *sieve_ast_argument_string_create
77197
 
+(struct sieve_ast_node *node, const string_t *str, unsigned int source_line) 
77198
 
+{      
77199
 
+       struct sieve_ast_argument *argument;
77200
 
+       string_t *newstr;
77201
 
+       
77202
 
+       /* Allocate new internal string buffer */
77203
 
+       newstr = str_new(node->ast->pool, str_len(str));
77204
 
+       
77205
 
+       /* Clone string */
77206
 
+       str_append_str(newstr, str);
77207
 
+        
77208
 
+       /* Create string argument */
77209
 
+       argument = sieve_ast_argument_string_create_raw
77210
 
+               (node->ast, newstr, source_line);
77211
 
+
77212
 
+       /* Add argument to command/test node */
77213
 
+       sieve_ast_node_add_argument(node, argument);
77214
 
+
77215
 
+       return argument;
77216
 
+}
77217
 
+
77218
 
+struct sieve_ast_argument *sieve_ast_argument_cstring_create
77219
 
+(struct sieve_ast_node *node, const char *str, unsigned int source_line) 
77220
 
+{      
77221
 
+       struct sieve_ast_argument *argument;
77222
 
+       string_t *newstr;
77223
 
+       
77224
 
+       /* Allocate new internal string buffer */
77225
 
+       newstr = str_new(node->ast->pool, strlen(str));
77226
 
+       
77227
 
+       /* Clone string */
77228
 
+       str_append(newstr, str);
77229
 
+        
77230
 
+       /* Create string argument */
77231
 
+       argument = sieve_ast_argument_string_create_raw
77232
 
+               (node->ast, newstr, source_line);
77233
 
+
77234
 
+       /* Add argument to command/test node */
77235
 
+       sieve_ast_node_add_argument(node, argument);
77236
 
+
77237
 
+       return argument;
77238
 
+}
77239
 
+
77240
 
+void sieve_ast_argument_string_set
77241
 
+(struct sieve_ast_argument *argument, string_t *newstr)
77242
 
+{
77243
 
+       i_assert( argument->type == SAAT_STRING);
77244
 
+       argument->_value.str = newstr;
77245
 
+}
77246
 
+
77247
 
+void sieve_ast_argument_string_setc
77248
 
+(struct sieve_ast_argument *argument, const char *newstr)
77249
 
+{
77250
 
+       i_assert( argument->type == SAAT_STRING);
77251
 
+       
77252
 
+       str_truncate(argument->_value.str, 0);
77253
 
+       str_append(argument->_value.str, newstr);
77254
 
+}
77255
 
+
77256
 
+void sieve_ast_argument_number_substitute
77257
 
+(struct sieve_ast_argument *argument, unsigned int number)
77258
 
+{
77259
 
+       argument->type = SAAT_NUMBER;
77260
 
+       argument->_value.number = number;
77261
 
+}
77262
 
+
77263
 
+struct sieve_ast_argument *sieve_ast_argument_stringlist_create
77264
 
+(struct sieve_ast_node *node, unsigned int source_line) 
77265
 
+{
77266
 
+       struct sieve_ast_argument *argument = 
77267
 
+               sieve_ast_argument_create(node->ast, source_line);
77268
 
+       
77269
 
+       argument->type = SAAT_STRING_LIST;
77270
 
+       argument->_value.strlist = NULL;
77271
 
+       
77272
 
+       sieve_ast_node_add_argument(node, argument);
77273
 
+
77274
 
+       return argument;
77275
 
+}
77276
 
+
77277
 
+struct sieve_ast_argument *sieve_ast_argument_stringlist_substitute
77278
 
+(struct sieve_ast_node *node, struct sieve_ast_argument *arg) 
77279
 
+{
77280
 
+       struct sieve_ast_argument *argument = 
77281
 
+               sieve_ast_argument_create(node->ast, arg->source_line);
77282
 
+       
77283
 
+       argument->type = SAAT_STRING_LIST;
77284
 
+       argument->_value.strlist = NULL;
77285
 
+       
77286
 
+       sieve_ast_argument_substitute(arg, argument);
77287
 
+
77288
 
+       return argument;
77289
 
+}
77290
 
+
77291
 
+static inline bool _sieve_ast_stringlist_add_item
77292
 
+(struct sieve_ast_argument *list, struct sieve_ast_argument *item) 
77293
 
+{
77294
 
+       i_assert( list->type == SAAT_STRING_LIST );
77295
 
+       
77296
 
+       if ( list->_value.strlist == NULL ) 
77297
 
+               list->_value.strlist = sieve_ast_arg_list_create(list->ast->pool);
77298
 
+       
77299
 
+       return sieve_ast_arg_list_add(list->_value.strlist, item);
77300
 
+}
77301
 
+
77302
 
+static bool sieve_ast_stringlist_add_stringlist
77303
 
+(struct sieve_ast_argument *list, struct sieve_ast_argument *items) 
77304
 
+{
77305
 
+       i_assert( list->type == SAAT_STRING_LIST );
77306
 
+       i_assert( items->type == SAAT_STRING_LIST );
77307
 
+
77308
 
+       if ( list->_value.strlist == NULL ) 
77309
 
+               list->_value.strlist = sieve_ast_arg_list_create(list->ast->pool);
77310
 
+       
77311
 
+       return sieve_ast_arg_list_join(list->_value.strlist, items->_value.strlist);
77312
 
+}
77313
 
+
77314
 
+static bool _sieve_ast_stringlist_add_str
77315
 
+(struct sieve_ast_argument *list, string_t *str, unsigned int source_line) 
77316
 
+{
77317
 
+       struct sieve_ast_argument *stritem;
77318
 
+       
77319
 
+       stritem = sieve_ast_argument_create(list->ast, source_line);            
77320
 
+       stritem->type = SAAT_STRING;
77321
 
+       stritem->_value.str = str;
77322
 
+
77323
 
+       return _sieve_ast_stringlist_add_item(list, stritem);
77324
 
+}
77325
 
+
77326
 
+bool sieve_ast_stringlist_add
77327
 
+(struct sieve_ast_argument *list, const string_t *str, unsigned int source_line) 
77328
 
+{
77329
 
+       string_t *copied_str = str_new(list->ast->pool, str_len(str));
77330
 
+       str_append_str(copied_str, str);
77331
 
+
77332
 
+       return _sieve_ast_stringlist_add_str(list, copied_str, source_line);
77333
 
+}
77334
 
+
77335
 
+bool sieve_ast_stringlist_add_strc
77336
 
+(struct sieve_ast_argument *list, const char *str, unsigned int source_line) 
77337
 
+{
77338
 
+       string_t *copied_str = str_new(list->ast->pool, strlen(str));
77339
 
+       str_append(copied_str, str);
77340
 
+       
77341
 
+       return _sieve_ast_stringlist_add_str(list, copied_str, source_line);
77342
 
+}
77343
 
+
77344
 
+struct sieve_ast_argument *sieve_ast_argument_tag_create
77345
 
+(struct sieve_ast_node *node, const char *tag, unsigned int source_line) 
77346
 
+{      
77347
 
+       struct sieve_ast_argument *argument = 
77348
 
+               sieve_ast_argument_create(node->ast, source_line);
77349
 
+       
77350
 
+       argument->type = SAAT_TAG;
77351
 
+       argument->_value.tag = p_strdup(node->ast->pool, tag);
77352
 
+
77353
 
+       if ( !sieve_ast_node_add_argument(node, argument) )
77354
 
+               return NULL;
77355
 
+
77356
 
+       return argument;
77357
 
+}
77358
 
+
77359
 
+struct sieve_ast_argument *sieve_ast_argument_tag_insert
77360
 
+(struct sieve_ast_argument *before, const char *tag, unsigned int source_line) 
77361
 
+{      
77362
 
+       struct sieve_ast_argument *argument = 
77363
 
+               sieve_ast_argument_create(before->ast, source_line);
77364
 
+       
77365
 
+       argument->type = SAAT_TAG;
77366
 
+       argument->_value.tag = p_strdup(before->ast->pool, tag);
77367
 
+
77368
 
+       if ( !sieve_ast_arg_list_insert(before->list, before, argument) )
77369
 
+               return NULL;
77370
 
+       
77371
 
+       return argument;
77372
 
+}
77373
 
+
77374
 
+struct sieve_ast_argument *sieve_ast_argument_number_create
77375
 
+(struct sieve_ast_node *node, unsigned int number, unsigned int source_line) 
77376
 
+{
77377
 
+       
77378
 
+       struct sieve_ast_argument *argument = 
77379
 
+               sieve_ast_argument_create(node->ast, source_line);
77380
 
+               
77381
 
+       argument->type = SAAT_NUMBER;
77382
 
+       argument->_value.number = number;
77383
 
+       
77384
 
+       if ( !sieve_ast_node_add_argument(node, argument) )
77385
 
+               return NULL;
77386
 
+       
77387
 
+       return argument;
77388
 
+}
77389
 
+
77390
 
+void sieve_ast_argument_number_set
77391
 
+(struct sieve_ast_argument *argument, unsigned int newnum)
77392
 
+{
77393
 
+       i_assert( argument->type == SAAT_NUMBER );
77394
 
+       argument->_value.number = newnum;
77395
 
+}
77396
 
+
77397
 
+
77398
 
+struct sieve_ast_argument *sieve_ast_arguments_detach
77399
 
+(struct sieve_ast_argument *first, unsigned int count) 
77400
 
+{      
77401
 
+       return sieve_ast_arg_list_detach(first, count);
77402
 
+}
77403
 
+
77404
 
+bool sieve_ast_argument_attach
77405
 
+(struct sieve_ast_node *node, struct sieve_ast_argument *argument)
77406
 
+{
77407
 
+       return sieve_ast_node_add_argument(node, argument);
77408
 
+}
77409
 
+
77410
 
+const char *sieve_ast_argument_type_name
77411
 
+(enum sieve_ast_argument_type arg_type) 
77412
 
+{
77413
 
+       switch ( arg_type ) {
77414
 
+       
77415
 
+       case SAAT_NONE: return "none";
77416
 
+       case SAAT_STRING_LIST: return "a string list";
77417
 
+       case SAAT_STRING: return "a string";
77418
 
+       case SAAT_NUMBER: return "a number";
77419
 
+       case SAAT_TAG: return "a tag";
77420
 
+       
77421
 
+       default: return "??ARGUMENT??";
77422
 
+       }
77423
 
+}
77424
 
+
77425
 
+/* Test AST node */
77426
 
+
77427
 
+struct sieve_ast_node *sieve_ast_test_create
77428
 
+(struct sieve_ast_node *parent, const char *identifier, 
77429
 
+       unsigned int source_line) 
77430
 
+{      
77431
 
+       struct sieve_ast_node *test = sieve_ast_node_create
77432
 
+               (parent->ast, parent, SAT_TEST, source_line);
77433
 
+               
77434
 
+       test->identifier = p_strdup(parent->ast->pool, identifier);
77435
 
+       
77436
 
+       if ( !sieve_ast_node_add_test(parent, test) )
77437
 
+               return NULL;
77438
 
+       
77439
 
+       return test;
77440
 
+}
77441
 
+
77442
 
+/* Command AST node */
77443
 
+
77444
 
+struct sieve_ast_node *sieve_ast_command_create
77445
 
+(struct sieve_ast_node *parent, const char *identifier, 
77446
 
+       unsigned int source_line) 
77447
 
+{
77448
 
+
77449
 
+       struct sieve_ast_node *command = sieve_ast_node_create
77450
 
+               (parent->ast, parent, SAT_COMMAND, source_line);
77451
 
+       
77452
 
+       command->identifier = p_strdup(parent->ast->pool, identifier);
77453
 
+       
77454
 
+       if ( !sieve_ast_node_add_command(parent, command) )
77455
 
+               return NULL;
77456
 
+       
77457
 
+       return command;
77458
 
+}
77459
 
+
77460
 
+/*
77461
 
+ * Utility
77462
 
+ */
77463
 
+
77464
 
+int sieve_ast_stringlist_map
77465
 
+(struct sieve_ast_argument **listitem, void *context,
77466
 
+       int (*map_function)(void *context, struct sieve_ast_argument *arg))
77467
 
+{
77468
 
+       if ( sieve_ast_argument_type(*listitem) == SAAT_STRING ) {
77469
 
+               /* Single string */
77470
 
+               return map_function(context, *listitem);
77471
 
+       } else if ( sieve_ast_argument_type(*listitem) == SAAT_STRING_LIST ) {
77472
 
+               int ret = 0; 
77473
 
+               
77474
 
+               /* String list */
77475
 
+               *listitem = sieve_ast_strlist_first(*listitem);
77476
 
+               
77477
 
+               while ( *listitem != NULL ) {
77478
 
+                       
77479
 
+                       if ( (ret=map_function(context, *listitem)) <= 0 )
77480
 
+                               return ret;
77481
 
+                       
77482
 
+                       *listitem = sieve_ast_strlist_next(*listitem);
77483
 
+               }
77484
 
+               
77485
 
+               return ret;
77486
 
+       } 
77487
 
+       
77488
 
+       i_unreached();
77489
 
+       return -1;
77490
 
+}
77491
 
+
77492
 
+struct sieve_ast_argument *sieve_ast_stringlist_join
77493
 
+(struct sieve_ast_argument *list, struct sieve_ast_argument *items)
77494
 
+{
77495
 
+       enum sieve_ast_argument_type list_type, items_type;
77496
 
+       struct sieve_ast_argument *newlist;
77497
 
+       
77498
 
+       list_type = sieve_ast_argument_type(list);
77499
 
+       items_type = sieve_ast_argument_type(items);
77500
 
+       
77501
 
+       switch ( list_type ) {
77502
 
+       
77503
 
+       case SAAT_STRING:
77504
 
+               switch ( items_type ) {
77505
 
+               
77506
 
+               case SAAT_STRING:
77507
 
+                       newlist = 
77508
 
+                               sieve_ast_argument_create(list->ast, list->source_line);
77509
 
+                       newlist->type = SAAT_STRING_LIST;
77510
 
+                       newlist->_value.strlist = NULL;
77511
 
+                       
77512
 
+                       sieve_ast_argument_substitute(list, newlist);
77513
 
+                       sieve_ast_arguments_detach(items, 1);
77514
 
+                       
77515
 
+                       if ( !_sieve_ast_stringlist_add_item(newlist, list) ||
77516
 
+                               !_sieve_ast_stringlist_add_item(newlist, items) ) {
77517
 
+                               return NULL;
77518
 
+                       }
77519
 
+                       
77520
 
+                       return newlist;
77521
 
+                       
77522
 
+               case SAAT_STRING_LIST:
77523
 
+                       /* Adding stringlist to string; make them swith places and add one to the
77524
 
+                        * other.
77525
 
+                        */
77526
 
+                       sieve_ast_arguments_detach(items, 1);
77527
 
+                       sieve_ast_argument_substitute(list, items);
77528
 
+                       if ( !_sieve_ast_stringlist_add_item(items, list) ) 
77529
 
+                               return NULL;
77530
 
+                       
77531
 
+                       return list;
77532
 
+                       
77533
 
+               default:
77534
 
+                       i_unreached();
77535
 
+               }
77536
 
+               break;
77537
 
+               
77538
 
+       case SAAT_STRING_LIST:
77539
 
+               switch ( items_type ) {
77540
 
+               
77541
 
+               case SAAT_STRING:
77542
 
+                       /* Adding string to stringlist; straightforward add */
77543
 
+                       sieve_ast_arguments_detach(items, 1);
77544
 
+                       if ( !_sieve_ast_stringlist_add_item(list, items) )
77545
 
+                               return NULL;
77546
 
+                       
77547
 
+                       return list;
77548
 
+                       
77549
 
+               case SAAT_STRING_LIST:
77550
 
+                       /* Adding stringlist to stringlist; perform actual join */
77551
 
+                       sieve_ast_arguments_detach(items, 1);
77552
 
+                       if ( !sieve_ast_stringlist_add_stringlist(list, items) )
77553
 
+                               return NULL;
77554
 
+                       
77555
 
+                       return list;
77556
 
+                       
77557
 
+               default:
77558
 
+                       i_unreached();
77559
 
+               }
77560
 
+               
77561
 
+               break;
77562
 
+       default:
77563
 
+               i_unreached();
77564
 
+       }
77565
 
+       
77566
 
+       return NULL;
77567
 
+}
77568
 
+
77569
 
+
77570
 
+/* Debug */
77571
 
+
77572
 
+/* Unparsing, currently implemented using plain printf()s */
77573
 
+
77574
 
+static void sieve_ast_unparse_string(const string_t *strval) 
77575
 
+{
77576
 
+       char *str = t_strdup_noconst(str_c((string_t *) strval));
77577
 
+
77578
 
+       if ( strchr(str, '\n') != NULL && str[strlen(str)-1] == '\n' ) {
77579
 
+               /* Print it as a multi-line string and do required dotstuffing */
77580
 
+               char *spos = str;
77581
 
+               char *epos = strchr(str, '\n');
77582
 
+               printf("text:\n");
77583
 
+               
77584
 
+               while ( epos != NULL ) {
77585
 
+                       *epos = '\0';
77586
 
+                       if ( *spos == '.' ) 
77587
 
+                               printf(".");
77588
 
+                       
77589
 
+                       printf("%s\n", spos);
77590
 
+                       
77591
 
+                       spos = epos+1;
77592
 
+                       epos = strchr(spos, '\n');
77593
 
+               }
77594
 
+               if ( *spos == '.' ) 
77595
 
+                               printf(".");
77596
 
+               
77597
 
+               printf("%s\n.\n", spos);        
77598
 
+       } else {
77599
 
+               /* Print it as a quoted string and escape " */
77600
 
+               char *spos = str;
77601
 
+               char *epos = strchr(str, '"');
77602
 
+               printf("\"");
77603
 
+               
77604
 
+               while ( epos != NULL ) {
77605
 
+                       *epos = '\0';
77606
 
+                       printf("%s\\\"", spos);
77607
 
+                       
77608
 
+                       spos = epos+1;
77609
 
+                       epos = strchr(spos, '"');
77610
 
+               }
77611
 
+               
77612
 
+               printf("%s\"", spos);
77613
 
+       }
77614
 
+}
77615
 
+
77616
 
+static void sieve_ast_unparse_argument
77617
 
+       (struct sieve_ast_argument *argument, int level);
77618
 
+
77619
 
+static void sieve_ast_unparse_stringlist
77620
 
+(struct sieve_ast_argument *strlist, int level) 
77621
 
+{
77622
 
+       struct sieve_ast_argument *stritem;
77623
 
+       
77624
 
+       if ( sieve_ast_strlist_count(strlist) > 1 ) { 
77625
 
+               int i;
77626
 
+               
77627
 
+               printf("[\n");
77628
 
+       
77629
 
+               /* Create indent */
77630
 
+               for ( i = 0; i < level+2; i++ ) 
77631
 
+                       printf("  ");   
77632
 
+
77633
 
+               stritem = sieve_ast_strlist_first(strlist);
77634
 
+               sieve_ast_unparse_string(sieve_ast_strlist_str(stritem));
77635
 
+               
77636
 
+               stritem = sieve_ast_strlist_next(stritem);
77637
 
+               while ( stritem != NULL ) {
77638
 
+                       printf(",\n");
77639
 
+                       for ( i = 0; i < level+2; i++ ) 
77640
 
+                               printf("  ");
77641
 
+                       sieve_ast_unparse_string(sieve_ast_strlist_str(stritem));
77642
 
+                 stritem = sieve_ast_strlist_next(stritem);
77643
 
+         }
77644
 
77645
 
+               printf(" ]");
77646
 
+       } else {
77647
 
+               stritem = sieve_ast_strlist_first(strlist);
77648
 
+               if ( stritem != NULL ) 
77649
 
+                       sieve_ast_unparse_string(sieve_ast_strlist_str(stritem));
77650
 
+       }
77651
 
+}
77652
 
+
77653
 
+static void sieve_ast_unparse_argument
77654
 
+(struct sieve_ast_argument *argument, int level) 
77655
 
+{
77656
 
+       switch ( argument->type ) {
77657
 
+       case SAAT_STRING:
77658
 
+               sieve_ast_unparse_string(sieve_ast_argument_str(argument));
77659
 
+               break;
77660
 
+       case SAAT_STRING_LIST:
77661
 
+               sieve_ast_unparse_stringlist(argument, level+1);
77662
 
+               break;
77663
 
+       case SAAT_NUMBER:
77664
 
+               printf("%d", sieve_ast_argument_number(argument));
77665
 
+               break;
77666
 
+       case SAAT_TAG:
77667
 
+               printf(":%s", sieve_ast_argument_tag(argument));
77668
 
+               break;
77669
 
+       default:
77670
 
+               printf("??ARGUMENT??");
77671
 
+               break;
77672
 
+       }
77673
 
+}
77674
 
+
77675
 
+static void sieve_ast_unparse_test
77676
 
+       (struct sieve_ast_node *node, int level);
77677
 
+
77678
 
+static void sieve_ast_unparse_tests
77679
 
+(struct sieve_ast_node *node, int level) 
77680
 
+{
77681
 
+       struct sieve_ast_node *test;
77682
 
+       
77683
 
+       if ( sieve_ast_test_count(node) > 1 ) { 
77684
 
+               int i;
77685
 
+               
77686
 
+               printf(" (\n");
77687
 
+       
77688
 
+               /* Create indent */
77689
 
+               for ( i = 0; i < level+2; i++ ) 
77690
 
+                       printf("  ");   
77691
 
+
77692
 
+               test = sieve_ast_test_first(node);
77693
 
+               sieve_ast_unparse_test(test, level+1);
77694
 
+               
77695
 
+               test = sieve_ast_test_next(test);
77696
 
+               while ( test != NULL ) {
77697
 
+                       printf(", \n");
77698
 
+                       for ( i = 0; i < level+2; i++ ) 
77699
 
+                               printf("  ");
77700
 
+                       sieve_ast_unparse_test(test, level+1);
77701
 
+                 test = sieve_ast_test_next(test);
77702
 
+         }
77703
 
77704
 
+               printf(" )");
77705
 
+       } else {
77706
 
+               test = sieve_ast_test_first(node);
77707
 
+               if ( test != NULL ) 
77708
 
+                       sieve_ast_unparse_test(test, level);
77709
 
+       }
77710
 
+}
77711
 
+
77712
 
+static void sieve_ast_unparse_test
77713
 
+(struct sieve_ast_node *node, int level) 
77714
 
+{
77715
 
+       struct sieve_ast_argument *argument;
77716
 
+               
77717
 
+       printf(" %s", node->identifier);
77718
 
+       
77719
 
+       argument = sieve_ast_argument_first(node);
77720
 
+       while ( argument != NULL ) {
77721
 
+               printf(" ");
77722
 
+               sieve_ast_unparse_argument(argument, level);
77723
 
+               argument = sieve_ast_argument_next(argument);
77724
 
+       }
77725
 
+       
77726
 
+       sieve_ast_unparse_tests(node, level);
77727
 
+}
77728
 
+
77729
 
+static void sieve_ast_unparse_command
77730
 
+(struct sieve_ast_node *node, int level) 
77731
 
+{
77732
 
+       struct sieve_ast_node *command;
77733
 
+       struct sieve_ast_argument *argument;
77734
 
+       
77735
 
+       int i;
77736
 
+       
77737
 
+       /* Create indent */
77738
 
+       for ( i = 0; i < level; i++ ) 
77739
 
+               printf("  ");
77740
 
+               
77741
 
+       printf("%s", node->identifier);
77742
 
+       
77743
 
+       argument = sieve_ast_argument_first(node);
77744
 
+       while ( argument != NULL ) {
77745
 
+               printf(" ");
77746
 
+               sieve_ast_unparse_argument(argument, level);
77747
 
+               argument = sieve_ast_argument_next(argument);
77748
 
+       }
77749
 
+       
77750
 
+       sieve_ast_unparse_tests(node, level);
77751
 
+       
77752
 
+       command = sieve_ast_command_first(node);
77753
 
+       if ( command != NULL ) {
77754
 
+               printf(" {\n");
77755
 
+               
77756
 
+               while ( command != NULL) {      
77757
 
+                       sieve_ast_unparse_command(command, level+1);
77758
 
+                       command = sieve_ast_command_next(command);
77759
 
+               }
77760
 
+               
77761
 
+               for ( i = 0; i < level; i++ ) 
77762
 
+                       printf("  ");
77763
 
+               printf("}\n");
77764
 
+       } else 
77765
 
+               printf(";\n");
77766
 
+}
77767
 
+
77768
 
+void sieve_ast_unparse(struct sieve_ast *ast) 
77769
 
+{
77770
 
+       struct sieve_ast_node *command;
77771
 
+
77772
 
+       printf("Unparsing Abstract Syntax Tree:\n");
77773
 
+
77774
 
+       T_BEGIN {       
77775
 
+               command = sieve_ast_command_first(sieve_ast_root(ast));
77776
 
+               while ( command != NULL ) {     
77777
 
+                       sieve_ast_unparse_command(command, 0);
77778
 
+                       command = sieve_ast_command_next(command);
77779
 
+               }               
77780
 
+       } T_END;
77781
 
+}
77782
 
+
77783
 
+
77784
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-ast.h dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-ast.h
77785
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-ast.h    1970-01-01 01:00:00.000000000 +0100
77786
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-ast.h     2009-07-08 19:23:24.000000000 +0200
77787
 
@@ -0,0 +1,372 @@
77788
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
77789
 
+ */
77790
 
+
77791
 
+#ifndef __SIEVE_AST_H
77792
 
+#define __SIEVE_AST_H
77793
 
+
77794
 
+#include "lib.h"
77795
 
+#include "str.h"
77796
 
+
77797
 
+#include "sieve-common.h"
77798
 
+#include "sieve-error.h"
77799
 
+
77800
 
+/*
77801
 
+       Abstract Syntax Tree (AST) structure:
77802
 
+       
77803
 
+       sieve_ast (root)
77804
 
+       [*command]
77805
 
+        |
77806
 
+        +-- command:
77807
 
+        |   ....
77808
 
+        +-- command:
77809
 
+        |       [identifier *argument                      *test *command]
77810
 
+        |                +-- argument:                 |     \--> as from root
77811
 
+        |                |   ....                      |
77812
 
+        |                +-- argument:                 V (continued below)
77813
 
+        |                |   [number | tag | *string]
77814
 
+        |                .
77815
 
+        .
77816
 
+       
77817
 
+        *test
77818
 
+        +-- test:
77819
 
+        |   ....
77820
 
+        +-- test:
77821
 
+        |   [identifier *argument                     *test]
77822
 
+        |               +-- argument:                 \-->  as from the top 
77823
 
+        .               |   ....                              of this tree
77824
 
+                        +-- argument:
77825
 
+                        |   [number | tag | *string]
77826
 
+                        .
77827
 
+                        
77828
 
+        Tests and commands are defined using the same structure: sieve_ast_node. 
77829
 
+        However, arguments and string-lists are described using sieve_ast_argument.  
77830
 
+*/
77831
 
+
77832
 
+/* IMPORTANT NOTICE: Do not decorate the AST with objects other than those 
77833
 
+ * allocated on the ast's pool or static const objects. Otherwise it is possible 
77834
 
+ * that pointers in the tree become dangling which is highly undesirable.
77835
 
+ */
77836
 
+
77837
 
+/*
77838
 
+ * Forward declarations
77839
 
+ */ 
77840
 
+
77841
 
+struct sieve_ast_list;
77842
 
+struct sieve_ast_arg_list;
77843
 
+
77844
 
+/*
77845
 
+ * Types
77846
 
+ */
77847
 
77848
 
+enum sieve_ast_argument_type {
77849
 
+       SAAT_NONE,
77850
 
+       SAAT_NUMBER,
77851
 
+       SAAT_STRING,
77852
 
+       SAAT_STRING_LIST,
77853
 
+       SAAT_TAG,
77854
 
+};
77855
 
+
77856
 
+enum sieve_ast_type {
77857
 
+       SAT_NONE,
77858
 
+       SAT_ROOT,
77859
 
+       SAT_COMMAND,
77860
 
+       SAT_TEST,
77861
 
+};
77862
 
+
77863
 
+/*
77864
 
+ * AST Nodes
77865
 
+ */
77866
 
77867
 
+/* Argument node */
77868
 
+
77869
 
+struct sieve_ast_argument {
77870
 
+       enum sieve_ast_argument_type type;
77871
 
+
77872
 
+       /* Back reference to the AST object */
77873
 
+       struct sieve_ast *ast;
77874
 
+
77875
 
+       /* List related */
77876
 
+       struct sieve_ast_arg_list *list;
77877
 
+       struct sieve_ast_argument *next;
77878
 
+       struct sieve_ast_argument *prev;
77879
 
+  
77880
 
+       /* Parser-assigned data */
77881
 
+  
77882
 
+       union { 
77883
 
+               string_t *str;
77884
 
+               struct sieve_ast_arg_list *strlist;
77885
 
+               const char *tag;
77886
 
+               unsigned int number;
77887
 
+       } _value;
77888
 
+  
77889
 
+       unsigned int source_line;
77890
 
+  
77891
 
+       /* Assigned during validation */
77892
 
+
77893
 
+       /* Argument associated with this ast element  */
77894
 
+       const struct sieve_argument *argument;
77895
 
+       int arg_id_code;
77896
 
+
77897
 
+       /* Parameters to this (tag) argument */
77898
 
+       struct sieve_ast_argument *parameters;
77899
 
+       
77900
 
+       /* Context data associated with this ast element */
77901
 
+       void *context;
77902
 
+};
77903
 
+
77904
 
+struct sieve_ast_node {
77905
 
+       enum sieve_ast_type type;
77906
 
+
77907
 
+       /* Back reference to the AST object */
77908
 
+       struct sieve_ast *ast;
77909
 
+       
77910
 
+       /* Back reference to this node's parent */
77911
 
+       struct sieve_ast_node *parent;
77912
 
+       
77913
 
+       /* Linked list references */
77914
 
+       struct sieve_ast_list *list;
77915
 
+       struct sieve_ast_node *next;
77916
 
+       struct sieve_ast_node *prev;
77917
 
+       
77918
 
+       /* Commands (NULL if not allocated) */
77919
 
+       bool block;
77920
 
+       struct sieve_ast_list *commands;
77921
 
+       
77922
 
+       /* Tests (NULL if not allocated)*/
77923
 
+       bool test_list;
77924
 
+       struct sieve_ast_list *tests;
77925
 
+
77926
 
+       /* Arguments (NULL if not allocated) */
77927
 
+       struct sieve_ast_arg_list *arguments;   
77928
 
+
77929
 
+       /* Identifier of command or test */
77930
 
+       const char *identifier;         
77931
 
+
77932
 
+       /* The location in the file where this command was started */
77933
 
+       unsigned int source_line;
77934
 
+               
77935
 
+       /* Assigned during validation */
77936
 
+               
77937
 
+       /* Context */
77938
 
+       struct sieve_command_context *context;  
77939
 
+};
77940
 
+
77941
 
+/*
77942
 
+ * AST node lists
77943
 
+ */
77944
 
77945
 
+struct sieve_ast_list {
77946
 
+       struct sieve_ast_node *head;            
77947
 
+       struct sieve_ast_node *tail;
77948
 
+       unsigned int len;       
77949
 
+};
77950
 
+
77951
 
+struct sieve_ast_arg_list {
77952
 
+       struct sieve_ast_argument *head;                
77953
 
+       struct sieve_ast_argument *tail;
77954
 
+       unsigned int len;       
77955
 
+};
77956
 
+
77957
 
+/*
77958
 
+ * AST object 
77959
 
+ */
77960
 
77961
 
+struct sieve_ast; 
77962
 
77963
 
+struct sieve_ast *sieve_ast_create(struct sieve_script *script);
77964
 
+void sieve_ast_ref(struct sieve_ast *ast);
77965
 
+void sieve_ast_unref(struct sieve_ast **ast);
77966
 
+
77967
 
+struct sieve_ast_node *sieve_ast_root(struct sieve_ast *ast);
77968
 
+pool_t sieve_ast_pool(struct sieve_ast *ast);
77969
 
+struct sieve_script *sieve_ast_script(struct sieve_ast *ast);
77970
 
+
77971
 
+/* Extension support */
77972
 
+
77973
 
+struct sieve_ast_extension {
77974
 
+       const struct sieve_extension *ext;      
77975
 
+
77976
 
+       void (*free)(struct sieve_ast *ast, void *context);
77977
 
+};
77978
 
+
77979
 
+void sieve_ast_extension_link
77980
 
+       (struct sieve_ast *ast, const struct sieve_extension *ext);
77981
 
+const struct sieve_extension * const *sieve_ast_extensions_get
77982
 
+       (struct sieve_ast *ast, unsigned int *count_r);
77983
 
+
77984
 
+void sieve_ast_extension_register
77985
 
+       (struct sieve_ast *ast, const struct sieve_ast_extension *ast_ext, 
77986
 
+               void *context);
77987
 
+void *sieve_ast_extension_get_context
77988
 
+       (struct sieve_ast *ast, const struct sieve_extension *ext);
77989
 
+
77990
 
+/* 
77991
 
+ * AST node manipulation
77992
 
+ */
77993
 
77994
 
+/* Command nodes */
77995
 
+
77996
 
+struct sieve_ast_node *sieve_ast_test_create
77997
 
+       (struct sieve_ast_node *parent, const char *identifier, 
77998
 
+               unsigned int source_line);
77999
 
+struct sieve_ast_node *sieve_ast_command_create
78000
 
+       (struct sieve_ast_node *parent, const char *identifier, 
78001
 
+               unsigned int source_line);
78002
 
+
78003
 
+struct sieve_ast_node *sieve_ast_node_detach
78004
 
+       (struct sieve_ast_node *first);
78005
 
+
78006
 
+const char *sieve_ast_type_name(enum sieve_ast_type ast_type);
78007
 
+       
78008
 
+/* Argument nodes */
78009
 
+
78010
 
+struct sieve_ast_argument *sieve_ast_argument_create
78011
 
+       (struct sieve_ast *ast, unsigned int source_line);
78012
 
+
78013
 
+struct sieve_ast_arg_list *sieve_ast_arg_list_create(pool_t pool);     
78014
 
+bool sieve_ast_arg_list_add
78015
 
+       (struct sieve_ast_arg_list *list, struct sieve_ast_argument *argument);
78016
 
+bool sieve_ast_arg_list_insert
78017
 
+       (struct sieve_ast_arg_list *list, struct sieve_ast_argument *before,
78018
 
+               struct sieve_ast_argument *argument);
78019
 
+void sieve_ast_arg_list_substitute
78020
 
+       (struct sieve_ast_arg_list *list, struct sieve_ast_argument *argument, 
78021
 
+               struct sieve_ast_argument *replacement);
78022
 
+
78023
 
+struct sieve_ast_argument *sieve_ast_argument_string_create_raw
78024
 
+       (struct sieve_ast *ast, string_t *str, unsigned int source_line);
78025
 
+struct sieve_ast_argument *sieve_ast_argument_string_create
78026
 
+       (struct sieve_ast_node *node, const string_t *str, unsigned int source_line);
78027
 
+struct sieve_ast_argument *sieve_ast_argument_cstring_create
78028
 
+       (struct sieve_ast_node *node, const char *str, unsigned int source_line);
78029
 
+       
78030
 
+struct sieve_ast_argument *sieve_ast_argument_tag_create
78031
 
+       (struct sieve_ast_node *node, const char *tag, unsigned int source_line);
78032
 
+
78033
 
+struct sieve_ast_argument *sieve_ast_argument_number_create
78034
 
+       (struct sieve_ast_node *node, unsigned int number, unsigned int source_line);
78035
 
+
78036
 
+void sieve_ast_argument_string_set
78037
 
+       (struct sieve_ast_argument *argument, string_t *newstr);
78038
 
+void sieve_ast_argument_string_setc
78039
 
+       (struct sieve_ast_argument *argument, const char *newstr);
78040
 
+
78041
 
+void sieve_ast_argument_number_set
78042
 
+       (struct sieve_ast_argument *argument, unsigned int newnum);
78043
 
+void sieve_ast_argument_number_substitute
78044
 
+       (struct sieve_ast_argument *argument, unsigned int number);
78045
 
+
78046
 
+struct sieve_ast_argument *sieve_ast_argument_tag_insert
78047
 
+(struct sieve_ast_argument *before, const char *tag, unsigned int source_line); 
78048
 
+
78049
 
+struct sieve_ast_argument *sieve_ast_argument_stringlist_create
78050
 
+       (struct sieve_ast_node *node, unsigned int source_line);
78051
 
+struct sieve_ast_argument *sieve_ast_argument_stringlist_substitute
78052
 
+       (struct sieve_ast_node *node, struct sieve_ast_argument *arg);
78053
 
+
78054
 
+struct sieve_ast_argument *sieve_ast_arguments_detach
78055
 
+       (struct sieve_ast_argument *first, unsigned int count);
78056
 
+bool sieve_ast_argument_attach
78057
 
+       (struct sieve_ast_node *node, struct sieve_ast_argument *argument);
78058
 
+       
78059
 
+const char *sieve_ast_argument_type_name(enum sieve_ast_argument_type arg_type);
78060
 
+#define sieve_ast_argument_name(argument) \
78061
 
+       sieve_ast_argument_type_name((argument)->type)
78062
 
+
78063
 
+bool sieve_ast_stringlist_add
78064
 
+       (struct sieve_ast_argument *list, const string_t *str, 
78065
 
+               unsigned int source_line);
78066
 
+bool sieve_ast_stringlist_add_strc
78067
 
+       (struct sieve_ast_argument *list, const char *str, 
78068
 
+               unsigned int source_line);
78069
 
+               
78070
 
+/* 
78071
 
+ * Utility
78072
 
+ */
78073
 
+
78074
 
+int sieve_ast_stringlist_map
78075
 
+       (struct sieve_ast_argument **listitem, void *context,
78076
 
+               int (*map_function)(void *context, struct sieve_ast_argument *arg));
78077
 
+struct sieve_ast_argument *sieve_ast_stringlist_join
78078
 
+       (struct sieve_ast_argument *list, struct sieve_ast_argument *items);
78079
 
+       
78080
 
+/* 
78081
 
+ * AST access macros 
78082
 
+ */
78083
 
+
78084
 
+/* Generic list access macros */
78085
 
+#define __AST_LIST_FIRST(list) \
78086
 
+       ((list) == NULL ? NULL : (list)->head)
78087
 
+#define __AST_LIST_LAST(list) \
78088
 
+       ((list) == NULL ? NULL : (list)->tail)
78089
 
+#define __AST_LIST_COUNT(list) \
78090
 
+       ((list) == NULL || (list)->head == NULL ? 0 : (list)->len)
78091
 
+#define __AST_LIST_NEXT(item) ((item)->next)
78092
 
+#define __AST_LIST_PREV(item) ((item)->prev)
78093
 
+
78094
 
+#define __AST_NODE_LIST_FIRST(node, list) __AST_LIST_FIRST((node)->list)
78095
 
+#define __AST_NODE_LIST_LAST(node, list) __AST_LIST_LAST((node)->list)
78096
 
+#define __AST_NODE_LIST_COUNT(node, list) __AST_LIST_COUNT((node)->list)
78097
 
+
78098
 
+/* AST macros */
78099
 
+
78100
 
+/* AST node macros */
78101
 
+#define sieve_ast_node_pool(node) (sieve_ast_pool((node)->ast))
78102
 
+#define sieve_ast_node_parent(node) ((node)->parent)
78103
 
+#define sieve_ast_node_prev(node) __AST_LIST_PREV(node)
78104
 
+#define sieve_ast_node_next(node) __AST_LIST_NEXT(node)
78105
 
+#define sieve_ast_node_type(node) ((node) == NULL ? SAT_NONE : (node)->type)
78106
 
+#define sieve_ast_node_line(node) ((node) == NULL ? 0 : (node)->source_line)
78107
 
+
78108
 
+/* AST command node macros */
78109
 
+#define sieve_ast_command_first(node) __AST_NODE_LIST_FIRST(node, commands)
78110
 
+#define sieve_ast_command_count(node) __AST_NODE_LIST_COUNT(node, commands)
78111
 
+#define sieve_ast_command_prev(command) __AST_LIST_PREV(command)
78112
 
+#define sieve_ast_command_next(command) __AST_LIST_NEXT(command)
78113
 
+
78114
 
+/* Compare the identifier of the previous command */
78115
 
+#define sieve_ast_prev_cmd_is(cmd, id) \
78116
 
+       ( (cmd)->prev == NULL ? FALSE : \
78117
 
+               strncasecmp((cmd)->prev->identifier, id, sizeof(id)-1) == 0 )
78118
 
+       
78119
 
+/* AST test macros */
78120
 
+#define sieve_ast_test_count(node) __AST_NODE_LIST_COUNT(node, tests)
78121
 
+#define sieve_ast_test_first(node) __AST_NODE_LIST_FIRST(node, tests)
78122
 
+#define sieve_ast_test_next(test) __AST_LIST_NEXT(test)
78123
 
+
78124
 
+/* AST argument macros */
78125
 
+#define sieve_ast_argument_first(node) __AST_NODE_LIST_FIRST(node, arguments)
78126
 
+#define sieve_ast_argument_last(node) __AST_NODE_LIST_LAST(node, arguments)
78127
 
+#define sieve_ast_argument_count(node) __AST_NODE_LIST_COUNT(node, arguments)
78128
 
+#define sieve_ast_argument_prev(argument) __AST_LIST_PREV(argument)
78129
 
+#define sieve_ast_argument_next(argument) __AST_LIST_NEXT(argument)
78130
 
+#define sieve_ast_argument_type(argument) \
78131
 
+       ((argument) == NULL ? SAAT_NONE : (argument)->type)
78132
 
+#define sieve_ast_argument_line(argument) \
78133
 
+       ((argument) == NULL ? 0 : (argument)->source_line)
78134
 
+
78135
 
+#define sieve_ast_argument_str(argument) ((argument)->_value.str)
78136
 
+#define sieve_ast_argument_strc(argument) (str_c((argument)->_value.str))
78137
 
+#define sieve_ast_argument_tag(argument) ((argument)->_value.tag)
78138
 
+#define sieve_ast_argument_number(argument) ((argument)->_value.number)
78139
 
+
78140
 
+/* AST string list macros */
78141
 
+// @UNSAFE: should check whether we are actually accessing a string list
78142
 
+#define sieve_ast_strlist_first(list) \
78143
 
+       __AST_NODE_LIST_FIRST(list, _value.strlist)
78144
 
+#define sieve_ast_strlist_last(list) \
78145
 
+       __AST_NODE_LIST_LAST(list, _value.strlist)
78146
 
+#define sieve_ast_strlist_count(list) \
78147
 
+       __AST_NODE_LIST_COUNT(list, _value.strlist)
78148
 
+#define sieve_ast_strlist_next(str) __AST_LIST_NEXT(str)
78149
 
+#define sieve_ast_strlist_prev(str) __AST_LIST_PREV(str)
78150
 
+#define sieve_ast_strlist_str(str) sieve_ast_argument_str(str)
78151
 
+#define sieve_ast_strlist_strc(str) sieve_ast_argument_strc(str)
78152
 
+
78153
 
+/* 
78154
 
+ * Debug 
78155
 
+ */
78156
 
+
78157
 
+void sieve_ast_unparse(struct sieve_ast *ast);
78158
 
+
78159
 
+#endif /* __SIEVE_AST_H */
78160
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-binary.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-binary.c
78161
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-binary.c 1970-01-01 01:00:00.000000000 +0100
78162
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-binary.c  2009-08-05 13:07:17.000000000 +0200
78163
 
@@ -0,0 +1,1776 @@
78164
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
78165
 
+ */
78166
 
+
78167
 
+#include "lib.h"
78168
 
+#include "str.h"
78169
 
+#include "str-sanitize.h"
78170
 
+#include "mempool.h"
78171
 
+#include "buffer.h"
78172
 
+#include "hash.h"
78173
 
+#include "array.h"
78174
 
+#include "ostream.h"
78175
 
+#include "eacces-error.h"      
78176
 
+
78177
 
+#include "sieve-error.h"
78178
 
+#include "sieve-extensions.h"
78179
 
+#include "sieve-code.h"
78180
 
+#include "sieve-script.h"
78181
 
+
78182
 
+#include "sieve-binary.h"
78183
 
+
78184
 
+#include <sys/types.h>
78185
 
+#include <sys/stat.h>
78186
 
+#include <unistd.h>
78187
 
+#include <fcntl.h>
78188
 
+
78189
 
+/*
78190
 
+ * Config
78191
 
+ */
78192
 
78193
 
+#define SIEVE_BINARY_VERSION_MAJOR     0
78194
 
+#define SIEVE_BINARY_VERSION_MINOR     1
78195
 
+
78196
 
+/*
78197
 
+ * Macros
78198
 
+ */
78199
 
+
78200
 
+#define SIEVE_BINARY_MAGIC              0xcafebabe
78201
 
+#define SIEVE_BINARY_MAGIC_OTHER_ENDIAN 0xbebafeca 
78202
 
+
78203
 
+#define SIEVE_BINARY_ALIGN(offset) \
78204
 
+       (((offset) + 3) & ~3)
78205
 
+#define SIEVE_BINARY_ALIGN_PTR(ptr) \
78206
 
+       ((void *) SIEVE_BINARY_ALIGN(((size_t) ptr)))
78207
 
+
78208
 
+/* 
78209
 
+ * Forward declarations 
78210
 
+ */
78211
 
+
78212
 
+struct sieve_binary_file;
78213
 
+
78214
 
+static bool sieve_binary_file_open
78215
 
+       (struct sieve_binary_file *file, const char *path);
78216
 
+static void sieve_binary_file_close(struct sieve_binary_file **file);
78217
 
+
78218
 
+static struct sieve_binary_block *sieve_binary_load_block
78219
 
+       (struct sieve_binary *sbin, unsigned int id);
78220
 
+
78221
 
+static inline struct sieve_binary_extension_reg *sieve_binary_extension_get_reg
78222
 
+       (struct sieve_binary *sbin, const struct sieve_extension *ext, 
78223
 
+               bool create);
78224
 
+static inline int sieve_binary_extension_register
78225
 
+       (struct sieve_binary *sbin, const struct sieve_extension *ext, 
78226
 
+               struct sieve_binary_extension_reg **reg);
78227
 
+
78228
 
+static inline sieve_size_t sieve_binary_emit_dynamic_data
78229
 
+       (struct sieve_binary *binary, const void *data, size_t size);
78230
 
+
78231
 
+/* 
78232
 
+ * Internal structures
78233
 
+ */
78234
 
+
78235
 
+/* Extension registration */
78236
 
+
78237
 
+struct sieve_binary_extension_reg {
78238
 
+       /* The identifier of the extension within this binary */
78239
 
+       int index;
78240
 
+       
78241
 
+       /* Global extension object */
78242
 
+       const struct sieve_extension *extension; 
78243
 
+       
78244
 
+       /* Extension to the binary; typically used to manage extension-specific blocks 
78245
 
+        * in the binary and as a means to get a binary_free notification to release
78246
 
+        * references held by extensions. 
78247
 
+        */
78248
 
+       const struct sieve_binary_extension *binext;    
78249
 
+       
78250
 
+       /* Context data associated to the binary by this extension */
78251
 
+       void *context;
78252
 
+       
78253
 
+       /* Main block for this extension */
78254
 
+       unsigned int block_id;
78255
 
+};
78256
 
+
78257
 
+/* Block */
78258
 
+
78259
 
+struct sieve_binary_block {
78260
 
+       buffer_t *buffer;
78261
 
+       int ext_index;
78262
 
+       
78263
 
+       uoff_t offset;
78264
 
+};
78265
 
+
78266
 
+/* File */
78267
 
+
78268
 
+/* FIXME: In essence this is an unbuffered stream implementation. Maybe this 
78269
 
+ * can be merged with the generic dovecot istream interface.
78270
 
+ */
78271
 
+struct sieve_binary_file {
78272
 
+       pool_t pool;
78273
 
+       const char *path;
78274
 
+       
78275
 
+       struct stat st;
78276
 
+       int fd;
78277
 
+       off_t offset;
78278
 
+
78279
 
+       bool (*load)(struct sieve_binary_file *file);   
78280
 
+       const void *(*load_data)
78281
 
+               (struct sieve_binary_file *file, off_t *offset, size_t size);
78282
 
+       buffer_t *(*load_buffer)
78283
 
+               (struct sieve_binary_file *file, off_t *offset, size_t size);
78284
 
+};
78285
 
+
78286
 
+/*
78287
 
+ * Binary object
78288
 
+ */
78289
 
+
78290
 
+struct sieve_binary {
78291
 
+       pool_t pool;
78292
 
+       int refcount;
78293
 
+       
78294
 
+       struct sieve_script *script;
78295
 
+       
78296
 
+       struct sieve_binary_file *file;
78297
 
+       
78298
 
+       /* When the binary is loaded into memory or when it is being constructed by
78299
 
+        * the generator, extensions can be associated to the binary. The extensions
78300
 
+        * array is a sequential list of all linked extensions. The extension_index 
78301
 
+        * array is a mapping ext_id -> binary_extension. This is used to obtain the 
78302
 
+        * index code associated with an extension for this particular binary. The 
78303
 
+        * linked_extensions list all extensions linked to this binary object other
78304
 
+        * than the preloaded language features implemented as 'extensions'. 
78305
 
+        * 
78306
 
+        * All arrays refer to the same extension registration objects. Upon loading 
78307
 
+        * a binary, the 'require'd extensions will sometimes need to associate 
78308
 
+        * context data to the binary object in memory. This is stored in these 
78309
 
+        * registration objects as well.
78310
 
+        */
78311
 
+       ARRAY_DEFINE(extensions, struct sieve_binary_extension_reg *); 
78312
 
+       ARRAY_DEFINE(extension_index, struct sieve_binary_extension_reg *); 
78313
 
+       ARRAY_DEFINE(linked_extensions, struct sieve_binary_extension_reg *); 
78314
 
+               
78315
 
+       /* Attributes of a loaded binary */
78316
 
+       const char *path;
78317
 
+               
78318
 
+       /* Blocks */
78319
 
+       ARRAY_DEFINE(blocks, struct sieve_binary_block *); 
78320
 
+       unsigned int active_block;
78321
 
+       
78322
 
+       /* Current block buffer: all emit and read functions act upon this buffer */
78323
 
+       buffer_t *data;
78324
 
+       const signed char *code;
78325
 
+       size_t code_size;
78326
 
+};
78327
 
+
78328
 
+static struct sieve_binary *sieve_binary_create(struct sieve_script *script) 
78329
 
+{
78330
 
+       pool_t pool;
78331
 
+       struct sieve_binary *sbin;
78332
 
+       unsigned int i;
78333
 
+       
78334
 
+       pool = pool_alloconly_create("sieve_binary", 8192);     
78335
 
+       sbin = p_new(pool, struct sieve_binary, 1);
78336
 
+       sbin->pool = pool;
78337
 
+       sbin->refcount = 1;
78338
 
+       sbin->script = script;
78339
 
+       if ( script != NULL ) 
78340
 
+               sieve_script_ref(script);
78341
 
+       
78342
 
+       p_array_init(&sbin->linked_extensions, pool, 5);
78343
 
+       p_array_init(&sbin->extensions, pool, 5);
78344
 
+       p_array_init(&sbin->extension_index, pool, sieve_extensions_get_count());
78345
 
+       
78346
 
+       p_array_init(&sbin->blocks, pool, 3);
78347
 
+
78348
 
+       /* Pre-load core language features implemented as 'extensions' */
78349
 
+       for ( i = 0; i < sieve_preloaded_extensions_count; i++ ) {
78350
 
+               const struct sieve_extension *ext = sieve_preloaded_extensions[i];
78351
 
+               if ( ext->binary_load != NULL )
78352
 
+                       (void)ext->binary_load(sbin);           
78353
 
+       }
78354
 
+                       
78355
 
+       return sbin;
78356
 
+}
78357
 
+
78358
 
+struct sieve_binary *sieve_binary_create_new(struct sieve_script *script) 
78359
 
+{
78360
 
+       struct sieve_binary *sbin = sieve_binary_create(script); 
78361
 
+       
78362
 
+       /* Extensions block */
78363
 
+       (void) sieve_binary_block_create(sbin);
78364
 
+       
78365
 
+       /* Main program block */
78366
 
+       (void) sieve_binary_block_set_active
78367
 
+               (sbin, sieve_binary_block_create(sbin), NULL);
78368
 
+       
78369
 
+       return sbin;
78370
 
+}
78371
 
+
78372
 
+void sieve_binary_ref(struct sieve_binary *sbin) 
78373
 
+{
78374
 
+       sbin->refcount++;
78375
 
+}
78376
 
+
78377
 
+static inline void sieve_binary_extensions_free(struct sieve_binary *sbin) 
78378
 
+{
78379
 
+       unsigned int ext_count, i;
78380
 
+       
78381
 
+       /* Cleanup binary extensions */
78382
 
+       ext_count = array_count(&sbin->extensions);     
78383
 
+       for ( i = 0; i < ext_count; i++ ) {
78384
 
+               struct sieve_binary_extension_reg * const *ereg
78385
 
+                       = array_idx(&sbin->extensions, i);
78386
 
+               const struct sieve_binary_extension *binext = (*ereg)->binext;
78387
 
+               
78388
 
+               if ( binext != NULL && binext->binary_free != NULL )
78389
 
+                       binext->binary_free(sbin);
78390
 
+       }
78391
 
+}
78392
 
+
78393
 
+void sieve_binary_unref(struct sieve_binary **sbin) 
78394
 
+{
78395
 
+       i_assert((*sbin)->refcount > 0);
78396
 
+
78397
 
+       if (--(*sbin)->refcount != 0)
78398
 
+               return;
78399
 
+
78400
 
+       sieve_binary_extensions_free(*sbin);
78401
 
+       
78402
 
+       if ( (*sbin)->file != NULL )
78403
 
+               sieve_binary_file_close(&(*sbin)->file);
78404
 
+
78405
 
+       if ( (*sbin)->script != NULL )
78406
 
+               sieve_script_unref(&(*sbin)->script);
78407
 
+       
78408
 
+       pool_unref(&((*sbin)->pool));
78409
 
+       
78410
 
+       *sbin = NULL;
78411
 
+}
78412
 
+
78413
 
+static inline sieve_size_t _sieve_binary_get_code_size
78414
 
+(struct sieve_binary *sbin)
78415
 
+{
78416
 
+       return buffer_get_used_size(sbin->data);
78417
 
+}
78418
 
+
78419
 
+sieve_size_t sieve_binary_get_code_size(struct sieve_binary *sbin)
78420
 
+{
78421
 
+       return _sieve_binary_get_code_size(sbin);
78422
 
+}
78423
 
+
78424
 
+pool_t sieve_binary_pool(struct sieve_binary *sbin)
78425
 
+{
78426
 
+       return sbin->pool;
78427
 
+}
78428
 
+
78429
 
+struct sieve_script *sieve_binary_script(struct sieve_binary *sbin)
78430
 
+{
78431
 
+       return sbin->script;
78432
 
+}
78433
 
+
78434
 
+const char *sieve_binary_path(struct sieve_binary *sbin)
78435
 
+{
78436
 
+       return sbin->path;
78437
 
+}
78438
 
+
78439
 
+bool sieve_binary_script_older
78440
 
+(struct sieve_binary *sbin, struct sieve_script *script)
78441
 
+{
78442
 
+       i_assert(sbin->file != NULL);
78443
 
+       return ( sieve_script_older(script, sbin->file->st.st_mtime) );
78444
 
+}
78445
 
+
78446
 
+const char *sieve_binary_script_name(struct sieve_binary *sbin)
78447
 
+{
78448
 
+       struct sieve_script *script = sieve_binary_script(sbin);
78449
 
+
78450
 
+       return ( script == NULL ? NULL : sieve_script_name(script) );
78451
 
+}
78452
 
+
78453
 
+const char *sieve_binary_script_path(struct sieve_binary *sbin)
78454
 
+{
78455
 
+       struct sieve_script *script = sieve_binary_script(sbin);
78456
 
+
78457
 
+       return ( script == NULL ? NULL : sieve_script_path(script) );
78458
 
+}
78459
 
+
78460
 
+
78461
 
+/* 
78462
 
+ * Block management 
78463
 
+ */
78464
 
+
78465
 
+static inline struct sieve_binary_block *sieve_binary_block_get
78466
 
+(struct sieve_binary *sbin, unsigned int id) 
78467
 
+{
78468
 
+       struct sieve_binary_block * const *block;
78469
 
+
78470
 
+       if  ( id >= array_count(&sbin->blocks) )
78471
 
+               return NULL;
78472
 
+       
78473
 
+       block = array_idx(&sbin->blocks, id);           
78474
 
+
78475
 
+       return *block;
78476
 
+}
78477
 
+
78478
 
+static inline unsigned int sieve_binary_block_add
78479
 
+(struct sieve_binary *sbin, struct sieve_binary_block *block)
78480
 
+{
78481
 
+       unsigned int id = array_count(&sbin->blocks);
78482
 
+       
78483
 
+       array_append(&sbin->blocks, &block, 1); 
78484
 
+       return id;
78485
 
+}
78486
 
+
78487
 
+static inline unsigned int sieve_binary_block_count
78488
 
+(struct sieve_binary *sbin)
78489
 
+{
78490
 
+       return array_count(&sbin->blocks);
78491
 
+}
78492
 
+
78493
 
+void sieve_binary_block_clear
78494
 
+(struct sieve_binary *sbin, unsigned int id)
78495
 
+{
78496
 
+       struct sieve_binary_block *block = sieve_binary_block_get(sbin, id);
78497
 
+       
78498
 
+       buffer_reset(block->buffer);
78499
 
+}
78500
 
+
78501
 
+bool sieve_binary_block_set_active
78502
 
+(struct sieve_binary *sbin, unsigned int id, unsigned *old_id_r)
78503
 
+{
78504
 
+       struct sieve_binary_block *block = sieve_binary_block_get(sbin, id);
78505
 
+                       
78506
 
+       if ( block == NULL ) return FALSE;
78507
 
+       
78508
 
+       if ( block->buffer == NULL ) {
78509
 
+               if ( sbin->file ) {
78510
 
+                       /* Try to acces the block in the binary on disk (apperently we were lazy)
78511
 
+                        */
78512
 
+                       if ( sieve_binary_load_block(sbin, id) == NULL || block->buffer == NULL )
78513
 
+                               return FALSE;
78514
 
+               } else {
78515
 
+                       /* Block buffer is missing during code generation. This is what we would 
78516
 
+                        * call a bug. FAIL. 
78517
 
+                        */
78518
 
+                       return FALSE;
78519
 
+               }
78520
 
+       }
78521
 
+       
78522
 
+       if ( old_id_r != NULL ) 
78523
 
+               *old_id_r = sbin->active_block;
78524
 
+
78525
 
+       sbin->data = block->buffer;
78526
 
+       sbin->code = buffer_get_data(block->buffer, &sbin->code_size);
78527
 
+       sbin->active_block = id;
78528
 
+       
78529
 
+       return TRUE;
78530
 
+}
78531
 
+
78532
 
+unsigned int sieve_binary_block_create(struct sieve_binary *sbin)
78533
 
+{
78534
 
+       struct sieve_binary_block *block;
78535
 
+       
78536
 
+       block = p_new(sbin->pool, struct sieve_binary_block, 1);
78537
 
+       block->buffer = buffer_create_dynamic(sbin->pool, 64);
78538
 
+
78539
 
+       return sieve_binary_block_add(sbin, block);
78540
 
+}
78541
 
+
78542
 
+static struct sieve_binary_block *sieve_binary_block_create_id
78543
 
+(struct sieve_binary *sbin, unsigned int id)
78544
 
+{
78545
 
+       struct sieve_binary_block *block;
78546
 
+       
78547
 
+       block = p_new(sbin->pool, struct sieve_binary_block, 1);
78548
 
+
78549
 
+       if ( id >= SBIN_SYSBLOCK_LAST )
78550
 
+               array_idx_set(&sbin->blocks, id, &block);               
78551
 
+       else
78552
 
+               (void)sieve_binary_block_add(sbin, block);
78553
 
+       
78554
 
+       return block;
78555
 
+}
78556
 
+
78557
 
+/*
78558
 
+ * Header and record structures of the binary on disk 
78559
 
+ */
78560
 
78561
 
+struct sieve_binary_header {
78562
 
+       uint32_t magic;
78563
 
+       uint16_t version_major;
78564
 
+       uint16_t version_minor;
78565
 
+       uint32_t blocks;
78566
 
+};
78567
 
+
78568
 
+struct sieve_binary_block_index {
78569
 
+       uint32_t id;
78570
 
+       uint32_t size;
78571
 
+       uint32_t offset;
78572
 
+       uint32_t ext_id;
78573
 
+};
78574
 
+
78575
 
+struct sieve_binary_block_header {
78576
 
+       uint32_t id; 
78577
 
+       uint32_t size;
78578
 
+};
78579
 
+
78580
 
+/* 
78581
 
+ * Saving the binary to a file. 
78582
 
+ */
78583
 
+
78584
 
+static inline bool _save_skip(struct ostream *stream, size_t size)
78585
 
+{      
78586
 
+       if ( (o_stream_seek(stream, stream->offset + size)) <= 0 ) 
78587
 
+               return FALSE;
78588
 
+               
78589
 
+       return TRUE;
78590
 
+}
78591
 
+
78592
 
+static inline bool _save_skip_aligned
78593
 
+(struct ostream *stream, size_t size, uoff_t *offset)
78594
 
+{
78595
 
+       uoff_t aligned_offset = SIEVE_BINARY_ALIGN(stream->offset);
78596
 
+       
78597
 
+       if ( (o_stream_seek(stream, aligned_offset + size)) <= 0 ) 
78598
 
+               return FALSE;
78599
 
+               
78600
 
+       if ( offset != NULL )
78601
 
+               *offset = aligned_offset;
78602
 
+               
78603
 
+       return TRUE;
78604
 
+}
78605
 
+
78606
 
+/* FIXME: Is this even necessary for a file? */
78607
 
+static bool _save_full(struct ostream *stream, const void *data, size_t size)
78608
 
+{
78609
 
+       size_t bytes_left = size;
78610
 
+       const void *pdata = data;
78611
 
+       
78612
 
+       while ( bytes_left > 0 ) {
78613
 
+               ssize_t ret;
78614
 
+               
78615
 
+               if ( (ret=o_stream_send(stream, pdata, bytes_left)) <= 0 ) 
78616
 
+                       return FALSE;
78617
 
+                       
78618
 
+               pdata = PTR_OFFSET(pdata, ret);
78619
 
+               bytes_left -= ret;
78620
 
+       }       
78621
 
+       
78622
 
+       return TRUE;
78623
 
+}
78624
 
+
78625
 
+static bool _save_aligned
78626
 
+(struct ostream *stream, const void *data, size_t size, uoff_t *offset)
78627
 
+{      
78628
 
+       uoff_t aligned_offset = SIEVE_BINARY_ALIGN(stream->offset);
78629
 
+
78630
 
+       o_stream_cork(stream);
78631
 
+       
78632
 
+       /* Align the data by adding zeroes to the output stream */
78633
 
+       if ( stream->offset < aligned_offset ) {
78634
 
+               if ( !_save_skip(stream, aligned_offset - stream->offset) ) 
78635
 
+                       return FALSE;
78636
 
+       }
78637
 
+       
78638
 
+       if ( !_save_full(stream, data, size) )
78639
 
+               return FALSE;
78640
 
+       
78641
 
+       o_stream_uncork(stream); 
78642
 
+
78643
 
+       if ( offset != NULL )
78644
 
+               *offset = aligned_offset;
78645
 
+
78646
 
+       return TRUE;
78647
 
+} 
78648
 
+
78649
 
+static bool _save_block
78650
 
+(struct sieve_binary *sbin, struct ostream *stream, unsigned int id)
78651
 
+{
78652
 
+       struct sieve_binary_block_header block_header;
78653
 
+       struct sieve_binary_block *block;
78654
 
+       const void *data;
78655
 
+       size_t size;
78656
 
+               
78657
 
+       block = sieve_binary_block_get(sbin, id);
78658
 
+       if ( block == NULL )
78659
 
+               return FALSE;
78660
 
+               
78661
 
+       data = buffer_get_data(block->buffer, &size);
78662
 
+       
78663
 
+       block_header.id = id;
78664
 
+       block_header.size = size;
78665
 
+       
78666
 
+       if ( !_save_aligned(stream, &block_header,
78667
 
+               sizeof(block_header), &block->offset) )
78668
 
+               return FALSE;
78669
 
+       
78670
 
+       return _save_aligned(stream, data, size, NULL);
78671
 
+}
78672
 
+
78673
 
+static bool _save_block_index_record
78674
 
+(struct sieve_binary *sbin, struct ostream *stream, unsigned int id)
78675
 
+{
78676
 
+       struct sieve_binary_block *block;
78677
 
+       struct sieve_binary_block_index header;
78678
 
+       
78679
 
+       block = sieve_binary_block_get(sbin, id);
78680
 
+       if ( block == NULL )
78681
 
+               return FALSE;
78682
 
+       
78683
 
+       header.id = id;
78684
 
+       header.size = buffer_get_used_size(block->buffer);
78685
 
+       header.ext_id = block->ext_index;
78686
 
+       header.offset = block->offset;
78687
 
+       
78688
 
+       if ( !_save_full(stream, &header, sizeof(header)) ) {
78689
 
+               sieve_sys_error("failed to save block index header %d: %m", id);
78690
 
+               
78691
 
+               return FALSE;
78692
 
+       }
78693
 
+       
78694
 
+       return TRUE;
78695
 
+}
78696
 
+
78697
 
+static bool _sieve_binary_save
78698
 
+(struct sieve_binary *sbin, struct ostream *stream)
78699
 
+{
78700
 
+       struct sieve_binary_header header;
78701
 
+       unsigned int ext_count, blk_count, i;
78702
 
+       uoff_t block_index;
78703
 
+       
78704
 
+       blk_count = sieve_binary_block_count(sbin);
78705
 
+       
78706
 
+       /* Signal all extensions to finish generating their blocks */
78707
 
+       
78708
 
+       ext_count = array_count(&sbin->extensions);     
78709
 
+       for ( i = 0; i < ext_count; i++ ) {
78710
 
+               struct sieve_binary_extension_reg * const *ereg
78711
 
+                       = array_idx(&sbin->extensions, i);
78712
 
+               const struct sieve_binary_extension *binext = (*ereg)->binext;
78713
 
+               
78714
 
+               if ( binext != NULL && binext->binary_save != NULL )
78715
 
+                       binext->binary_save(sbin);
78716
 
+       }
78717
 
+               
78718
 
+       /* Create header */
78719
 
+       
78720
 
+       header.magic = SIEVE_BINARY_MAGIC;
78721
 
+       header.version_major = SIEVE_BINARY_VERSION_MAJOR;
78722
 
+       header.version_minor = SIEVE_BINARY_VERSION_MINOR;
78723
 
+       header.blocks = blk_count;
78724
 
+
78725
 
+       if ( !_save_aligned(stream, &header, sizeof(header), NULL) ) {
78726
 
+               sieve_sys_error("failed to save binary header: %m");
78727
 
+               return FALSE;
78728
 
+       } 
78729
 
+       
78730
 
+       /* Skip block index for now */
78731
 
+       
78732
 
+       if ( !_save_skip_aligned(stream, 
78733
 
+               sizeof(struct sieve_binary_block_index) * blk_count, &block_index) )
78734
 
+               return FALSE;
78735
 
+       
78736
 
+       /* Create block containing all used extensions 
78737
 
+        *   FIXME: Per-extension this should also store binary version numbers.
78738
 
+        */
78739
 
+       if ( !sieve_binary_block_set_active(sbin, SBIN_SYSBLOCK_EXTENSIONS, NULL) )
78740
 
+               return FALSE;
78741
 
+               
78742
 
+       ext_count = array_count(&sbin->linked_extensions);
78743
 
+       sieve_binary_emit_unsigned(sbin, ext_count);
78744
 
+       
78745
 
+       for ( i = 0; i < ext_count; i++ ) {
78746
 
+               struct sieve_binary_extension_reg * const *ext
78747
 
+                       = array_idx(&sbin->linked_extensions, i);
78748
 
+               
78749
 
+               sieve_binary_emit_cstring(sbin, (*ext)->extension->name);
78750
 
+               sieve_binary_emit_unsigned(sbin, (*ext)->block_id);
78751
 
+       }
78752
 
+       
78753
 
+       if ( !sieve_binary_block_set_active(sbin, SBIN_SYSBLOCK_MAIN_PROGRAM, NULL) )
78754
 
+               return FALSE;
78755
 
+       
78756
 
+       /* Save all blocks into the binary */
78757
 
+       
78758
 
+       for ( i = 0; i < blk_count; i++ ) {
78759
 
+               if ( !_save_block(sbin, stream, i) ) 
78760
 
+                       return FALSE;
78761
 
+       }
78762
 
+       
78763
 
+       /* Create the block index */
78764
 
+       o_stream_seek(stream, block_index);
78765
 
+       for ( i = 0; i < blk_count; i++ ) {
78766
 
+               if ( !_save_block_index_record(sbin, stream, i) ) 
78767
 
+                       return FALSE;
78768
 
+       }
78769
 
+
78770
 
+       return TRUE;
78771
 
+} 
78772
 
+
78773
 
+bool sieve_binary_save
78774
 
+(struct sieve_binary *sbin, const char *path)
78775
 
+{
78776
 
+       bool result = TRUE;
78777
 
+       const char *temp_path;
78778
 
+       struct ostream *stream;
78779
 
+       int fd;
78780
 
+       mode_t save_mode = sbin->script == NULL ? 0600 : sieve_script_permissions(sbin->script);
78781
 
+       
78782
 
+       /* Use default path if none is specified */
78783
 
+       if ( path == NULL ) {
78784
 
+               if ( sbin->script == NULL ) {
78785
 
+                       sieve_sys_error("cannot determine default binary save path "
78786
 
+                               "with missing script object");
78787
 
+               return FALSE;
78788
 
+               }
78789
 
+               path = sieve_script_binpath(sbin->script);
78790
 
+       }
78791
 
+
78792
 
+       /* Open it as temp file first, as not to overwrite an existing just yet */
78793
 
+       temp_path = t_strconcat(path, ".tmp", NULL);
78794
 
+       fd = open(temp_path, O_CREAT | O_TRUNC | O_WRONLY, save_mode);
78795
 
+       if ( fd < 0 ) {
78796
 
+               if ( errno == EACCES ) {
78797
 
+                       sieve_sys_error("failed to save binary: %s",
78798
 
+                               eacces_error_get_creating("open", temp_path));
78799
 
+               } else {
78800
 
+                       sieve_sys_error("failed to save binary: open(%s) failed: %m", 
78801
 
+                               temp_path);
78802
 
+               }
78803
 
+               return FALSE;
78804
 
+       }
78805
 
+
78806
 
+       stream = o_stream_create_fd(fd, 0, FALSE);
78807
 
+       result = _sieve_binary_save(sbin, stream);
78808
 
+       o_stream_destroy(&stream);
78809
 
78810
 
+       if (close(fd) < 0)
78811
 
+               sieve_sys_error("failed to close saved binary temporary file: "
78812
 
+                       "close(fd=%s) failed: %m", temp_path);
78813
 
+
78814
 
+       /* Replace any original binary atomically */
78815
 
+       if (result && (rename(temp_path, path) < 0)) {
78816
 
+               if ( errno == EACCES ) {
78817
 
+                       sieve_sys_error("failed to replace existing binary: %s", 
78818
 
+                               eacces_error_get_creating("rename", path));                     
78819
 
+               } else {                
78820
 
+                       sieve_sys_error("failed to replace existing binary: "
78821
 
+                               "rename(%s, %s) failed: %m", temp_path, path);
78822
 
+               }
78823
 
+               result = FALSE;
78824
 
+       }
78825
 
+
78826
 
+       if ( !result ) {
78827
 
+               /* Get rid of temp output (if any) */
78828
 
+               (void) unlink(temp_path);
78829
 
+       } else {
78830
 
+               if ( sbin->path == NULL || strcmp(sbin->path, path) != 0 ) {
78831
 
+                       sbin->path = p_strdup(sbin->pool, path);
78832
 
+               }
78833
 
+       }
78834
 
+       
78835
 
+       return result;
78836
 
+}
78837
 
+
78838
 
+/* 
78839
 
+ * Binary file management 
78840
 
+ */
78841
 
+
78842
 
+static bool sieve_binary_file_open
78843
 
+       (struct sieve_binary_file *file, const char *path)
78844
 
+{
78845
 
+       int fd;
78846
 
+       struct stat st;
78847
 
+       
78848
 
+       if ( (fd=open(path, O_RDONLY)) < 0 ) {
78849
 
+               if ( errno != ENOENT ) {
78850
 
+                       if ( errno == EACCES ) {
78851
 
+                               sieve_sys_error("failed to open binary: %s", 
78852
 
+                                       eacces_error_get("open", path));                        
78853
 
+                       } else {
78854
 
+                               sieve_sys_error("failed to open binary: "
78855
 
+                                       "open(%s) failed: %m", path);
78856
 
+                       }
78857
 
+               }
78858
 
+               return FALSE;
78859
 
+       }
78860
 
+
78861
 
+       if ( fstat(fd, &st) < 0 ) {
78862
 
+               if ( errno != ENOENT ) {
78863
 
+                       sieve_sys_error("failed to open binary: "
78864
 
+                               "fstat(fd=%s) failed: %m", path);
78865
 
+               }
78866
 
+               return FALSE;
78867
 
+       }
78868
 
+
78869
 
+       if ( !S_ISREG(st.st_mode) ) {
78870
 
+               sieve_sys_error("binary %s is not a regular file", path);
78871
 
+               return FALSE;           
78872
 
+       }
78873
 
+       
78874
 
+       file->fd = fd;
78875
 
+       file->st = st;
78876
 
+
78877
 
+       return TRUE;
78878
 
+}
78879
 
+       
78880
 
+static void sieve_binary_file_close(struct sieve_binary_file **file)
78881
 
+{
78882
 
+       if ( (*file)->fd != -1 ) {
78883
 
+               if ( close((*file)->fd) < 0 ) {
78884
 
+                       sieve_sys_error("failed to close opened binary: "
78885
 
+                               "close(fd=%s) failed: %m", (*file)->path);
78886
 
+               }
78887
 
+       }
78888
 
+
78889
 
+       pool_unref(&(*file)->pool);
78890
 
+       
78891
 
+       *file = NULL;
78892
 
+}
78893
 
+
78894
 
+#if 0 /* file_memory is currently unused */
78895
 
+
78896
 
+/* File loaded/mapped to memory */
78897
 
+
78898
 
+struct _file_memory {
78899
 
+       struct sieve_binary_file binfile;
78900
 
+
78901
 
+       /* Pointer to the binary in memory */
78902
 
+       const void *memory;
78903
 
+       off_t memory_size;
78904
 
+};
78905
 
+
78906
 
+static const void *_file_memory_load_data
78907
 
+       (struct sieve_binary_file *file, off_t *offset, size_t size)
78908
 
+{      
78909
 
+       struct _file_memory *fmem = (struct _file_memory *) file;
78910
 
+
78911
 
+       *offset = SIEVE_BINARY_ALIGN(*offset);
78912
 
+
78913
 
+       if ( (*offset) + size <= fmem->memory_size ) {
78914
 
+               const void *data = PTR_OFFSET(fmem->memory, *offset);
78915
 
+               *offset += size;
78916
 
+               file->offset = *offset;
78917
 
+               
78918
 
+               return data;
78919
 
+       }
78920
 
+               
78921
 
+       return NULL;
78922
 
+}
78923
 
+
78924
 
+static buffer_t *_file_memory_load_buffer
78925
 
+       (struct sieve_binary_file *file, off_t *offset, size_t size)
78926
 
+{      
78927
 
+       struct _file_memory *fmem = (struct _file_memory *) file;
78928
 
+
78929
 
+       *offset = SIEVE_BINARY_ALIGN(*offset);
78930
 
+
78931
 
+       if ( (*offset) + size <= fmem->memory_size ) {
78932
 
+               const void *data = PTR_OFFSET(fmem->memory, *offset);
78933
 
+               *offset += size;
78934
 
+               file->offset = *offset;
78935
 
+               
78936
 
+               return buffer_create_const_data(file->pool, data, size);
78937
 
+       }
78938
 
+       
78939
 
+       return NULL;
78940
 
+}
78941
 
+
78942
 
+static bool _file_memory_load(struct sieve_binary_file *file)
78943
 
+{
78944
 
+       struct _file_memory *fmem = (struct _file_memory *) file;
78945
 
+       int ret;
78946
 
+       size_t size;
78947
 
+       void *indata;
78948
 
+               
78949
 
+       i_assert(file->fd > 0);
78950
 
+               
78951
 
+       /* Allocate memory buffer
78952
 
+        */
78953
 
+       indata = p_malloc(file->pool, file->st.st_size);
78954
 
+       size = file->st.st_size; 
78955
 
+       
78956
 
+       file->offset = 0; 
78957
 
+       fmem->memory = indata;
78958
 
+       fmem->memory_size = file->st.st_size;
78959
 
+
78960
 
+       /* Return to beginning of the file */
78961
 
+       if ( lseek(file->fd, 0, SEEK_SET) == (off_t) -1 ) {
78962
 
+               sieve_sys_error("failed to seek() in binary %s: %m", file->path);
78963
 
+               return FALSE;
78964
 
+       }       
78965
 
+
78966
 
+       /* Read the whole file into memory */
78967
 
+       while (size > 0) {
78968
 
+               if ( (ret=read(file->fd, indata, size)) <= 0 ) {
78969
 
+                       sieve_sys_error("failed to read from binary %s: %m", file->path);
78970
 
+                       break;
78971
 
+               }
78972
 
+               
78973
 
+               indata = PTR_OFFSET(indata, ret);
78974
 
+               size -= ret;
78975
 
+       }       
78976
 
+
78977
 
+       if ( size != 0 ) {
78978
 
+               /* Failed to read the whole file */
78979
 
+               return FALSE;
78980
 
+       }
78981
 
+       
78982
 
+       return TRUE;
78983
 
+}
78984
 
+
78985
 
+static struct sieve_binary_file *_file_memory_open(const char *path)
78986
 
+{
78987
 
+       pool_t pool;
78988
 
+       struct _file_memory *file;
78989
 
+       
78990
 
+       pool = pool_alloconly_create("sieve_binary_file_memory", 1024);
78991
 
+       file = p_new(pool, struct _file_memory, 1);
78992
 
+       file->binfile.pool = pool;
78993
 
+       file->binfile.path = p_strdup(pool, path);
78994
 
+       file->binfile.load = _file_memory_load;
78995
 
+       file->binfile.load_data = _file_memory_load_data;
78996
 
+       file->binfile.load_buffer = _file_memory_load_buffer;
78997
 
+       
78998
 
+       if ( !sieve_binary_file_open(&file->binfile, path) ) {
78999
 
+               pool_unref(&pool);
79000
 
+               return NULL;
79001
 
+       }
79002
 
+
79003
 
+       return &file->binfile;
79004
 
+}
79005
 
+
79006
 
+#endif /* file_memory is currently unused */
79007
 
+
79008
 
+/* File open in lazy mode (only read what is needed into memory) */
79009
 
+
79010
 
+static bool _file_lazy_read
79011
 
+(struct sieve_binary_file *file, off_t *offset, void *buffer, size_t size)
79012
 
+{
79013
 
+       int ret;
79014
 
+       void *indata = buffer;
79015
 
+       size_t insize = size;
79016
 
+       
79017
 
+       *offset = SIEVE_BINARY_ALIGN(*offset);
79018
 
+       
79019
 
+       /* Seek to the correct position */ 
79020
 
+       if ( *offset != file->offset && 
79021
 
+               lseek(file->fd, *offset, SEEK_SET) == (off_t) -1 ) {
79022
 
+               sieve_sys_error("failed to seek(fd, %lld, SEEK_SET) in binary %s: %m", 
79023
 
+                       (long long) *offset, file->path);
79024
 
+               return FALSE;
79025
 
+       }       
79026
 
+
79027
 
+       /* Read record into memory */
79028
 
+       while (insize > 0) {
79029
 
+               if ( (ret=read(file->fd, indata, insize)) <= 0 ) {
79030
 
+                       if ( ret == 0 ) 
79031
 
+                               sieve_sys_error("binary %s is truncated (more data expected)", 
79032
 
+                                       file->path);
79033
 
+                       else
79034
 
+                               sieve_sys_error("failed to read from binary %s: %m", file->path);
79035
 
+                       break;
79036
 
+               }
79037
 
+               
79038
 
+               indata = PTR_OFFSET(indata, ret);
79039
 
+               insize -= ret;
79040
 
+       }       
79041
 
+
79042
 
+       if ( insize != 0 ) {
79043
 
+               /* Failed to read the whole requested record */
79044
 
+               return FALSE;
79045
 
+       }
79046
 
+       
79047
 
+       *offset += size;
79048
 
+       file->offset = *offset;
79049
 
+
79050
 
+       return TRUE;
79051
 
+}
79052
 
+
79053
 
+static const void *_file_lazy_load_data
79054
 
+(struct sieve_binary_file *file, off_t *offset, size_t size)
79055
 
+{      
79056
 
+       void *data = t_malloc(size);
79057
 
+
79058
 
+       if ( _file_lazy_read(file, offset, data, size) ) {
79059
 
+               return data;
79060
 
+       }
79061
 
+       
79062
 
+       return NULL;
79063
 
+}
79064
 
+
79065
 
+static buffer_t *_file_lazy_load_buffer
79066
 
+(struct sieve_binary_file *file, off_t *offset, size_t size)
79067
 
+{                      
79068
 
+       buffer_t *buffer = buffer_create_static_hard(file->pool, size);
79069
 
+       
79070
 
+       if ( _file_lazy_read
79071
 
+               (file, offset, buffer_get_space_unsafe(buffer, 0, size), size) ) {
79072
 
+               return buffer;
79073
 
+       }
79074
 
+       
79075
 
+       return NULL;
79076
 
+}
79077
 
+
79078
 
+static struct sieve_binary_file *_file_lazy_open(const char *path)
79079
 
+{
79080
 
+       pool_t pool;
79081
 
+       struct sieve_binary_file *file;
79082
 
+       
79083
 
+       pool = pool_alloconly_create("sieve_binary_file_lazy", 4096);
79084
 
+       file = p_new(pool, struct sieve_binary_file, 1);
79085
 
+       file->pool = pool;
79086
 
+       file->path = p_strdup(pool, path);
79087
 
+       file->load_data = _file_lazy_load_data;
79088
 
+       file->load_buffer = _file_lazy_load_buffer;
79089
 
+       
79090
 
+       if ( !sieve_binary_file_open(file, path) ) {
79091
 
+               pool_unref(&pool);
79092
 
+               return NULL;
79093
 
+       }
79094
 
+
79095
 
+       return file;
79096
 
+}
79097
 
+
79098
 
+/* 
79099
 
+ * Load binary from a file
79100
 
+ */
79101
 
+
79102
 
+#define LOAD_HEADER(sbin, offset, header) \
79103
 
+       (header *) sbin->file->load_data(sbin->file, offset, sizeof(header))
79104
 
+
79105
 
+static struct sieve_binary_block *_load_block
79106
 
+(struct sieve_binary *sbin, off_t *offset, unsigned int id)
79107
 
+{
79108
 
+       const struct sieve_binary_block_header *header = 
79109
 
+               LOAD_HEADER(sbin, offset, const struct sieve_binary_block_header);
79110
 
+       struct sieve_binary_block *block;
79111
 
+               
79112
 
+       if ( header == NULL ) {
79113
 
+               sieve_sys_error("block %d of loaded binary %s is truncated", id, sbin->path);
79114
 
+               return NULL;
79115
 
+       }
79116
 
+       
79117
 
+       if ( header->id != id ) {
79118
 
+               sieve_sys_error("block %d of loaded binary %s has unexpected id %d", id, 
79119
 
+                       sbin->path, header->id);
79120
 
+               return NULL;
79121
 
+       }
79122
 
+       
79123
 
+       block = sieve_binary_block_get(sbin, id);
79124
 
+       
79125
 
+       if ( block == NULL ) {
79126
 
+               sieve_sys_error("!!BUG!!: block %d missing in index (impossible) "
79127
 
+                       "of binary %s", id, sbin->path);
79128
 
+               return NULL;
79129
 
+       }
79130
 
+       
79131
 
+       block->buffer = sbin->file->load_buffer(sbin->file, offset, header->size);
79132
 
+       if ( block->buffer == NULL ) {
79133
 
+               sieve_sys_error("block %d of loaded binary %s has invalid size %d",
79134
 
+                       id, sbin->path, header->size);
79135
 
+               return NULL;
79136
 
+       }
79137
 
+               
79138
 
+       return block;
79139
 
+}
79140
 
+
79141
 
+static struct sieve_binary_block *sieve_binary_load_block
79142
 
+(struct sieve_binary *sbin, unsigned int id)
79143
 
+{
79144
 
+       struct sieve_binary_block *block;
79145
 
+       off_t offset;
79146
 
+       
79147
 
+       block = sieve_binary_block_get(sbin, id);
79148
 
+       
79149
 
+       if ( block == NULL ) return NULL;
79150
 
+       
79151
 
+       offset = block->offset;
79152
 
+       
79153
 
+       return _load_block(sbin, &offset, id);
79154
 
+}
79155
 
+
79156
 
+static bool _load_block_index_record
79157
 
+(struct sieve_binary *sbin, off_t *offset, unsigned int id)
79158
 
+{
79159
 
+       const struct sieve_binary_block_index *record = 
79160
 
+               LOAD_HEADER(sbin, offset, const struct sieve_binary_block_index);
79161
 
+       struct sieve_binary_block *block;
79162
 
+       
79163
 
+       if ( record == NULL ) {
79164
 
+               sieve_sys_error("failed to read index record for block %d in binary %s", 
79165
 
+                       id, sbin->path);
79166
 
+               return FALSE;
79167
 
+       }
79168
 
+       
79169
 
+       if ( record->id != id ) {
79170
 
+               sieve_sys_error("block index record %d of loaded binary %s "
79171
 
+                       "has unexpected id %d", id, sbin->path, record->id);
79172
 
+               return FALSE;
79173
 
+       }
79174
 
+       
79175
 
+       block = sieve_binary_block_create_id(sbin, id);
79176
 
+       block->ext_index = record->ext_id;
79177
 
+       block->offset = record->offset;
79178
 
+       
79179
 
+       return TRUE;
79180
 
+}
79181
 
+
79182
 
+static bool _sieve_binary_load_extensions(struct sieve_binary *sbin)
79183
 
+{
79184
 
+       sieve_size_t offset = 0;
79185
 
+       unsigned int i, count;
79186
 
+       bool result = TRUE;
79187
 
+       
79188
 
+       if ( !sieve_binary_block_set_active(sbin, SBIN_SYSBLOCK_EXTENSIONS, NULL) ) 
79189
 
+               return FALSE;
79190
 
+
79191
 
+       if ( !sieve_binary_read_unsigned(sbin, &offset, &count) )
79192
 
+               return FALSE;
79193
 
+       
79194
 
+       for ( i = 0; result && i < count; i++ ) {
79195
 
+               T_BEGIN {
79196
 
+                       string_t *extension;
79197
 
+                       const struct sieve_extension *ext;
79198
 
+                       
79199
 
+                       if ( sieve_binary_read_string(sbin, &offset, &extension) ) { 
79200
 
+                               ext = sieve_extension_get_by_name(str_c(extension));    
79201
 
+                       
79202
 
+                               if ( ext == NULL ) { 
79203
 
+                                       sieve_sys_error("loaded binary %s requires unknown extension '%s'", 
79204
 
+                                               sbin->path, str_sanitize(str_c(extension), 128));
79205
 
+                                       result = FALSE;                                 
79206
 
+                               } else {
79207
 
+                                       struct sieve_binary_extension_reg *ereg = NULL;
79208
 
+                                       
79209
 
+                                       (void) sieve_binary_extension_register(sbin, ext, &ereg);
79210
 
+                                       if ( !sieve_binary_read_unsigned(sbin, &offset, &ereg->block_id) )
79211
 
+                                               result = FALSE;
79212
 
+                               }
79213
 
+                       }       else
79214
 
+                               result = FALSE;
79215
 
+               } T_END;
79216
 
+       }               
79217
 
+               
79218
 
+       return result;
79219
 
+}
79220
 
+
79221
 
+static bool _sieve_binary_open(struct sieve_binary *sbin)
79222
 
+{
79223
 
+       bool result = TRUE;
79224
 
+       off_t offset = 0;
79225
 
+       const struct sieve_binary_header *header;
79226
 
+       struct sieve_binary_block *extensions;
79227
 
+       unsigned int i, blk_count;
79228
 
+       
79229
 
+       /* Verify header */
79230
 
+       
79231
 
+       T_BEGIN {
79232
 
+               header = LOAD_HEADER(sbin, &offset, const struct sieve_binary_header);
79233
 
+               if ( header == NULL ) {
79234
 
+                       sieve_sys_error("opened binary %s is not even large enough "
79235
 
+                               "to contain a header.", sbin->path);
79236
 
+                       result = FALSE;
79237
 
+
79238
 
+               } else if ( header->magic != SIEVE_BINARY_MAGIC ) {
79239
 
+                       if ( header->magic != SIEVE_BINARY_MAGIC_OTHER_ENDIAN ) 
79240
 
+                               sieve_sys_error("opened binary %s has corrupted header (0x%08x)", 
79241
 
+                                       sbin->path, header->magic);
79242
 
+                       result = FALSE;
79243
 
+
79244
 
+               } else if ( result && (
79245
 
+                 header->version_major != SIEVE_BINARY_VERSION_MAJOR || 
79246
 
+                       header->version_minor != SIEVE_BINARY_VERSION_MINOR ) ) {
79247
 
+
79248
 
+                       /* Binary is of different version. Caller will have to recompile */
79249
 
+                       result = FALSE;
79250
 
+
79251
 
+               } else if ( result && header->blocks == 0 ) {
79252
 
+                       sieve_sys_error("opened binary %s contains no blocks", sbin->path);
79253
 
+                       result = FALSE; 
79254
 
+
79255
 
+               } else {
79256
 
+                       blk_count = header->blocks;
79257
 
+               }
79258
 
+       } T_END;
79259
 
+       
79260
 
+       if ( !result ) return FALSE;
79261
 
+       
79262
 
+       /* Load block index */
79263
 
+       
79264
 
+       for ( i = 0; i < blk_count && result; i++ ) {   
79265
 
+               T_BEGIN {
79266
 
+                       if ( !_load_block_index_record(sbin, &offset, i) ) {
79267
 
+                               sieve_sys_error(
79268
 
+                                       "block index record %d of opened binary %s is corrupt", 
79269
 
+                                       i, sbin->path);
79270
 
+                               result = FALSE;
79271
 
+                       }
79272
 
+               } T_END;
79273
 
+       }
79274
 
+       
79275
 
+       if ( !result ) return FALSE;
79276
 
+       
79277
 
+       /* Load extensions used by this binary */
79278
 
+       
79279
 
+       T_BEGIN {
79280
 
+               extensions =_load_block(sbin, &offset, 0);
79281
 
+               if ( extensions == NULL ) {
79282
 
+                       result = FALSE;
79283
 
+               } else if ( !_sieve_binary_load_extensions(sbin) ) {
79284
 
+                       sieve_sys_error("extension block of opened binary %s is corrupt", 
79285
 
+                               sbin->path);
79286
 
+                       result = FALSE;
79287
 
+               }
79288
 
+       } T_END;
79289
 
+               
79290
 
+       return result;
79291
 
+}
79292
 
+
79293
 
+static bool _sieve_binary_load(struct sieve_binary *sbin) 
79294
 
+{      
79295
 
+       bool result = TRUE;
79296
 
+       unsigned int i, blk_count;
79297
 
+       struct sieve_binary_block *block;
79298
 
+       off_t offset;
79299
 
+       
79300
 
+       blk_count = array_count(&sbin->blocks);
79301
 
+       if ( blk_count == 1 ) {
79302
 
+               /* Binary is empty */
79303
 
+               return TRUE;
79304
 
+       }       
79305
 
+
79306
 
+       block = sieve_binary_block_get(sbin, SBIN_SYSBLOCK_MAIN_PROGRAM);
79307
 
+       offset = block->offset;
79308
 
+       
79309
 
+       /* Load the other blocks */
79310
 
+       
79311
 
+       for ( i = 1; result && i < blk_count; i++ ) {   
79312
 
+               T_BEGIN {
79313
 
+                       if ( _load_block(sbin, &offset, i) == NULL ) {
79314
 
+                               sieve_sys_error("block %d of loaded binary %s is corrupt", 
79315
 
+                                       i, sbin->path);
79316
 
+                               result = FALSE;
79317
 
+                       }
79318
 
+               } T_END;
79319
 
+       }
79320
 
+                               
79321
 
+       return result;
79322
 
+}
79323
 
+
79324
 
+struct sieve_binary *sieve_binary_open
79325
 
+       (const char *path, struct sieve_script *script)
79326
 
+{
79327
 
+       unsigned int ext_count, i;
79328
 
+       struct sieve_binary *sbin;
79329
 
+       struct sieve_binary_file *file;
79330
 
+               
79331
 
+       //file = _file_memory_open(path);       
79332
 
+       file = _file_lazy_open(path);
79333
 
+       if ( file == NULL )
79334
 
+               return NULL;
79335
 
+               
79336
 
+       /* Create binary object */
79337
 
+       sbin = sieve_binary_create(script);
79338
 
+       sbin->path = p_strdup(sbin->pool, path);
79339
 
+       sbin->file = file;
79340
 
+       
79341
 
+       if ( !_sieve_binary_open(sbin) ) {
79342
 
+               sieve_binary_unref(&sbin);
79343
 
+               return NULL;
79344
 
+       }
79345
 
+       
79346
 
+       sieve_binary_activate(sbin);
79347
 
+       
79348
 
+       /* Signal open event to extensions */
79349
 
+       ext_count = array_count(&sbin->extensions);     
79350
 
+       for ( i = 0; i < ext_count; i++ ) {
79351
 
+               struct sieve_binary_extension_reg * const *ereg
79352
 
+                       = array_idx(&sbin->extensions, i);
79353
 
+               const struct sieve_binary_extension *binext = (*ereg)->binext;
79354
 
+               
79355
 
+               if ( binext != NULL && binext->binary_open != NULL && 
79356
 
+                       !binext->binary_open(sbin) ) {
79357
 
+                       /* Extension thinks its corrupt */
79358
 
+                       sieve_binary_unref(&sbin);
79359
 
+                       return NULL;
79360
 
+               }
79361
 
+       }       
79362
 
+
79363
 
+       return sbin;
79364
 
+}
79365
 
+
79366
 
+bool sieve_binary_load(struct sieve_binary *sbin)
79367
 
+{
79368
 
+       i_assert(sbin->file != NULL);
79369
 
+
79370
 
+       /*
79371
 
+       if ( sbin->file->load != NULL && !sbin->file->load(sbin->file) )
79372
 
+               return FALSE;   */              
79373
 
+       
79374
 
+       if ( !_sieve_binary_load(sbin) ) {
79375
 
+               /* Failed to interpret binary header and/or block structure */
79376
 
+               return FALSE;
79377
 
+       }
79378
 
+       
79379
 
+       return TRUE;
79380
 
+}
79381
 
+
79382
 
+/*
79383
 
+ * Up-to-date checking
79384
 
+ */
79385
 
+
79386
 
+bool sieve_binary_up_to_date(struct sieve_binary *sbin)
79387
 
+{
79388
 
+       unsigned int ext_count, i;
79389
 
+       
79390
 
+       i_assert(sbin->file != NULL);
79391
 
+
79392
 
+       if ( sbin->script == NULL || !sieve_script_older
79393
 
+               (sbin->script, sbin->file->st.st_mtime) )
79394
 
+               return FALSE;
79395
 
+       
79396
 
+       ext_count = array_count(&sbin->extensions);     
79397
 
+       for ( i = 0; i < ext_count; i++ ) {
79398
 
+               struct sieve_binary_extension_reg * const *ereg
79399
 
+                       = array_idx(&sbin->extensions, i);
79400
 
+               const struct sieve_binary_extension *binext = (*ereg)->binext;
79401
 
+               
79402
 
+               if ( binext != NULL && binext->binary_up_to_date != NULL && 
79403
 
+                       !binext->binary_up_to_date(sbin) )
79404
 
+                       return FALSE;
79405
 
+       }
79406
 
+       
79407
 
+       return TRUE;
79408
 
+}
79409
 
+
79410
 
+/*
79411
 
+ * Activate the binary (after code generation)
79412
 
+ */
79413
 
79414
 
+void sieve_binary_activate(struct sieve_binary *sbin)
79415
 
+{
79416
 
+       unsigned int i;
79417
 
+       
79418
 
+       (void)sieve_binary_block_set_active(sbin, SBIN_SYSBLOCK_MAIN_PROGRAM, NULL);
79419
 
+       
79420
 
+       /* Load other extensions into binary */
79421
 
+       for ( i = 0; i < array_count(&sbin->linked_extensions); i++ ) {
79422
 
+               struct sieve_binary_extension_reg * const *ereg = 
79423
 
+                       array_idx(&sbin->linked_extensions, i);
79424
 
+               const struct sieve_extension *ext = (*ereg)->extension;
79425
 
+               
79426
 
+               if ( ext != NULL && ext->binary_load != NULL )
79427
 
+                       ext->binary_load(sbin);
79428
 
+       }
79429
 
+}
79430
 
+
79431
 
+/* 
79432
 
+ * Extension handling 
79433
 
+ */
79434
 
+
79435
 
+static inline struct sieve_binary_extension_reg *
79436
 
+       sieve_binary_extension_create_reg
79437
 
+(struct sieve_binary *sbin, const struct sieve_extension *ext)
79438
 
+{
79439
 
+       int ext_id = SIEVE_EXT_ID(ext);
79440
 
+       int index = array_count(&sbin->extensions);
79441
 
+       struct sieve_binary_extension_reg *ereg;
79442
 
+
79443
 
+       if ( ext_id < 0 ) return NULL;
79444
 
+
79445
 
+       ereg = p_new(sbin->pool, struct sieve_binary_extension_reg, 1);
79446
 
+       ereg->index = index;
79447
 
+       ereg->extension = ext;
79448
 
+       
79449
 
+       array_idx_set(&sbin->extensions, (unsigned int) index, &ereg);
79450
 
+       array_idx_set(&sbin->extension_index, (unsigned int) ext_id, &ereg);
79451
 
+       
79452
 
+       return ereg;
79453
 
+}
79454
 
+
79455
 
+static inline struct sieve_binary_extension_reg *sieve_binary_extension_get_reg 
79456
 
+(struct sieve_binary *sbin, const struct sieve_extension *ext, bool create) 
79457
 
+{
79458
 
+       int ext_id = SIEVE_EXT_ID(ext);
79459
 
+       struct sieve_binary_extension_reg *reg = NULL;
79460
 
+
79461
 
+       if ( ext_id >= 0 && ext_id < (int) array_count(&sbin->extension_index) ) {
79462
 
+               struct sieve_binary_extension_reg * const *ereg = 
79463
 
+                       array_idx(&sbin->extension_index, (unsigned int) ext_id);
79464
 
+               
79465
 
+               reg = *ereg;
79466
 
+       }
79467
 
+
79468
 
+       /* Register if not known */
79469
 
+       if ( reg == NULL && create )
79470
 
+               return sieve_binary_extension_create_reg(sbin, ext);
79471
 
+
79472
 
+       return reg;
79473
 
+}
79474
 
+
79475
 
+void sieve_binary_extension_set_context
79476
 
+(struct sieve_binary *sbin, const struct sieve_extension *ext, void *context)
79477
 
+{
79478
 
+       struct sieve_binary_extension_reg *ereg = 
79479
 
+               sieve_binary_extension_get_reg(sbin, ext, TRUE);
79480
 
+       
79481
 
+       if ( ereg != NULL )
79482
 
+               ereg->context = context;
79483
 
+}
79484
 
+
79485
 
+const void *sieve_binary_extension_get_context
79486
 
+       (struct sieve_binary *sbin, const struct sieve_extension *ext) 
79487
 
+{
79488
 
+       struct sieve_binary_extension_reg *ereg = 
79489
 
+               sieve_binary_extension_get_reg(sbin, ext, TRUE);
79490
 
+
79491
 
+       if ( ereg != NULL ) {
79492
 
+               return ereg->context;
79493
 
+       }
79494
 
+               
79495
 
+       return NULL;
79496
 
+}
79497
 
+
79498
 
+void sieve_binary_extension_set
79499
 
+(struct sieve_binary *sbin, const struct sieve_binary_extension *bext,
79500
 
+       void *context)
79501
 
+{
79502
 
+       struct sieve_binary_extension_reg *ereg = 
79503
 
+               sieve_binary_extension_get_reg(sbin, bext->extension, TRUE);
79504
 
+       
79505
 
+       if ( ereg != NULL ) {
79506
 
+               ereg->binext = bext;
79507
 
+
79508
 
+               if ( context != NULL )
79509
 
+                       ereg->context = context;
79510
 
+       }
79511
 
+}
79512
 
+
79513
 
+unsigned int sieve_binary_extension_create_block
79514
 
+(struct sieve_binary *sbin, const struct sieve_extension *ext)
79515
 
+{
79516
 
+       struct sieve_binary_block *block;       
79517
 
+       unsigned int block_id;
79518
 
+       struct sieve_binary_extension_reg *ereg = 
79519
 
+               sieve_binary_extension_get_reg(sbin, ext, TRUE);
79520
 
+       
79521
 
+       i_assert(ereg != NULL);
79522
 
+
79523
 
+       block = p_new(sbin->pool, struct sieve_binary_block, 1);
79524
 
+       block->buffer = buffer_create_dynamic(sbin->pool, 64);
79525
 
+
79526
 
+       block_id = sieve_binary_block_add(sbin, block);
79527
 
+       
79528
 
+       if ( ereg->block_id < SBIN_SYSBLOCK_LAST )
79529
 
+               ereg->block_id = block_id;
79530
 
+       block->ext_index = ereg->index;
79531
 
+       
79532
 
+       return block_id;
79533
 
+}
79534
 
+
79535
 
+unsigned int sieve_binary_extension_get_block
79536
 
+(struct sieve_binary *sbin, const struct sieve_extension *ext)
79537
 
+{
79538
 
+       struct sieve_binary_extension_reg *ereg = 
79539
 
+               sieve_binary_extension_get_reg(sbin, ext, TRUE);
79540
 
+               
79541
 
+       i_assert(ereg != NULL);
79542
 
+
79543
 
+       return ereg->block_id;
79544
 
+}
79545
 
+
79546
 
+static inline int sieve_binary_extension_register
79547
 
+(struct sieve_binary *sbin, const struct sieve_extension *ext, 
79548
 
+       struct sieve_binary_extension_reg **reg_r) 
79549
 
+{
79550
 
+       struct sieve_binary_extension_reg *ereg;
79551
 
+
79552
 
+       if ( (ereg=sieve_binary_extension_get_reg(sbin, ext, FALSE)) == NULL ) {
79553
 
+               ereg = sieve_binary_extension_create_reg(sbin, ext);
79554
 
+               
79555
 
+               if ( ereg == NULL ) return -1;
79556
 
+
79557
 
+               array_append(&sbin->linked_extensions, &ereg, 1);
79558
 
+       }
79559
 
+
79560
 
+       if ( reg_r != NULL ) *reg_r = ereg;
79561
 
+       return ereg->index;
79562
 
+}
79563
 
+
79564
 
+int sieve_binary_extension_link
79565
 
+(struct sieve_binary *sbin, const struct sieve_extension *ext) 
79566
 
+{      
79567
 
+       return sieve_binary_extension_register(sbin, ext, NULL);
79568
 
+}
79569
 
+
79570
 
+static inline const struct sieve_extension *_sieve_binary_extension_get_by_index
79571
 
+(struct sieve_binary *sbin, int index) 
79572
 
+{
79573
 
+       struct sieve_binary_extension_reg * const *ext;
79574
 
+       
79575
 
+       if ( index < (int) array_count(&sbin->extensions) ) {
79576
 
+               ext = array_idx(&sbin->extensions, (unsigned int) index);
79577
 
+               
79578
 
+               return (*ext)->extension;
79579
 
+       }
79580
 
+       
79581
 
+       return NULL;
79582
 
+}
79583
 
+
79584
 
+const struct sieve_extension *sieve_binary_extension_get_by_index
79585
 
+(struct sieve_binary *sbin, int index)
79586
 
+{
79587
 
+       return _sieve_binary_extension_get_by_index(sbin, index);
79588
 
+}
79589
 
+
79590
 
+int sieve_binary_extension_get_index
79591
 
+       (struct sieve_binary *sbin, const struct sieve_extension *ext) 
79592
 
+{
79593
 
+       struct sieve_binary_extension_reg *ereg =
79594
 
+               sieve_binary_extension_get_reg(sbin, ext, FALSE);
79595
 
+       
79596
 
+       return ( ereg == NULL ? -1 : ereg->index );
79597
 
+}
79598
 
+
79599
 
+int sieve_binary_extensions_count(struct sieve_binary *sbin) 
79600
 
+{
79601
 
+       return (int) array_count(&sbin->extensions);
79602
 
+}
79603
 
+
79604
 
+/*
79605
 
+ * Emission functions
79606
 
+ */
79607
 
+
79608
 
+/* Low-level emission functions */
79609
 
+
79610
 
+static inline void _sieve_binary_emit_data
79611
 
+(struct sieve_binary *sbin, const void *data, sieve_size_t size) 
79612
 
+{        
79613
 
+       buffer_append(sbin->data, data, size);
79614
 
+}
79615
 
+
79616
 
+static inline void _sieve_binary_emit_byte
79617
 
+(struct sieve_binary *sbin, unsigned char byte)
79618
 
+{
79619
 
+    _sieve_binary_emit_data(sbin, &byte, 1);
79620
 
+}
79621
 
+
79622
 
+static inline void _sieve_binary_update_data
79623
 
+(struct sieve_binary *sbin, sieve_size_t address, const void *data, 
79624
 
+       sieve_size_t size) 
79625
 
+{
79626
 
+       buffer_write(sbin->data, address, data, size);
79627
 
+}
79628
 
+
79629
 
+sieve_size_t sieve_binary_emit_data
79630
 
+(struct sieve_binary *sbin, const void *data, sieve_size_t size)
79631
 
+{
79632
 
+       sieve_size_t address = _sieve_binary_get_code_size(sbin);
79633
 
+
79634
 
+       _sieve_binary_emit_data(sbin, data, size);
79635
 
+
79636
 
+       return address;
79637
 
+}
79638
 
+
79639
 
+sieve_size_t sieve_binary_emit_byte
79640
 
+(struct sieve_binary *sbin, unsigned char byte) 
79641
 
+{
79642
 
+       sieve_size_t address = _sieve_binary_get_code_size(sbin);
79643
 
+
79644
 
+       _sieve_binary_emit_data(sbin, &byte, 1);
79645
 
+       
79646
 
+       return address;
79647
 
+}
79648
 
+
79649
 
+void sieve_binary_update_data
79650
 
+(struct sieve_binary *sbin, sieve_size_t address, const void *data, 
79651
 
+       sieve_size_t size) 
79652
 
+{
79653
 
+       _sieve_binary_update_data(sbin, address, data, size);
79654
 
+}
79655
 
+
79656
 
+/* Offset emission functions */
79657
 
+
79658
 
+sieve_size_t sieve_binary_emit_offset(struct sieve_binary *binary, int offset) 
79659
 
+{
79660
 
+       int i;
79661
 
+       sieve_size_t address = _sieve_binary_get_code_size(binary);
79662
 
+
79663
 
+       for ( i = 3; i >= 0; i-- ) {
79664
 
+               char c = (char) (offset >> (i * 8));
79665
 
+               _sieve_binary_emit_data(binary, &c, 1);
79666
 
+       }
79667
 
+       
79668
 
+       return address;
79669
 
+}
79670
 
+
79671
 
+void sieve_binary_resolve_offset
79672
 
+       (struct sieve_binary *binary, sieve_size_t address) 
79673
 
+{
79674
 
+       int i;
79675
 
+       int offset = _sieve_binary_get_code_size(binary) - address; 
79676
 
+       
79677
 
+       for ( i = 3; i >= 0; i-- ) {
79678
 
+               char c = (char) (offset >> (i * 8));    
79679
 
+               _sieve_binary_update_data(binary, address + 3 - i, &c, 1);
79680
 
+       }
79681
 
+}
79682
 
+
79683
 
+/* Literal emission */
79684
 
+
79685
 
+/* FIXME: this integer format is compact, but it might be too slow. 
79686
 
+ */
79687
 
+
79688
 
+sieve_size_t sieve_binary_emit_integer
79689
 
+(struct sieve_binary *binary, sieve_number_t integer)
79690
 
+{
79691
 
+       sieve_size_t address = _sieve_binary_get_code_size(binary);
79692
 
+       int i;
79693
 
+       char buffer[sizeof(sieve_number_t) + 1];
79694
 
+       int bufpos = sizeof(buffer) - 1;
79695
 
+  
79696
 
+       buffer[bufpos] = integer & 0x7F;
79697
 
+       bufpos--;
79698
 
+       integer >>= 7;
79699
 
+       while ( integer > 0 ) {
79700
 
+               buffer[bufpos] = integer & 0x7F;
79701
 
+               bufpos--;
79702
 
+               integer >>= 7;  
79703
 
+       }
79704
 
+  
79705
 
+       bufpos++;
79706
 
+       if ( (sizeof(buffer) - bufpos) > 1 ) { 
79707
 
+               for ( i = bufpos; i < ((int) sizeof(buffer) - 1); i++) {
79708
 
+                       buffer[i] |= 0x80;
79709
 
+               }
79710
 
+       } 
79711
 
+  
79712
 
+       _sieve_binary_emit_data(binary, buffer + bufpos, sizeof(buffer) - bufpos);
79713
 
+
79714
 
+       return address;
79715
 
+}
79716
 
+
79717
 
+static inline sieve_size_t sieve_binary_emit_dynamic_data
79718
 
+       (struct sieve_binary *binary, const void *data, sieve_size_t size)
79719
 
+{
79720
 
+       sieve_size_t address = sieve_binary_emit_integer(binary, (sieve_number_t) size);
79721
 
+
79722
 
+       _sieve_binary_emit_data(binary, data, size);
79723
 
+  
79724
 
+       return address;
79725
 
+}
79726
 
+
79727
 
+sieve_size_t sieve_binary_emit_cstring
79728
 
+       (struct sieve_binary *binary, const char *str)
79729
 
+{
79730
 
+       sieve_size_t address = sieve_binary_emit_dynamic_data
79731
 
+               (binary, (void *) str, (sieve_size_t) strlen(str));
79732
 
+       _sieve_binary_emit_byte(binary, 0);
79733
 
+  
79734
 
+       return address;
79735
 
+}
79736
 
+
79737
 
+sieve_size_t sieve_binary_emit_string
79738
 
+       (struct sieve_binary *binary, const string_t *str)
79739
 
+{
79740
 
+       sieve_size_t address = sieve_binary_emit_dynamic_data
79741
 
+               (binary, (void *) str_data(str), (sieve_size_t) str_len(str));
79742
 
+       _sieve_binary_emit_byte(binary, 0);
79743
 
+       
79744
 
+       return address;
79745
 
+}
79746
 
+
79747
 
+/*
79748
 
+ * Extension emission
79749
 
+ */
79750
 
+
79751
 
+sieve_size_t sieve_binary_emit_extension
79752
 
+(struct sieve_binary *sbin, const struct sieve_extension *ext,
79753
 
+       unsigned int offset)
79754
 
+{
79755
 
+       sieve_size_t address = _sieve_binary_get_code_size(sbin);
79756
 
+       struct sieve_binary_extension_reg *ereg = NULL;
79757
 
+
79758
 
+       (void)sieve_binary_extension_register(sbin, ext, &ereg);
79759
 
+
79760
 
+       i_assert(ereg != NULL);
79761
 
+
79762
 
+       _sieve_binary_emit_byte(sbin, offset + ereg->index);
79763
 
+       return address;
79764
 
+}
79765
 
+
79766
 
+void sieve_binary_emit_extension_object
79767
 
+(struct sieve_binary *sbin, const struct sieve_extension_objects *objs,
79768
 
+       unsigned int code)
79769
 
+{
79770
 
+       if ( objs->count > 1 )
79771
 
+               _sieve_binary_emit_byte(sbin, code);
79772
 
+}
79773
 
+
79774
 
+/*
79775
 
+ * Code retrieval
79776
 
+ */
79777
 
79778
 
+#define ADDR_CODE_AT(binary, address) ((signed char) ((binary)->code[*address]))
79779
 
+#define ADDR_DATA_AT(binary, address) ((unsigned char) ((binary)->code[*address]))
79780
 
+#define ADDR_POINTER(binary, address) ((const char *) (&(binary)->code[*address]))
79781
 
+#define ADDR_BYTES_LEFT(binary, address) ((binary)->code_size - (*address))
79782
 
+#define ADDR_JUMP(address, offset) (*address) += offset
79783
 
+
79784
 
+/* Literals */
79785
 
+
79786
 
+bool sieve_binary_read_byte
79787
 
+       (struct sieve_binary *binary, sieve_size_t *address, unsigned int *byte_r) 
79788
 
+{      
79789
 
+       if ( ADDR_BYTES_LEFT(binary, address) >= 1 ) {
79790
 
+               if ( byte_r != NULL )
79791
 
+                       *byte_r = ADDR_DATA_AT(binary, address);
79792
 
+               ADDR_JUMP(address, 1);
79793
 
+                       
79794
 
+               return TRUE;
79795
 
+       }
79796
 
+       
79797
 
+       *byte_r = 0;
79798
 
+       return FALSE;
79799
 
+}
79800
 
+
79801
 
+bool sieve_binary_read_code
79802
 
+       (struct sieve_binary *binary, sieve_size_t *address, signed int *code_r) 
79803
 
+{      
79804
 
+       if ( ADDR_BYTES_LEFT(binary, address) >= 1 ) {
79805
 
+               if ( code_r != NULL )
79806
 
+                       *code_r = ADDR_CODE_AT(binary, address);
79807
 
+               ADDR_JUMP(address, 1);
79808
 
+                       
79809
 
+               return TRUE;
79810
 
+       }
79811
 
+       
79812
 
+       *code_r = 0;
79813
 
+       return FALSE;
79814
 
+}
79815
 
+
79816
 
+
79817
 
+bool sieve_binary_read_offset
79818
 
+       (struct sieve_binary *binary, sieve_size_t *address, int *offset_r) 
79819
 
+{
79820
 
+       uint32_t offs = 0;
79821
 
+       
79822
 
+       if ( ADDR_BYTES_LEFT(binary, address) >= 4 ) {
79823
 
+               int i; 
79824
 
+         
79825
 
+               for ( i = 0; i < 4; i++ ) {
79826
 
+                       offs = (offs << 8) + ADDR_DATA_AT(binary, address);
79827
 
+                       ADDR_JUMP(address, 1);
79828
 
+               }
79829
 
+         
79830
 
+               if ( offset_r != NULL )
79831
 
+                       *offset_r = (int) offs;
79832
 
+                       
79833
 
+               return TRUE;
79834
 
+       }
79835
 
+       
79836
 
+       return FALSE;
79837
 
+}
79838
 
+
79839
 
+/* FIXME: might need negative numbers in the future */
79840
 
+bool sieve_binary_read_integer
79841
 
+  (struct sieve_binary *binary, sieve_size_t *address, sieve_number_t *int_r) 
79842
 
+{
79843
 
+       int bits = sizeof(sieve_number_t) * 8;
79844
 
+       *int_r = 0;
79845
 
+  
79846
 
+       if ( ADDR_BYTES_LEFT(binary, address) == 0 )
79847
 
+               return FALSE;
79848
 
+  
79849
 
+       while ( (ADDR_DATA_AT(binary, address) & 0x80) > 0 ) {
79850
 
+               if ( ADDR_BYTES_LEFT(binary, address) > 0 && bits > 0) {
79851
 
+                       *int_r |= ADDR_DATA_AT(binary, address) & 0x7F;
79852
 
+                       ADDR_JUMP(address, 1);
79853
 
+    
79854
 
+                       *int_r <<= 7;
79855
 
+                       bits -= 7;
79856
 
+               } else {
79857
 
+                       /* This is an error */
79858
 
+                       return FALSE;
79859
 
+               }
79860
 
+       }
79861
 
+  
79862
 
+       *int_r |= ADDR_DATA_AT(binary, address) & 0x7F;
79863
 
+       ADDR_JUMP(address, 1);
79864
 
+  
79865
 
+       return TRUE;
79866
 
+}
79867
 
+
79868
 
+bool sieve_binary_read_string
79869
 
+(struct sieve_binary *binary, sieve_size_t *address, string_t **str_r) 
79870
 
+{
79871
 
+       unsigned int strlen = 0;
79872
 
+  
79873
 
+       if ( !sieve_binary_read_unsigned(binary, address, &strlen) ) 
79874
 
+               return FALSE;
79875
 
+         
79876
 
+       if ( strlen > ADDR_BYTES_LEFT(binary, address) ) 
79877
 
+               return FALSE;
79878
 
79879
 
+       if ( str_r != NULL )  
79880
 
+               *str_r = t_str_new_const(ADDR_POINTER(binary, address), strlen);
79881
 
+       ADDR_JUMP(address, strlen);
79882
 
+       
79883
 
+       if ( ADDR_CODE_AT(binary, address) != 0 )
79884
 
+               return FALSE;
79885
 
+       
79886
 
+       ADDR_JUMP(address, 1);
79887
 
+  
79888
 
+       return TRUE;
79889
 
+}
79890
 
+
79891
 
+bool sieve_binary_read_extension
79892
 
+(struct sieve_binary *sbin, sieve_size_t *address, unsigned int *offset_r,
79893
 
+       const struct sieve_extension **ext_r)
79894
 
+{
79895
 
+       unsigned int code;
79896
 
+       unsigned int offset = *offset_r;
79897
 
+       const struct sieve_extension *ext = NULL;
79898
 
+
79899
 
+       if ( ADDR_BYTES_LEFT(sbin, address) <= 0 )
79900
 
+               return FALSE;
79901
 
+
79902
 
+       (*offset_r) = code = ADDR_DATA_AT(sbin, address);
79903
 
+       ADDR_JUMP(address, 1);
79904
 
+
79905
 
+       if ( code >= offset ) {
79906
 
+               ext = _sieve_binary_extension_get_by_index(sbin, code - offset);
79907
 
+               
79908
 
+               if ( ext == NULL ) 
79909
 
+                       return FALSE;
79910
 
+       }
79911
 
+
79912
 
+       (*ext_r) = ext;
79913
 
+
79914
 
+       return TRUE;
79915
 
+}
79916
 
+
79917
 
+const void *sieve_binary_read_extension_object
79918
 
+(struct sieve_binary *sbin, sieve_size_t *address, 
79919
 
+       const struct sieve_extension_objects *objs)
79920
 
+{
79921
 
+       unsigned int code;
79922
 
+
79923
 
+       if ( objs->count == 0 ) 
79924
 
+               return NULL;
79925
 
+
79926
 
+       if ( objs->count == 1 )
79927
 
+               return objs->objects;
79928
 
+
79929
 
+       if ( ADDR_BYTES_LEFT(sbin, address) <= 0 )
79930
 
+               return NULL;
79931
 
+
79932
 
+       code = ADDR_DATA_AT(sbin, address);
79933
 
+       ADDR_JUMP(address, 1);  
79934
 
+
79935
 
+       if ( code >= objs->count )
79936
 
+               return NULL;
79937
 
+
79938
 
+       return ((const void *const *) objs->objects)[code];
79939
 
+}
79940
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-binary-dumper.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-binary-dumper.c
79941
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-binary-dumper.c  1970-01-01 01:00:00.000000000 +0100
79942
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-binary-dumper.c   2009-04-10 17:48:29.000000000 +0200
79943
 
@@ -0,0 +1,153 @@
79944
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
79945
 
+ */
79946
 
+
79947
 
+#include "lib.h"
79948
 
+#include "str.h"
79949
 
+#include "ostream.h"
79950
 
+
79951
 
+#include "sieve-common.h"
79952
 
+#include "sieve-extensions.h"
79953
 
+#include "sieve-binary.h"
79954
 
+
79955
 
+#include "sieve-dump.h"
79956
 
+
79957
 
+/*
79958
 
+ * Binary dumper object
79959
 
+ */ 
79960
 
79961
 
+struct sieve_binary_dumper {
79962
 
+       pool_t pool;
79963
 
+       
79964
 
+       /* Dumptime environment */
79965
 
+       struct sieve_dumptime_env dumpenv; 
79966
 
+};
79967
 
+
79968
 
+struct sieve_binary_dumper *sieve_binary_dumper_create
79969
 
+       (struct sieve_binary *sbin) 
79970
 
+{
79971
 
+       pool_t pool;
79972
 
+       struct sieve_binary_dumper *dumper;
79973
 
+       
79974
 
+       pool = pool_alloconly_create("sieve_binary_dumper", 4096);      
79975
 
+       dumper = p_new(pool, struct sieve_binary_dumper, 1);
79976
 
+       dumper->pool = pool;
79977
 
+       dumper->dumpenv.dumper = dumper;
79978
 
+       
79979
 
+       dumper->dumpenv.sbin = sbin;
79980
 
+       sieve_binary_ref(sbin);
79981
 
+       
79982
 
+       return dumper;
79983
 
+}
79984
 
+
79985
 
+void sieve_binary_dumper_free(struct sieve_binary_dumper **dumper) 
79986
 
+{
79987
 
+       sieve_binary_unref(&(*dumper)->dumpenv.sbin);
79988
 
+       pool_unref(&((*dumper)->pool));
79989
 
+       
79990
 
+       *dumper = NULL;
79991
 
+}
79992
 
+
79993
 
+pool_t sieve_binary_dumper_pool(struct sieve_binary_dumper *dumper)
79994
 
+{
79995
 
+       return dumper->pool;
79996
 
+}
79997
 
+
79998
 
+/* 
79999
 
+ * Formatted output 
80000
 
+ */
80001
 
+
80002
 
+void sieve_binary_dumpf
80003
 
+(const struct sieve_dumptime_env *denv, const char *fmt, ...)
80004
 
+{ 
80005
 
+       string_t *outbuf = t_str_new(128);
80006
 
+       va_list args;
80007
 
+       
80008
 
+       va_start(args, fmt);                    
80009
 
+       str_vprintfa(outbuf, fmt, args);
80010
 
+       va_end(args);
80011
 
+       
80012
 
+       o_stream_send(denv->stream, str_data(outbuf), str_len(outbuf));
80013
 
+}
80014
 
+
80015
 
+void sieve_binary_dump_sectionf
80016
 
+(const struct sieve_dumptime_env *denv, const char *fmt, ...)
80017
 
+{
80018
 
+       string_t *outbuf = t_str_new(128);
80019
 
+       va_list args;
80020
 
+       
80021
 
+       va_start(args, fmt);                    
80022
 
+       str_printfa(outbuf, "\n* ");
80023
 
+       str_vprintfa(outbuf, fmt, args);
80024
 
+       str_printfa(outbuf, ":\n\n");
80025
 
+       va_end(args);
80026
 
+       
80027
 
+       o_stream_send(denv->stream, str_data(outbuf), str_len(outbuf));
80028
 
+}
80029
 
+
80030
 
+/* 
80031
 
+ * Dumping the binary
80032
 
+ */
80033
 
+
80034
 
+bool sieve_binary_dumper_run
80035
 
+(struct sieve_binary_dumper *dumper, struct ostream *stream) 
80036
 
+{      
80037
 
+       struct sieve_binary *sbin = dumper->dumpenv.sbin;
80038
 
+       struct sieve_dumptime_env *denv = &(dumper->dumpenv);
80039
 
+       int count, i;
80040
 
+       
80041
 
+       dumper->dumpenv.stream = stream;
80042
 
+       
80043
 
+       /* Dump list of used extensions */
80044
 
+       
80045
 
+       count = sieve_binary_extensions_count(sbin);
80046
 
+       if ( count > 0 ) {
80047
 
+               sieve_binary_dump_sectionf(denv, "Required extensions");
80048
 
+       
80049
 
+               for ( i = 0; i < count; i++ ) {
80050
 
+                       const struct sieve_extension *ext = sieve_binary_extension_get_by_index
80051
 
+                               (sbin, i);
80052
 
+                       sieve_binary_dumpf(denv, "%3d: %s (%d)\n", i, ext->name, SIEVE_EXT_ID(ext));
80053
 
+               }
80054
 
+       }
80055
 
+
80056
 
+       /* Dump extension-specific elements of the binary */
80057
 
+       
80058
 
+       count = sieve_binary_extensions_count(sbin);
80059
 
+       if ( count > 0 ) {      
80060
 
+               for ( i = 0; i < count; i++ ) {
80061
 
+                       bool success = TRUE;
80062
 
+
80063
 
+                       T_BEGIN { 
80064
 
+                               const struct sieve_extension *ext = sieve_binary_extension_get_by_index
80065
 
+                                       (sbin, i);
80066
 
+       
80067
 
+                               if ( ext->binary_dump != NULL ) {       
80068
 
+                                       success = ext->binary_dump(denv);
80069
 
+                               }
80070
 
+                       } T_END;
80071
 
+
80072
 
+                       if ( !success ) return FALSE;
80073
 
+               }
80074
 
+       }
80075
 
+       
80076
 
+       /* Dump main program */
80077
 
+       
80078
 
+       sieve_binary_dump_sectionf(denv, "Main program (block: %d)", SBIN_SYSBLOCK_MAIN_PROGRAM);
80079
 
+
80080
 
+       if ( !sieve_binary_block_set_active(sbin, SBIN_SYSBLOCK_MAIN_PROGRAM, NULL) ) {
80081
 
+        return FALSE;
80082
 
+       }
80083
 
+
80084
 
+       dumper->dumpenv.cdumper = sieve_code_dumper_create(&(dumper->dumpenv));
80085
 
+
80086
 
+       if ( dumper->dumpenv.cdumper != NULL ) {
80087
 
+               sieve_code_dumper_run(dumper->dumpenv.cdumper);
80088
 
+               
80089
 
+               sieve_code_dumper_free(&dumper->dumpenv.cdumper);
80090
 
+       }
80091
 
+       
80092
 
+       /* Finish with empty line */
80093
 
+       sieve_binary_dumpf(denv, "\n");
80094
 
+
80095
 
+       return TRUE;
80096
 
+}
80097
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-binary-dumper.h dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-binary-dumper.h
80098
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-binary-dumper.h  1970-01-01 01:00:00.000000000 +0100
80099
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-binary-dumper.h   2009-01-06 00:15:52.000000000 +0100
80100
 
@@ -0,0 +1,40 @@
80101
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
80102
 
+ */
80103
 
+
80104
 
+#ifndef __SIEVE_BINARY_DUMPER_H
80105
 
+#define __SIEVE_BINARY_DUMPER_H
80106
 
+
80107
 
+#include "sieve-common.h"
80108
 
+
80109
 
+/*
80110
 
+ * Binary dumper object
80111
 
+ */
80112
 
+
80113
 
+struct sieve_binary_dumper;
80114
 
+
80115
 
+struct sieve_binary_dumper *sieve_binary_dumper_create
80116
 
+       (struct sieve_binary *sbin);
80117
 
+void sieve_binary_dumper_free
80118
 
+       (struct sieve_binary_dumper **dumper);
80119
 
+
80120
 
+pool_t sieve_binary_dumper_pool
80121
 
+       (struct sieve_binary_dumper *dumper);
80122
 
+
80123
 
+/* 
80124
 
+ * Formatted output 
80125
 
+ */
80126
 
+
80127
 
+void sieve_binary_dumpf
80128
 
+       (const struct sieve_dumptime_env *denv, const char *fmt, ...);
80129
 
+void sieve_binary_dump_sectionf
80130
 
+       (const struct sieve_dumptime_env *denv, const char *fmt, ...);
80131
 
+
80132
 
+/*
80133
 
+ * Dumping the binary
80134
 
+ */
80135
 
+
80136
 
+bool sieve_binary_dumper_run
80137
 
+       (struct sieve_binary_dumper *dumper, struct ostream *stream);
80138
 
+
80139
 
+
80140
 
+#endif /* __SIEVE_BINARY_DUMPER_H */
80141
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-binary.h dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-binary.h
80142
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-binary.h 1970-01-01 01:00:00.000000000 +0100
80143
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-binary.h  2009-08-05 13:07:32.000000000 +0200
80144
 
@@ -0,0 +1,194 @@
80145
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
80146
 
+ */
80147
 
+
80148
 
+#ifndef __SIEVE_BINARY_H
80149
 
+#define __SIEVE_BINARY_H
80150
 
+
80151
 
+#include "lib.h"
80152
 
+
80153
 
+#include "sieve-common.h"
80154
 
+
80155
 
+/*
80156
 
+ * Binary object
80157
 
+ */
80158
 
80159
 
+struct sieve_binary;
80160
 
+
80161
 
+struct sieve_binary *sieve_binary_create_new(struct sieve_script *script);
80162
 
+void sieve_binary_ref(struct sieve_binary *sbin);
80163
 
+void sieve_binary_unref(struct sieve_binary **sbin);
80164
 
+
80165
 
+/*
80166
 
+ * Accessors
80167
 
+ */
80168
 
+
80169
 
+pool_t sieve_binary_pool(struct sieve_binary *sbin);
80170
 
+struct sieve_script *sieve_binary_script(struct sieve_binary *sbin);
80171
 
+const char *sieve_binary_path(struct sieve_binary *sbin);
80172
 
+bool sieve_binary_script_older
80173
 
+       (struct sieve_binary *sbin, struct sieve_script *script);
80174
 
+
80175
 
+const char *sieve_binary_script_name(struct sieve_binary *sbin);
80176
 
+const char *sieve_binary_script_path(struct sieve_binary *sbin);
80177
 
+
80178
 
+/*
80179
 
+ * Activation after code generation
80180
 
+ */ 
80181
 
80182
 
+void sieve_binary_activate(struct sieve_binary *sbin);
80183
 
+
80184
 
+/* 
80185
 
+ * Saving the binary
80186
 
+ */
80187
 
80188
 
+bool sieve_binary_save
80189
 
+       (struct sieve_binary *sbin, const char *path);
80190
 
+       
80191
 
+/* 
80192
 
+ * Loading the binary
80193
 
+ */ 
80194
 
+       
80195
 
+struct sieve_binary *sieve_binary_open
80196
 
+       (const char *path, struct sieve_script *script);
80197
 
+bool sieve_binary_up_to_date(struct sieve_binary *sbin);
80198
 
+bool sieve_binary_load(struct sieve_binary *sbin);
80199
 
+       
80200
 
+/* 
80201
 
+ * Block management 
80202
 
+ */
80203
 
80204
 
+enum sieve_binary_system_block {
80205
 
+       SBIN_SYSBLOCK_EXTENSIONS,
80206
 
+       SBIN_SYSBLOCK_MAIN_PROGRAM,
80207
 
+       SBIN_SYSBLOCK_LAST
80208
 
+};
80209
 
+
80210
 
+bool sieve_binary_block_set_active
80211
 
+       (struct sieve_binary *sbin, unsigned int id, unsigned *old_id_r);
80212
 
+unsigned int sieve_binary_block_create(struct sieve_binary *sbin);
80213
 
+void sieve_binary_block_clear
80214
 
+       (struct sieve_binary *sbin, unsigned int id);
80215
 
+       
80216
 
+/* 
80217
 
+ * Extension support 
80218
 
+ */
80219
 
80220
 
+struct sieve_binary_extension {
80221
 
+       const struct sieve_extension *extension;
80222
 
+
80223
 
+       bool (*binary_save)(struct sieve_binary *sbin);
80224
 
+       bool (*binary_open)(struct sieve_binary *sbin);
80225
 
+       
80226
 
+       void (*binary_free)(struct sieve_binary *sbin);
80227
 
+       
80228
 
+       bool (*binary_up_to_date)(struct sieve_binary *sbin);
80229
 
+};
80230
 
80231
 
+void sieve_binary_extension_set_context
80232
 
+       (struct sieve_binary *sbin, const struct sieve_extension *ext, void *context);
80233
 
+const void *sieve_binary_extension_get_context
80234
 
+       (struct sieve_binary *sbin, const struct sieve_extension *ext);
80235
 
+       
80236
 
+void sieve_binary_extension_set
80237
 
+       (struct sieve_binary *sbin, const struct sieve_binary_extension *bext,
80238
 
+               void *context);
80239
 
+
80240
 
+unsigned int sieve_binary_extension_create_block
80241
 
+       (struct sieve_binary *sbin, const struct sieve_extension *ext);
80242
 
+unsigned int sieve_binary_extension_get_block
80243
 
+(struct sieve_binary *sbin, const struct sieve_extension *ext);
80244
 
+
80245
 
+int sieve_binary_extension_link
80246
 
+       (struct sieve_binary *sbin, const struct sieve_extension *ext);
80247
 
+const struct sieve_extension *sieve_binary_extension_get_by_index
80248
 
+       (struct sieve_binary *sbin, int index);
80249
 
+int sieve_binary_extension_get_index
80250
 
+       (struct sieve_binary *sbin, const struct sieve_extension *ext);
80251
 
+int sieve_binary_extensions_count(struct sieve_binary *sbin);
80252
 
+
80253
 
+       
80254
 
+/* 
80255
 
+ * Code emission 
80256
 
+ */
80257
 
80258
 
+/* Low-level emission functions */
80259
 
+
80260
 
+sieve_size_t sieve_binary_emit_data
80261
 
+       (struct sieve_binary *binary, const void *data, sieve_size_t size);
80262
 
+sieve_size_t sieve_binary_emit_byte
80263
 
+       (struct sieve_binary *binary, unsigned char byte);
80264
 
+void sieve_binary_update_data
80265
 
+       (struct sieve_binary *binary, sieve_size_t address, const void *data, 
80266
 
+               sieve_size_t size);
80267
 
+sieve_size_t sieve_binary_get_code_size(struct sieve_binary *binary);
80268
 
+
80269
 
+/* Offset emission functions */
80270
 
+
80271
 
+sieve_size_t sieve_binary_emit_offset
80272
 
+       (struct sieve_binary *binary, int offset);
80273
 
+void sieve_binary_resolve_offset
80274
 
+       (struct sieve_binary *binary, sieve_size_t address);
80275
 
+
80276
 
+/* Literal emission functions */
80277
 
+
80278
 
+sieve_size_t sieve_binary_emit_integer
80279
 
+       (struct sieve_binary *binary, sieve_number_t integer);
80280
 
+sieve_size_t sieve_binary_emit_string
80281
 
+       (struct sieve_binary *binary, const string_t *str);
80282
 
+sieve_size_t sieve_binary_emit_cstring
80283
 
+       (struct sieve_binary *binary, const char *str);
80284
 
+
80285
 
+static inline sieve_size_t sieve_binary_emit_unsigned
80286
 
+       (struct sieve_binary *binary, unsigned int count)
80287
 
+{
80288
 
+       return sieve_binary_emit_integer(binary, count);
80289
 
+}
80290
 
+
80291
 
+
80292
 
+/* Extension emission functions */
80293
 
+
80294
 
+sieve_size_t sieve_binary_emit_extension
80295
 
+       (struct sieve_binary *sbin, const struct sieve_extension *ext,
80296
 
+               unsigned int offset);
80297
 
+void sieve_binary_emit_extension_object
80298
 
+       (struct sieve_binary *sbin, const struct sieve_extension_objects *objs,
80299
 
+       unsigned int code);
80300
 
+
80301
 
+/* 
80302
 
+ * Code retrieval 
80303
 
+ */
80304
 
+
80305
 
+/* Literals */
80306
 
+bool sieve_binary_read_byte
80307
 
+       (struct sieve_binary *binary, sieve_size_t *address, unsigned int *byte_r);
80308
 
+bool sieve_binary_read_code
80309
 
+       (struct sieve_binary *binary, sieve_size_t *address, signed int *code_r);
80310
 
+bool sieve_binary_read_offset
80311
 
+       (struct sieve_binary *binary, sieve_size_t *address, int *offset_r);
80312
 
+bool sieve_binary_read_integer
80313
 
+  (struct sieve_binary *binary, sieve_size_t *address, sieve_number_t *int_r); 
80314
 
+bool sieve_binary_read_string
80315
 
+  (struct sieve_binary *binary, sieve_size_t *address, string_t **str_r);
80316
 
+
80317
 
+static inline bool sieve_binary_read_unsigned
80318
 
+  (struct sieve_binary *binary, sieve_size_t *address, unsigned int *count_r)
80319
 
+{
80320
 
+       sieve_number_t integer;
80321
 
+
80322
 
+       if ( !sieve_binary_read_integer(binary, address, &integer) )
80323
 
+               return FALSE;
80324
 
+
80325
 
+       *count_r = integer;
80326
 
+
80327
 
+       return TRUE;
80328
 
+}
80329
 
+
80330
 
+/* Extension */
80331
 
+bool sieve_binary_read_extension
80332
 
+       (struct sieve_binary *sbin, sieve_size_t *address, unsigned int *offset_r,
80333
 
+               const struct sieve_extension **ext_r);
80334
 
+const void *sieve_binary_read_extension_object
80335
 
+       (struct sieve_binary *binary, sieve_size_t *address,
80336
 
+       const struct sieve_extension_objects *objs);
80337
 
+
80338
 
+#endif
80339
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve.c
80340
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve.c        1970-01-01 01:00:00.000000000 +0100
80341
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve.c 2009-08-04 19:31:14.000000000 +0200
80342
 
@@ -0,0 +1,609 @@
80343
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file 
80344
 
+ */
80345
 
+
80346
 
+#include "lib.h"
80347
 
+#include "str.h"
80348
 
+#include "istream.h"
80349
 
+#include "buffer.h"
80350
 
+
80351
 
+#include "sieve-extensions.h"
80352
 
+
80353
 
+#include "sieve-script.h"
80354
 
+#include "sieve-ast.h"
80355
 
+#include "sieve-binary.h"
80356
 
+#include "sieve-actions.h"
80357
 
+#include "sieve-result.h"
80358
 
+
80359
 
+#include "sieve-parser.h"
80360
 
+#include "sieve-validator.h"
80361
 
+#include "sieve-generator.h"
80362
 
+#include "sieve-interpreter.h"
80363
 
+#include "sieve-binary-dumper.h"
80364
 
+
80365
 
+#include "sieve.h"
80366
 
+#include "sieve-common.h"
80367
 
+
80368
 
+#include <sys/types.h>
80369
 
+#include <sys/stat.h>
80370
 
+#include <fcntl.h>
80371
 
+#include <stdlib.h>
80372
 
+#include <unistd.h>
80373
 
+#include <stdio.h>
80374
 
+#include <dirent.h>
80375
 
+
80376
 
+/* 
80377
 
+ * Main Sieve library interface
80378
 
+ */
80379
 
+
80380
 
+bool sieve_init(void)
80381
 
+{
80382
 
+       return sieve_extensions_init();
80383
 
+}
80384
 
+
80385
 
+void sieve_deinit(void)
80386
 
+{
80387
 
+       sieve_extensions_deinit();
80388
 
+}
80389
 
+
80390
 
+void sieve_set_extensions(const char *extensions)
80391
 
+{
80392
 
+       sieve_extensions_set_string(extensions);
80393
 
+}
80394
 
+
80395
 
+const char *sieve_get_capabilities(const char *name) 
80396
 
+{
80397
 
+       if ( name == NULL || *name == '\0' )
80398
 
+               return sieve_extensions_get_string();
80399
 
+       
80400
 
+       return sieve_extension_capabilities_get_string(name);
80401
 
+}
80402
 
+
80403
 
+/*
80404
 
+ * Low-level compiler functions 
80405
 
+ */
80406
 
+
80407
 
+struct sieve_ast *sieve_parse
80408
 
+       (struct sieve_script *script, struct sieve_error_handler *ehandler)
80409
 
+{
80410
 
+       struct sieve_parser *parser;
80411
 
+       struct sieve_ast *ast = NULL;
80412
 
+       
80413
 
+       /* Parse */
80414
 
+       if ( (parser = sieve_parser_create(script, ehandler)) == NULL )
80415
 
+               return NULL;
80416
 
+
80417
 
+       if ( !sieve_parser_run(parser, &ast) || sieve_get_errors(ehandler) > 0 ) {
80418
 
+               ast = NULL;
80419
 
+       } else 
80420
 
+               sieve_ast_ref(ast);
80421
 
+       
80422
 
+       sieve_parser_free(&parser);     
80423
 
+       
80424
 
+       return ast;
80425
 
+}
80426
 
+
80427
 
+bool sieve_validate(struct sieve_ast *ast, struct sieve_error_handler *ehandler)
80428
 
+{
80429
 
+       bool result = TRUE;
80430
 
+       struct sieve_validator *validator = sieve_validator_create(ast, ehandler);
80431
 
+               
80432
 
+       if ( !sieve_validator_run(validator) || sieve_get_errors(ehandler) > 0 ) 
80433
 
+               result = FALSE;
80434
 
+       
80435
 
+       sieve_validator_free(&validator);       
80436
 
+               
80437
 
+       return result;
80438
 
+}
80439
 
+
80440
 
+static struct sieve_binary *sieve_generate
80441
 
+       (struct sieve_ast *ast, struct sieve_error_handler *ehandler)
80442
 
+{
80443
 
+       struct sieve_generator *generator = sieve_generator_create(ast, ehandler);
80444
 
+       struct sieve_binary *sbin = NULL;
80445
 
+               
80446
 
+       (void) sieve_generator_run(generator, &sbin);
80447
 
+       
80448
 
+       sieve_generator_free(&generator);
80449
 
+       
80450
 
+       return sbin;
80451
 
+}
80452
 
+
80453
 
+/*
80454
 
+ * Sieve compilation
80455
 
+ */
80456
 
+
80457
 
+struct sieve_binary *sieve_compile_script
80458
 
+(struct sieve_script *script, struct sieve_error_handler *ehandler) 
80459
 
+{
80460
 
+       struct sieve_ast *ast;
80461
 
+       struct sieve_binary *sbin;              
80462
 
+       
80463
 
+       /* Parse */
80464
 
+       if ( (ast = sieve_parse(script, ehandler)) == NULL ) {
80465
 
+               sieve_error(ehandler, sieve_script_name(script), "parse failed");
80466
 
+               return NULL;
80467
 
+       }
80468
 
+
80469
 
+       /* Validate */
80470
 
+       if ( !sieve_validate(ast, ehandler) ) {
80471
 
+               sieve_error(ehandler, sieve_script_name(script), "validation failed");
80472
 
+               
80473
 
+               sieve_ast_unref(&ast);
80474
 
+               return NULL;
80475
 
+       }
80476
 
+       
80477
 
+       /* Generate */
80478
 
+       if ( (sbin=sieve_generate(ast, ehandler)) == NULL ) {
80479
 
+               sieve_error(ehandler, sieve_script_name(script), "code generation failed");
80480
 
+               
80481
 
+               sieve_ast_unref(&ast);
80482
 
+               return NULL;
80483
 
+       }
80484
 
+       
80485
 
+       /* Cleanup */
80486
 
+       sieve_ast_unref(&ast);
80487
 
+
80488
 
+       return sbin;
80489
 
+}
80490
 
+
80491
 
+struct sieve_binary *sieve_compile
80492
 
+(const char *script_path, const char *script_name, 
80493
 
+       struct sieve_error_handler *ehandler)
80494
 
+{
80495
 
+       struct sieve_script *script;
80496
 
+       struct sieve_binary *sbin;
80497
 
+
80498
 
+       if ( (script = sieve_script_create
80499
 
+               (script_path, script_name, ehandler, NULL)) == NULL )
80500
 
+               return NULL;
80501
 
+       
80502
 
+       sbin = sieve_compile_script(script, ehandler);
80503
 
+       
80504
 
+       sieve_script_unref(&script);
80505
 
+       
80506
 
+       return sbin;
80507
 
+}
80508
 
+
80509
 
+/*
80510
 
+ * Sieve runtime
80511
 
+ */
80512
 
+
80513
 
+static int sieve_run
80514
 
+(struct sieve_binary *sbin, struct sieve_result **result, 
80515
 
+       const struct sieve_message_data *msgdata, const struct sieve_script_env *senv, 
80516
 
+       struct sieve_error_handler *ehandler)
80517
 
+{
80518
 
+       struct sieve_interpreter *interp;
80519
 
+       int ret = 0;
80520
 
+
80521
 
+       /* Create the interpreter */
80522
 
+       if ( (interp=sieve_interpreter_create(sbin, ehandler)) == NULL )
80523
 
+               return SIEVE_EXEC_BIN_CORRUPT;
80524
 
+
80525
 
+       /* Reset execution status */
80526
 
+       if ( senv->exec_status != NULL )
80527
 
+               memset(senv->exec_status, 0, sizeof(*senv->exec_status));
80528
 
+       
80529
 
+       /* Create result object */
80530
 
+       if ( *result == NULL )
80531
 
+               *result = sieve_result_create(msgdata, senv, ehandler);
80532
 
+       else {
80533
 
+               sieve_result_ref(*result);
80534
 
+               sieve_result_set_error_handler(*result, ehandler);
80535
 
+       }
80536
 
+                                                       
80537
 
+       /* Run the interpreter */
80538
 
+       ret = sieve_interpreter_run(interp, msgdata, senv, *result);
80539
 
+       
80540
 
+       /* Free the interpreter */
80541
 
+       sieve_interpreter_free(&interp);
80542
 
+
80543
 
+       return ret;
80544
 
+}
80545
 
+
80546
 
+/*
80547
 
+ * Reading/writing sieve binaries
80548
 
+ */
80549
 
+
80550
 
+struct sieve_binary *sieve_open
80551
 
+(const char *script_path, const char *script_name,
80552
 
+       struct sieve_error_handler *ehandler, bool *exists_r)
80553
 
+{
80554
 
+       struct sieve_script *script;
80555
 
+       struct sieve_binary *sbin;
80556
 
+       const char *binpath;
80557
 
+       
80558
 
+       /* First open the scriptfile itself */
80559
 
+       script = sieve_script_create(script_path, script_name, ehandler, exists_r);
80560
 
+
80561
 
+       if ( script == NULL ) {
80562
 
+               /* Failed */
80563
 
+               return NULL;
80564
 
+       }
80565
 
+
80566
 
+       T_BEGIN {
80567
 
+               /* Then try to open the matching binary */
80568
 
+               binpath = sieve_script_binpath(script); 
80569
 
+               sbin = sieve_binary_open(binpath, script);
80570
 
+       
80571
 
+               if (sbin != NULL) {
80572
 
+                       /* Ok, it exists; now let's see if it is up to date */
80573
 
+                       if ( !sieve_binary_up_to_date(sbin) ) {
80574
 
+                               /* Not up to date */
80575
 
+                               sieve_binary_unref(&sbin);
80576
 
+                               sbin = NULL;
80577
 
+                       } else if ( !sieve_binary_load(sbin) ) {
80578
 
+                               /* Failed to load */
80579
 
+                               sieve_binary_unref(&sbin);
80580
 
+                               sbin = NULL;
80581
 
+                       }
80582
 
+               }
80583
 
+               
80584
 
+               /* If the binary does not exist, is not up-to-date or fails to load, we need
80585
 
+                * to (re-)compile.
80586
 
+                */
80587
 
+               if ( sbin == NULL ) {   
80588
 
+                       sbin = sieve_compile_script(script, ehandler);
80589
 
+
80590
 
+                       /* Save the binary if compile was successful */
80591
 
+                       if ( sbin != NULL ) 
80592
 
+                               (void) sieve_binary_save(sbin, binpath);        
80593
 
+               }
80594
 
+       } T_END;
80595
 
+       
80596
 
+       /* Drop script reference, if sbin != NULL it holds a reference of its own. 
80597
 
+        * Otherwise the script object is freed here.
80598
 
+        */
80599
 
+       sieve_script_unref(&script);
80600
 
+
80601
 
+       return sbin;
80602
 
+} 
80603
 
+
80604
 
+bool sieve_save
80605
 
+(struct sieve_binary *sbin, const char *bin_path)
80606
 
+{
80607
 
+       return sieve_binary_save(sbin, bin_path);
80608
 
+}
80609
 
+
80610
 
+struct sieve_binary *sieve_load
80611
 
+(const char *bin_path)
80612
 
+{
80613
 
+       struct sieve_binary *sbin = sieve_binary_open(bin_path, NULL);
80614
 
+
80615
 
+    if ( sbin != NULL && !sieve_binary_load(sbin) ) {
80616
 
+        sieve_binary_unref(&sbin);
80617
 
+        sbin = NULL;
80618
 
+    }
80619
 
+
80620
 
+       return sbin;
80621
 
+}
80622
 
+
80623
 
+void sieve_close(struct sieve_binary **sbin)
80624
 
+{
80625
 
+       sieve_binary_unref(sbin);
80626
 
+}
80627
 
+
80628
 
+/*
80629
 
+ * Debugging
80630
 
+ */
80631
 
+
80632
 
+void sieve_dump(struct sieve_binary *sbin, struct ostream *stream) 
80633
 
+{
80634
 
+       struct sieve_binary_dumper *dumpr = sieve_binary_dumper_create(sbin);                   
80635
 
+
80636
 
+       sieve_binary_dumper_run(dumpr, stream); 
80637
 
+       
80638
 
+       sieve_binary_dumper_free(&dumpr);
80639
 
+}
80640
 
+
80641
 
+int sieve_test
80642
 
+(struct sieve_binary *sbin, const struct sieve_message_data *msgdata,
80643
 
+       const struct sieve_script_env *senv, struct sieve_error_handler *ehandler,
80644
 
+       struct ostream *stream, bool *keep)     
80645
 
+{
80646
 
+       struct sieve_result *result = NULL;
80647
 
+       int ret;
80648
 
+
80649
 
+       if ( keep != NULL ) *keep = FALSE;
80650
 
+       
80651
 
+       /* Run the script */
80652
 
+       ret = sieve_run(sbin, &result, msgdata, senv, ehandler);
80653
 
+                               
80654
 
+       /* Print result if successful */
80655
 
+       if ( ret > 0 ) {
80656
 
+               ret = sieve_result_print(result, senv, stream, keep);
80657
 
+       } else if ( ret == 0 ) {
80658
 
+               if ( keep != NULL ) *keep = TRUE;
80659
 
+       }
80660
 
+       
80661
 
+       /* Cleanup */
80662
 
+       sieve_result_unref(&result);
80663
 
+       
80664
 
+       return ret;
80665
 
+}
80666
 
+
80667
 
+/*
80668
 
+ * Script execution
80669
 
+ */
80670
 
+
80671
 
+int sieve_execute
80672
 
+(struct sieve_binary *sbin, const struct sieve_message_data *msgdata,
80673
 
+       const struct sieve_script_env *senv, struct sieve_error_handler *ehandler,
80674
 
+       bool *keep)
80675
 
+{
80676
 
+       struct sieve_result *result = NULL;
80677
 
+       int ret;
80678
 
+
80679
 
+       if ( keep != NULL ) *keep = FALSE;
80680
 
+       
80681
 
+       /* Run the script */
80682
 
+       ret = sieve_run(sbin, &result, msgdata, senv, ehandler);
80683
 
+               
80684
 
+       /* Evaluate status and execute the result:
80685
 
+        *   Strange situations, e.g. currupt binaries, must be handled by the caller. 
80686
 
+        *   In that case no implicit keep is attempted, because the situation may be 
80687
 
+        *   resolved.
80688
 
+        */
80689
 
+       if ( ret > 0 ) {
80690
 
+               /* Execute result */
80691
 
+               ret = sieve_result_execute(result, keep);
80692
 
+       } else if ( ret == 0 ) {
80693
 
+               /* Perform implicit keep if script failed with a normal runtime error */
80694
 
+               if ( !sieve_result_implicit_keep(result) ) {
80695
 
+                       ret = SIEVE_EXEC_KEEP_FAILED;
80696
 
+               } else {
80697
 
+                       if ( keep != NULL ) *keep = TRUE;
80698
 
+               }
80699
 
+       }
80700
 
+       
80701
 
+       /* Cleanup */
80702
 
+       sieve_result_unref(&result);
80703
 
+
80704
 
+       return ret;
80705
 
+}
80706
 
+
80707
 
+/*
80708
 
+ * Multiscript support
80709
 
+ */
80710
 
80711
 
+struct sieve_multiscript {
80712
 
+       struct sieve_result *result;
80713
 
+       const struct sieve_message_data *msgdata;
80714
 
+       const struct sieve_script_env *scriptenv;
80715
 
+
80716
 
+       int status;
80717
 
+       bool active;
80718
 
+       bool ended;
80719
 
+       bool keep;
80720
 
+
80721
 
+       struct ostream *teststream;
80722
 
+};
80723
 
80724
 
+struct sieve_multiscript *sieve_multiscript_start_execute
80725
 
+(const struct sieve_message_data *msgdata, const struct sieve_script_env *senv)
80726
 
+{
80727
 
+       pool_t pool;
80728
 
+       struct sieve_result *result;
80729
 
+       struct sieve_multiscript *mscript;
80730
 
+       
80731
 
+       result = sieve_result_create(msgdata, senv, NULL);
80732
 
+       pool = sieve_result_pool(result);
80733
 
+       
80734
 
+       sieve_result_set_keep_action(result, NULL);
80735
 
+       
80736
 
+       mscript = p_new(pool, struct sieve_multiscript, 1);
80737
 
+       mscript->result = result;
80738
 
+       mscript->msgdata = msgdata;
80739
 
+       mscript->scriptenv = senv;
80740
 
+       mscript->status = SIEVE_EXEC_OK;
80741
 
+       mscript->active = TRUE;
80742
 
+       mscript->keep = TRUE;
80743
 
+       
80744
 
+       return mscript;
80745
 
+}
80746
 
+
80747
 
+struct sieve_multiscript *sieve_multiscript_start_test
80748
 
+(const struct sieve_message_data *msgdata, const struct sieve_script_env *senv,
80749
 
+       struct ostream *stream)
80750
 
+{
80751
 
+       struct sieve_multiscript *mscript = 
80752
 
+               sieve_multiscript_start_execute(msgdata, senv);
80753
 
+       
80754
 
+       mscript->teststream = stream;
80755
 
+
80756
 
+       return mscript;
80757
 
+}
80758
 
+
80759
 
+static void sieve_multiscript_test
80760
 
+(struct sieve_multiscript *mscript, struct sieve_error_handler *ehandler,
80761
 
+       bool *keep)
80762
 
+{                                              
80763
 
+       sieve_result_set_error_handler(mscript->result, ehandler);
80764
 
+
80765
 
+       if ( mscript->status > 0 ) {
80766
 
+               mscript->status = sieve_result_print
80767
 
+                       (mscript->result, mscript->scriptenv, mscript->teststream, keep);
80768
 
+       } else {
80769
 
+               if ( keep != NULL ) *keep = TRUE;
80770
 
+       }
80771
 
+               
80772
 
+       mscript->active = ( mscript->active && *keep );
80773
 
+
80774
 
+       sieve_result_mark_executed(mscript->result);
80775
 
+}
80776
 
+
80777
 
+static void sieve_multiscript_execute
80778
 
+(struct sieve_multiscript *mscript, struct sieve_error_handler *ehandler,
80779
 
+       bool *keep)
80780
 
+{
80781
 
+       sieve_result_set_error_handler(mscript->result, ehandler);
80782
 
+
80783
 
+       if ( mscript->status > 0 ) {
80784
 
+               mscript->status = sieve_result_execute(mscript->result, keep);
80785
 
+       } else {
80786
 
+               if ( !sieve_result_implicit_keep(mscript->result) )
80787
 
+                       mscript->status = SIEVE_EXEC_KEEP_FAILED;
80788
 
+               else
80789
 
+                       if ( keep != NULL ) *keep = TRUE;                       
80790
 
+       }
80791
 
+       
80792
 
+       mscript->active = ( mscript->active && *keep );
80793
 
+}
80794
 
+
80795
 
+bool sieve_multiscript_run
80796
 
+(struct sieve_multiscript *mscript, struct sieve_binary *sbin,
80797
 
+       struct sieve_error_handler *ehandler, bool final)
80798
 
+{
80799
 
+       if ( !mscript->active ) return FALSE;
80800
 
+       
80801
 
+       if ( final )
80802
 
+               sieve_result_set_keep_action(mscript->result, &act_store);
80803
 
+       
80804
 
+       /* Run the script */
80805
 
+       mscript->status = sieve_run(sbin, &mscript->result, mscript->msgdata, 
80806
 
+               mscript->scriptenv, ehandler);
80807
 
+
80808
 
+       if ( mscript->status >= 0 ) {
80809
 
+               mscript->keep = FALSE;
80810
 
+
80811
 
+               if ( mscript->teststream != NULL ) 
80812
 
+                       sieve_multiscript_test(mscript, ehandler, &mscript->keep);
80813
 
+               else
80814
 
+                       sieve_multiscript_execute(mscript, ehandler, &mscript->keep);
80815
 
+
80816
 
+               if ( final ) mscript->active = FALSE;
80817
 
+       }       
80818
 
+
80819
 
+       if ( mscript->status <= 0 )
80820
 
+               return FALSE;
80821
 
+
80822
 
+       return mscript->active;
80823
 
+}
80824
 
+
80825
 
+int sieve_multiscript_status(struct sieve_multiscript *mscript)
80826
 
+{
80827
 
+       return mscript->status;
80828
 
+}
80829
 
+
80830
 
+int sieve_multiscript_finish(struct sieve_multiscript **mscript, 
80831
 
+       struct sieve_error_handler *ehandler, bool *keep)
80832
 
+{
80833
 
+       struct sieve_result *result = (*mscript)->result;
80834
 
+       int ret = (*mscript)->status;
80835
 
+
80836
 
+       if ( ehandler != NULL )
80837
 
+               sieve_result_set_error_handler((*mscript)->result, ehandler);   
80838
 
+
80839
 
+       if ( (*mscript)->active ) {
80840
 
+               ret = SIEVE_EXEC_FAILURE;
80841
 
+
80842
 
+               if ( (*mscript)->teststream ) {
80843
 
+                       (*mscript)->keep = TRUE;
80844
 
+               } else {
80845
 
+                       if ( !sieve_result_implicit_keep((*mscript)->result) )
80846
 
+                               ret = SIEVE_EXEC_KEEP_FAILED;
80847
 
+                       else
80848
 
+                               (*mscript)->keep = TRUE;
80849
 
+               }
80850
 
+       }
80851
 
+
80852
 
+       if ( keep != NULL ) *keep = (*mscript)->keep;
80853
 
+       
80854
 
+       /* Cleanup */
80855
 
+       sieve_result_unref(&result);
80856
 
+       *mscript = NULL;
80857
 
+       
80858
 
+       return ret;
80859
 
+}
80860
 
+
80861
 
+/*
80862
 
+ * Script directory
80863
 
+ */
80864
 
+
80865
 
+struct sieve_directory {
80866
 
+               DIR *dirp;
80867
 
+
80868
 
+               const char *path;
80869
 
+};
80870
 
+
80871
 
+struct sieve_directory *sieve_directory_open(const char *path)
80872
 
+{ 
80873
 
+       struct sieve_directory *sdir = NULL;
80874
 
+       DIR *dirp;
80875
 
+       struct stat st;
80876
 
+
80877
 
+       /* Specified path can either be a regular file or a directory */
80878
 
+       if ( stat(path, &st) != 0 )
80879
 
+               return NULL;
80880
 
+
80881
 
+       if ( S_ISDIR(st.st_mode) ) {
80882
 
+               
80883
 
+               /* Open the directory */
80884
 
+               if ( (dirp = opendir(path)) == NULL ) {
80885
 
+                       sieve_sys_error("opendir(%s) failed: %m", path);
80886
 
+                       return NULL;            
80887
 
+               }
80888
 
+       
80889
 
+               /* Create object */
80890
 
+               sdir = t_new(struct sieve_directory, 1);
80891
 
+               sdir->path = path;
80892
 
+               sdir->dirp = dirp;
80893
 
+       } else {
80894
 
+               sdir = t_new(struct sieve_directory, 1);
80895
 
+               sdir->path = path;
80896
 
+               sdir->dirp = NULL;
80897
 
+       }
80898
 
+
80899
 
+       return sdir;
80900
 
+}
80901
 
+
80902
 
+const char *sieve_directory_get_scriptfile(struct sieve_directory *sdir)
80903
 
+{
80904
 
+       const char *script = NULL;
80905
 
+       struct dirent *dp;
80906
 
+       
80907
 
+       if ( sdir->dirp != NULL ) {
80908
 
+               while ( script == NULL ) {
80909
 
+                       const char *file;
80910
 
+                       struct stat st;
80911
 
+
80912
 
+                       errno = 0;
80913
 
+                       if ( (dp = readdir(sdir->dirp)) == NULL ) {
80914
 
+                               if ( errno != 0 ) { 
80915
 
+                                       sieve_sys_error("readdir(%s) failed: %m", sdir->path);
80916
 
+                                       continue;
80917
 
+                               } else 
80918
 
+                                       return NULL;
80919
 
+                       }
80920
 
+
80921
 
+                       if ( !sieve_script_file_has_extension(dp->d_name) )
80922
 
+                               continue;
80923
 
+
80924
 
+                       if ( sdir->path[strlen(sdir->path)-1] == '/' )
80925
 
+                               file = t_strconcat(sdir->path, dp->d_name, NULL);
80926
 
+                       else
80927
 
+                               file = t_strconcat(sdir->path, "/", dp->d_name, NULL);
80928
 
+
80929
 
+                       if ( stat(file, &st) != 0 || !S_ISREG(st.st_mode) )
80930
 
+                               continue;
80931
 
+
80932
 
+                       script = file;
80933
 
+               }
80934
 
+       } else {
80935
 
+               script = sdir->path;
80936
 
+               sdir->path = NULL;              
80937
 
+       }
80938
 
+                                                       
80939
 
+       return script;
80940
 
+}
80941
 
+
80942
 
+void sieve_directory_close(struct sieve_directory **sdir)
80943
 
+{
80944
 
+       /* Close the directory */
80945
 
+       if ( (*sdir)->dirp != NULL && closedir((*sdir)->dirp) < 0 ) 
80946
 
+               sieve_sys_error("closedir(%s) failed: %m", (*sdir)->path);
80947
 
+               
80948
 
+       *sdir = NULL;
80949
 
+}
80950
 
+
80951
 
+
80952
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-code.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-code.c
80953
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-code.c   1970-01-01 01:00:00.000000000 +0100
80954
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-code.c    2009-08-05 13:08:32.000000000 +0200
80955
 
@@ -0,0 +1,1026 @@
80956
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
80957
 
+ */
80958
 
80959
 
+#include "lib.h"
80960
 
+#include "str.h"
80961
 
+#include "str-sanitize.h"
80962
 
+
80963
 
+#include "sieve-common.h"
80964
 
+#include "sieve-limits.h"
80965
 
+#include "sieve-extensions.h"
80966
 
+#include "sieve-actions.h"
80967
 
+#include "sieve-binary.h"
80968
 
+#include "sieve-generator.h"
80969
 
+#include "sieve-interpreter.h"
80970
 
+#include "sieve-dump.h"
80971
 
+
80972
 
+#include "sieve-code.h"
80973
 
+
80974
 
+#include <stdio.h>
80975
 
+
80976
 
+/* 
80977
 
+ * Coded stringlist
80978
 
+ */
80979
 
+
80980
 
+struct sieve_coded_stringlist {
80981
 
+       const struct sieve_runtime_env *runenv;
80982
 
+       sieve_size_t start_address;
80983
 
+       sieve_size_t end_address;
80984
 
+       sieve_size_t current_offset;
80985
 
+       unsigned int length;
80986
 
+       unsigned int index;
80987
 
+};
80988
 
+
80989
 
+static struct sieve_coded_stringlist *sieve_coded_stringlist_create
80990
 
+(const struct sieve_runtime_env *renv, 
80991
 
+        sieve_size_t start_address, unsigned int length, sieve_size_t end)
80992
 
+{
80993
 
+       struct sieve_coded_stringlist *strlist;
80994
 
+       
80995
 
+       if ( end > sieve_binary_get_code_size(renv->sbin) ) 
80996
 
+               return NULL;
80997
 
+    
80998
 
+       strlist = t_new(struct sieve_coded_stringlist, 1);
80999
 
+       strlist->runenv = renv;
81000
 
+       strlist->start_address = start_address;
81001
 
+       strlist->current_offset = start_address;
81002
 
+       strlist->end_address = end;
81003
 
+       strlist->length = length;
81004
 
+       strlist->index = 0;
81005
 
+  
81006
 
+       return strlist;
81007
 
+}
81008
 
+
81009
 
+bool sieve_coded_stringlist_next_item
81010
 
+(struct sieve_coded_stringlist *strlist, string_t **str_r) 
81011
 
+{
81012
 
+       sieve_size_t address;
81013
 
+       *str_r = NULL;
81014
 
+  
81015
 
+       if ( strlist->index >= strlist->length ) 
81016
 
+               return TRUE;
81017
 
+       else {
81018
 
+               address = strlist->current_offset;
81019
 
+       
81020
 
+               if ( sieve_opr_string_read(strlist->runenv, &address, str_r) ) {
81021
 
+                       strlist->index++;
81022
 
+                       strlist->current_offset = address;
81023
 
+                       return TRUE;
81024
 
+               }
81025
 
+       }  
81026
 
+  
81027
 
+       return FALSE;
81028
 
+}
81029
 
+
81030
 
+void sieve_coded_stringlist_reset(struct sieve_coded_stringlist *strlist) 
81031
 
+{  
81032
 
+       strlist->current_offset = strlist->start_address;
81033
 
+       strlist->index = 0;
81034
 
+}
81035
 
+
81036
 
+unsigned int sieve_coded_stringlist_get_length
81037
 
+(struct sieve_coded_stringlist *strlist)
81038
 
+{
81039
 
+       return strlist->length;
81040
 
+}
81041
 
+
81042
 
+sieve_size_t sieve_coded_stringlist_get_end_address
81043
 
+(struct sieve_coded_stringlist *strlist)
81044
 
+{
81045
 
+       return strlist->end_address;
81046
 
+}
81047
 
+
81048
 
+sieve_size_t sieve_coded_stringlist_get_current_offset
81049
 
+(struct sieve_coded_stringlist *strlist)
81050
 
+{
81051
 
+       return strlist->current_offset;
81052
 
+}
81053
 
+
81054
 
+bool sieve_coded_stringlist_read_all
81055
 
+(struct sieve_coded_stringlist *strlist, pool_t pool,
81056
 
+       const char * const **list_r)
81057
 
+{
81058
 
+       bool result = FALSE;
81059
 
+       ARRAY_DEFINE(items, const char *);
81060
 
+       string_t *item;
81061
 
+       
81062
 
+       sieve_coded_stringlist_reset(strlist);
81063
 
+       
81064
 
+       p_array_init(&items, pool, 4);
81065
 
+       
81066
 
+       item = NULL;
81067
 
+       while ( (result=sieve_coded_stringlist_next_item(strlist, &item)) && 
81068
 
+               item != NULL ) {
81069
 
+               const char *stritem = p_strdup(pool, str_c(item));
81070
 
+               
81071
 
+               array_append(&items, &stritem, 1);
81072
 
+       }
81073
 
+       
81074
 
+       (void)array_append_space(&items);
81075
 
+       *list_r = array_idx(&items, 0);
81076
 
+
81077
 
+       return result;
81078
 
+}
81079
 
+
81080
 
+static bool sieve_coded_stringlist_dump
81081
 
+(const struct sieve_dumptime_env *denv, sieve_size_t *address, 
81082
 
+       unsigned int length, sieve_size_t end, const char *field_name)
81083
 
+{
81084
 
+       unsigned int i;
81085
 
+       
81086
 
+       if ( end > sieve_binary_get_code_size(denv->sbin) ) 
81087
 
+               return FALSE;
81088
 
+    
81089
 
+       if ( field_name != NULL )
81090
 
+               sieve_code_dumpf(denv, "%s: STRLIST [%u] (end: %08llx)", 
81091
 
+                       field_name, length, (unsigned long long) end);
81092
 
+       else
81093
 
+               sieve_code_dumpf(denv, "STRLIST [%u] (end: %08llx)", 
81094
 
+                       length, (unsigned long long) end);
81095
 
+       
81096
 
+       sieve_code_descend(denv);
81097
 
+       
81098
 
+       for ( i = 0; i < length; i++ ) {
81099
 
+               bool success = TRUE;
81100
 
+
81101
 
+               T_BEGIN {               
81102
 
+                       success = sieve_opr_string_dump(denv, address, NULL);
81103
 
+               } T_END;
81104
 
+
81105
 
+               if ( !success || *address > end ) 
81106
 
+                       return FALSE;
81107
 
+       }
81108
 
+
81109
 
+       if ( *address != end ) return FALSE;
81110
 
+       
81111
 
+       sieve_code_ascend(denv);
81112
 
+               
81113
 
+       return TRUE;
81114
 
+}
81115
 
+       
81116
 
+/*
81117
 
+ * Source line coding
81118
 
+ */
81119
 
+
81120
 
+void sieve_code_source_line_emit
81121
 
+(struct sieve_binary *sbin, unsigned int source_line)
81122
 
+{
81123
 
+    (void)sieve_binary_emit_unsigned(sbin, source_line);
81124
 
+}
81125
 
+
81126
 
+bool sieve_code_source_line_dump
81127
 
+(const struct sieve_dumptime_env *denv, sieve_size_t *address)
81128
 
+{
81129
 
+    unsigned int number = 0;
81130
 
+
81131
 
+       sieve_code_mark(denv);
81132
 
+    if (sieve_binary_read_unsigned(denv->sbin, address, &number) ) {
81133
 
+        sieve_code_dumpf(denv, "(source line: %lu)", (unsigned long) number);
81134
 
+
81135
 
+        return TRUE;
81136
 
+    }
81137
 
+
81138
 
+    return FALSE;
81139
 
+}
81140
 
+
81141
 
+bool sieve_code_source_line_read
81142
 
+(const struct sieve_runtime_env *renv, sieve_size_t *address,
81143
 
+       unsigned int *source_line_r)
81144
 
+{
81145
 
+       return sieve_binary_read_unsigned(renv->sbin, address, source_line_r);
81146
 
+}
81147
 
+
81148
 
+/*
81149
 
+ * Core operands
81150
 
+ */
81151
 
81152
 
+extern const struct sieve_operand comparator_operand;
81153
 
+extern const struct sieve_operand match_type_operand;
81154
 
+extern const struct sieve_operand address_part_operand;
81155
 
+
81156
 
+const struct sieve_operand *sieve_operands[] = {
81157
 
+       &omitted_operand, /* SIEVE_OPERAND_OPTIONAL */
81158
 
+       &number_operand,
81159
 
+       &string_operand,
81160
 
+       &stringlist_operand,
81161
 
+       &comparator_operand,
81162
 
+       &match_type_operand,
81163
 
+       &address_part_operand,
81164
 
+       &catenated_string_operand
81165
 
+}; 
81166
 
+
81167
 
+const unsigned int sieve_operand_count =
81168
 
+       N_ELEMENTS(sieve_operands);
81169
 
+
81170
 
+/* 
81171
 
+ * Operand functions 
81172
 
+ */
81173
 
+
81174
 
+sieve_size_t sieve_operand_emit_code
81175
 
+(struct sieve_binary *sbin, const struct sieve_operand *opr)
81176
 
+{
81177
 
+       sieve_size_t address;
81178
 
+
81179
 
+       if ( opr->extension != NULL ) {
81180
 
+               address = sieve_binary_emit_extension
81181
 
+                       (sbin, opr->extension, sieve_operand_count);
81182
 
+       
81183
 
+               sieve_binary_emit_extension_object
81184
 
+                       (sbin, &opr->extension->operands, opr->code);
81185
 
+
81186
 
+               return address;
81187
 
+       }
81188
 
+
81189
 
+       return  sieve_binary_emit_byte(sbin, opr->code);
81190
 
+}
81191
 
+
81192
 
+const struct sieve_operand *sieve_operand_read
81193
 
+(struct sieve_binary *sbin, sieve_size_t *address) 
81194
 
+{
81195
 
+       const struct sieve_extension *ext;
81196
 
+       unsigned int code = sieve_operand_count;
81197
 
+
81198
 
+       if ( !sieve_binary_read_extension(sbin, address, &code, &ext) )
81199
 
+               return NULL;
81200
 
+
81201
 
+       if ( !ext )
81202
 
+               return code < sieve_operand_count ? sieve_operands[code] : NULL;
81203
 
+
81204
 
+       return (const struct sieve_operand *) sieve_binary_read_extension_object
81205
 
+               (sbin, address, &ext->operands);
81206
 
+}
81207
 
+
81208
 
+bool sieve_operand_optional_present
81209
 
+(struct sieve_binary *sbin, sieve_size_t *address)
81210
 
+{      
81211
 
+       sieve_size_t tmp_addr = *address;
81212
 
+       unsigned int op = -1;
81213
 
+       
81214
 
+       if ( sieve_binary_read_byte(sbin, &tmp_addr, &op) && 
81215
 
+               (op == SIEVE_OPERAND_OPTIONAL) ) {
81216
 
+               *address = tmp_addr;
81217
 
+               return TRUE;
81218
 
+       }
81219
 
+       
81220
 
+       return FALSE;
81221
 
+}
81222
 
+
81223
 
+bool sieve_operand_optional_read
81224
 
+(struct sieve_binary *sbin, sieve_size_t *address, signed int *id_code)
81225
 
+{
81226
 
+       if ( sieve_binary_read_code(sbin, address, id_code) ) 
81227
 
+               return TRUE;
81228
 
+       
81229
 
+       *id_code = 0;
81230
 
+
81231
 
+       return FALSE;
81232
 
+}
81233
 
+
81234
 
+/* 
81235
 
+ * Operand definitions
81236
 
+ */
81237
 
+
81238
 
+/* Omitted */
81239
 
+
81240
 
+const struct sieve_operand_class omitted_class =
81241
 
+       { "OMITTED" };
81242
 
+
81243
 
+const struct sieve_operand omitted_operand = {
81244
 
+       "@OMITTED",
81245
 
+       NULL, SIEVE_OPERAND_OPTIONAL,   
81246
 
+       &omitted_class, NULL
81247
 
+};
81248
 
81249
 
+/* Number */
81250
 
+
81251
 
+static bool opr_number_dump
81252
 
+       (const struct sieve_dumptime_env *denv, sieve_size_t *address,
81253
 
+               const char *field_name);
81254
 
+static bool opr_number_read
81255
 
+       (const struct sieve_runtime_env *renv, sieve_size_t *address, 
81256
 
+               sieve_number_t *number_r);
81257
 
+
81258
 
+const struct sieve_opr_number_interface number_interface = { 
81259
 
+       opr_number_dump, 
81260
 
+       opr_number_read
81261
 
+};
81262
 
+
81263
 
+const struct sieve_operand_class number_class = 
81264
 
+       { "number" };
81265
 
+       
81266
 
+const struct sieve_operand number_operand = { 
81267
 
+       "@number", 
81268
 
+       NULL, SIEVE_OPERAND_NUMBER,
81269
 
+       &number_class,
81270
 
+       &number_interface 
81271
 
+};
81272
 
+
81273
 
+/* String */
81274
 
+
81275
 
+static bool opr_string_dump
81276
 
+       (const struct sieve_dumptime_env *denv, sieve_size_t *address,
81277
 
+               const char *field_name);
81278
 
+static bool opr_string_read
81279
 
+       (const struct sieve_runtime_env *renv, sieve_size_t *address, string_t **str_r);
81280
 
+
81281
 
+const struct sieve_opr_string_interface string_interface ={ 
81282
 
+       opr_string_dump,
81283
 
+       opr_string_read
81284
 
+};
81285
 
+       
81286
 
+const struct sieve_operand_class string_class = 
81287
 
+       { "string" };
81288
 
+       
81289
 
+const struct sieve_operand string_operand = { 
81290
 
+       "@string", 
81291
 
+       NULL, SIEVE_OPERAND_STRING,
81292
 
+       &string_class,
81293
 
+       &string_interface
81294
 
+};     
81295
 
+
81296
 
+/* String List */
81297
 
+
81298
 
+static bool opr_stringlist_dump
81299
 
+       (const struct sieve_dumptime_env *denv, sieve_size_t *address,
81300
 
+               const char *field_name);
81301
 
+static struct sieve_coded_stringlist *opr_stringlist_read
81302
 
+       (const struct sieve_runtime_env *renv, sieve_size_t *address);
81303
 
+
81304
 
+const struct sieve_opr_stringlist_interface stringlist_interface = { 
81305
 
+       opr_stringlist_dump, 
81306
 
+       opr_stringlist_read
81307
 
+};
81308
 
+
81309
 
+const struct sieve_operand_class stringlist_class = 
81310
 
+       { "string-list" };
81311
 
+
81312
 
+const struct sieve_operand stringlist_operand =        { 
81313
 
+       "@string-list", 
81314
 
+       NULL, SIEVE_OPERAND_STRING_LIST,
81315
 
+       &stringlist_class, 
81316
 
+       &stringlist_interface
81317
 
+};
81318
 
+
81319
 
+/* Catenated String */
81320
 
+
81321
 
+static bool opr_catenated_string_read
81322
 
+       (const struct sieve_runtime_env *renv, sieve_size_t *address, string_t **str);
81323
 
+static bool opr_catenated_string_dump
81324
 
+       (const struct sieve_dumptime_env *denv, sieve_size_t *address,
81325
 
+               const char *field_name);
81326
 
+
81327
 
+const struct sieve_opr_string_interface catenated_string_interface = { 
81328
 
+       opr_catenated_string_dump,
81329
 
+       opr_catenated_string_read
81330
 
+};
81331
 
+               
81332
 
+const struct sieve_operand catenated_string_operand = { 
81333
 
+       "@catenated-string", 
81334
 
+       NULL, SIEVE_OPERAND_CATENATED_STRING,
81335
 
+       &string_class,
81336
 
+       &catenated_string_interface
81337
 
+};     
81338
 
+       
81339
 
+/* 
81340
 
+ * Operand implementations 
81341
 
+ */
81342
 
+
81343
 
+/* Omitted */
81344
 
+
81345
 
+void sieve_opr_omitted_emit(struct sieve_binary *sbin)
81346
 
+{
81347
 
+    (void) sieve_operand_emit_code(sbin, &omitted_operand);
81348
 
+}
81349
 
81350
 
+/* Number */
81351
 
+
81352
 
+void sieve_opr_number_emit(struct sieve_binary *sbin, sieve_number_t number) 
81353
 
+{
81354
 
+       (void) sieve_operand_emit_code(sbin, &number_operand);
81355
 
+       (void) sieve_binary_emit_integer(sbin, number);
81356
 
+}
81357
 
+
81358
 
+bool sieve_opr_number_dump_data
81359
 
+(const struct sieve_dumptime_env *denv, const struct sieve_operand *operand,
81360
 
+       sieve_size_t *address, const char *field_name) 
81361
 
+{
81362
 
+       const struct sieve_opr_number_interface *intf;
81363
 
+
81364
 
+       if ( !sieve_operand_is_number(operand) ) 
81365
 
+               return FALSE;
81366
 
+               
81367
 
+       intf = (const struct sieve_opr_number_interface *) operand->interface; 
81368
 
+       
81369
 
+       if ( intf->dump == NULL )
81370
 
+               return FALSE;
81371
 
+
81372
 
+       return intf->dump(denv, address, field_name);  
81373
 
+}
81374
 
+
81375
 
+bool sieve_opr_number_dump
81376
 
+(const struct sieve_dumptime_env *denv, sieve_size_t *address,
81377
 
+       const char *field_name) 
81378
 
+{
81379
 
+       const struct sieve_operand *operand;
81380
 
+       
81381
 
+       sieve_code_mark(denv);
81382
 
+       
81383
 
+       operand = sieve_operand_read(denv->sbin, address);
81384
 
+
81385
 
+       return sieve_opr_number_dump_data(denv, operand, address, field_name);
81386
 
+}
81387
 
+
81388
 
+bool sieve_opr_number_read_data
81389
 
+(const struct sieve_runtime_env *renv, const struct sieve_operand *operand,
81390
 
+       sieve_size_t *address, sieve_number_t *number_r)
81391
 
+{
81392
 
+       const struct sieve_opr_number_interface *intf;
81393
 
+               
81394
 
+       if ( !sieve_operand_is_number(operand) ) 
81395
 
+               return FALSE;   
81396
 
+               
81397
 
+       intf = (const struct sieve_opr_number_interface *) operand->interface; 
81398
 
+       
81399
 
+       if ( intf->read == NULL )
81400
 
+               return FALSE;
81401
 
+
81402
 
+       return intf->read(renv, address, number_r);  
81403
 
+}
81404
 
+
81405
 
+bool sieve_opr_number_read
81406
 
+(const struct sieve_runtime_env *renv, sieve_size_t *address, 
81407
 
+       sieve_number_t *number_r)
81408
 
+{
81409
 
+       const struct sieve_operand *operand = sieve_operand_read(renv->sbin, address);
81410
 
+               
81411
 
+       return sieve_opr_number_read_data(renv, operand, address, number_r);
81412
 
+}
81413
 
+
81414
 
+static bool opr_number_dump
81415
 
+(const struct sieve_dumptime_env *denv, sieve_size_t *address,
81416
 
+       const char *field_name) 
81417
 
+{
81418
 
+       sieve_number_t number = 0;
81419
 
+       
81420
 
+       if (sieve_binary_read_integer(denv->sbin, address, &number) ) {
81421
 
+               if ( field_name != NULL ) 
81422
 
+                       sieve_code_dumpf(denv, "%s: NUM %llu", field_name, (unsigned long long) number);
81423
 
+               else
81424
 
+                       sieve_code_dumpf(denv, "NUM %llu", (unsigned long long) number);
81425
 
+
81426
 
+               return TRUE;
81427
 
+       }
81428
 
+       
81429
 
+       return FALSE;
81430
 
+}
81431
 
+
81432
 
+static bool opr_number_read
81433
 
+(const struct sieve_runtime_env *renv, sieve_size_t *address, 
81434
 
+       sieve_number_t *number_r)
81435
 
+{ 
81436
 
+       return sieve_binary_read_integer(renv->sbin, address, number_r);
81437
 
+}
81438
 
+
81439
 
+/* String */
81440
 
+
81441
 
+void sieve_opr_string_emit(struct sieve_binary *sbin, string_t *str)
81442
 
+{
81443
 
+       (void) sieve_operand_emit_code(sbin, &string_operand);
81444
 
+       (void) sieve_binary_emit_string(sbin, str);
81445
 
+}
81446
 
+
81447
 
+bool sieve_opr_string_dump_data
81448
 
+(const struct sieve_dumptime_env *denv, const struct sieve_operand *operand,
81449
 
+       sieve_size_t *address, const char *field_name) 
81450
 
+{
81451
 
+       const struct sieve_opr_string_interface *intf;
81452
 
+       
81453
 
+       if ( !sieve_operand_is_string(operand) ) {
81454
 
+               sieve_code_dumpf(denv, "ERROR: INVALID STRING OPERAND %s", operand->name);
81455
 
+               return FALSE;
81456
 
+       }
81457
 
+               
81458
 
+       intf = (const struct sieve_opr_string_interface *) operand->interface; 
81459
 
+       
81460
 
+       if ( intf->dump == NULL ) {
81461
 
+               sieve_code_dumpf(denv, "ERROR: DUMP STRING OPERAND");
81462
 
+               return FALSE;
81463
 
+       }
81464
 
+
81465
 
+       return intf->dump(denv, address, field_name);  
81466
 
+}
81467
 
+
81468
 
+bool sieve_opr_string_dump
81469
 
+(const struct sieve_dumptime_env *denv, sieve_size_t *address,
81470
 
+       const char *field_name) 
81471
 
+{
81472
 
+       const struct sieve_operand *operand;
81473
 
+       
81474
 
+       sieve_code_mark(denv);
81475
 
+       operand = sieve_operand_read(denv->sbin, address);
81476
 
+       
81477
 
+       if ( operand == NULL ) {
81478
 
+               sieve_code_dumpf(denv, "ERROR: INVALID OPERAND");
81479
 
+               return FALSE;
81480
 
+       }
81481
 
+
81482
 
+       return sieve_opr_string_dump_data(denv, operand, address, field_name);
81483
 
+}
81484
 
+
81485
 
+bool sieve_opr_string_dump_ex
81486
 
+(const struct sieve_dumptime_env *denv, sieve_size_t *address, 
81487
 
+       const char *field_name, bool *literal_r)
81488
 
+{
81489
 
+       const struct sieve_operand *operand;
81490
 
+       
81491
 
+       sieve_code_mark(denv);
81492
 
+       operand = sieve_operand_read(denv->sbin, address);
81493
 
+
81494
 
+       *literal_r = ( operand == &string_operand );    
81495
 
+
81496
 
+       return sieve_opr_string_dump_data(denv, operand, address, field_name);
81497
 
+} 
81498
 
+
81499
 
+bool sieve_opr_string_read_data
81500
 
+(const struct sieve_runtime_env *renv, const struct sieve_operand *operand,
81501
 
+       sieve_size_t *address, string_t **str_r)
81502
 
+{
81503
 
+       const struct sieve_opr_string_interface *intf;
81504
 
+       
81505
 
+       if ( operand == NULL || operand->class != &string_class ) 
81506
 
+               return FALSE;
81507
 
+               
81508
 
+       intf = (const struct sieve_opr_string_interface *) operand->interface; 
81509
 
+       
81510
 
+       if ( intf->read == NULL )
81511
 
+               return FALSE;
81512
 
+
81513
 
+       return intf->read(renv, address, str_r);  
81514
 
+}
81515
 
+
81516
 
+bool sieve_opr_string_read
81517
 
+(const struct sieve_runtime_env *renv, sieve_size_t *address, string_t **str_r)
81518
 
+{
81519
 
+       const struct sieve_operand *operand = sieve_operand_read(renv->sbin, address);
81520
 
+
81521
 
+       return sieve_opr_string_read_data(renv, operand, address, str_r);
81522
 
+}
81523
 
+
81524
 
+bool sieve_opr_string_read_ex
81525
 
+(const struct sieve_runtime_env *renv, sieve_size_t *address, string_t **str_r,
81526
 
+       bool *literal_r)
81527
 
+{
81528
 
+       const struct sieve_operand *operand = sieve_operand_read(renv->sbin, address);
81529
 
+
81530
 
+       *literal_r = ( operand == &string_operand );
81531
 
+
81532
 
+       return sieve_opr_string_read_data(renv, operand, address, str_r);
81533
 
+}
81534
 
+
81535
 
+static void _dump_string
81536
 
+(const struct sieve_dumptime_env *denv, string_t *str, 
81537
 
+       const char *field_name) 
81538
 
+{
81539
 
+       if ( str_len(str) > 80 ) {
81540
 
+               if ( field_name != NULL ) 
81541
 
+                       sieve_code_dumpf(denv, "%s: STR[%ld] \"%s", 
81542
 
+                               field_name, (long) str_len(str), str_sanitize(str_c(str), 80));
81543
 
+               else
81544
 
+                       sieve_code_dumpf(denv, "STR[%ld] \"%s", 
81545
 
+                               (long) str_len(str), str_sanitize(str_c(str), 80));
81546
 
+       } else {
81547
 
+               if ( field_name != NULL )
81548
 
+                       sieve_code_dumpf(denv, "%s: STR[%ld] \"%s\"", 
81549
 
+                               field_name, (long) str_len(str), str_sanitize(str_c(str), 80));         
81550
 
+               else
81551
 
+                       sieve_code_dumpf(denv, "STR[%ld] \"%s\"", 
81552
 
+                               (long) str_len(str), str_sanitize(str_c(str), 80));             
81553
 
+       }
81554
 
+}
81555
 
+
81556
 
+bool opr_string_dump
81557
 
+(const struct sieve_dumptime_env *denv, sieve_size_t *address,
81558
 
+       const char *field_name) 
81559
 
+{
81560
 
+       string_t *str; 
81561
 
+       
81562
 
+       if ( sieve_binary_read_string(denv->sbin, address, &str) ) {
81563
 
+               _dump_string(denv, str, field_name);            
81564
 
+               
81565
 
+               return TRUE;
81566
 
+       }
81567
 
+  
81568
 
+       return FALSE;
81569
 
+}
81570
 
+
81571
 
+static bool opr_string_read
81572
 
+(const struct sieve_runtime_env *renv, sieve_size_t *address, string_t **str_r)
81573
 
+{      
81574
 
+       return sieve_binary_read_string(renv->sbin, address, str_r);
81575
 
+}
81576
 
+
81577
 
+/* String list */
81578
 
+
81579
 
+void sieve_opr_stringlist_emit_start
81580
 
+       (struct sieve_binary *sbin, unsigned int listlen, void **context)
81581
 
+{
81582
 
+       sieve_size_t *end_offset = t_new(sieve_size_t, 1);
81583
 
+
81584
 
+       /* Emit byte identifying the type of operand */   
81585
 
+       (void) sieve_operand_emit_code(sbin, &stringlist_operand);
81586
 
+  
81587
 
+       /* Give the interpreter an easy way to skip over this string list */
81588
 
+       *end_offset = sieve_binary_emit_offset(sbin, 0);
81589
 
+       *context = (void *) end_offset;
81590
 
+
81591
 
+       /* Emit the length of the list */
81592
 
+       (void) sieve_binary_emit_unsigned(sbin, listlen);
81593
 
+}
81594
 
+
81595
 
+void sieve_opr_stringlist_emit_item
81596
 
+(struct sieve_binary *sbin, void *context ATTR_UNUSED, string_t *item)
81597
 
+{
81598
 
+       (void) sieve_opr_string_emit(sbin, item);
81599
 
+}
81600
 
+
81601
 
+void sieve_opr_stringlist_emit_end
81602
 
+(struct sieve_binary *sbin, void *context)
81603
 
+{
81604
 
+       sieve_size_t *end_offset = (sieve_size_t *) context;
81605
 
+
81606
 
+       (void) sieve_binary_resolve_offset(sbin, *end_offset);
81607
 
+}
81608
 
+
81609
 
+bool sieve_opr_stringlist_dump_data
81610
 
+(const struct sieve_dumptime_env *denv, const struct sieve_operand *operand,
81611
 
+       sieve_size_t *address, const char *field_name) 
81612
 
+{
81613
 
+       if ( operand == NULL )
81614
 
+               return FALSE;
81615
 
+       
81616
 
+       if ( operand->class == &stringlist_class ) {
81617
 
+               const struct sieve_opr_stringlist_interface *intf =
81618
 
+                       (const struct sieve_opr_stringlist_interface *) operand->interface; 
81619
 
+               
81620
 
+               if ( intf->dump == NULL )
81621
 
+                       return FALSE;
81622
 
+
81623
 
+               return intf->dump(denv, address, field_name); 
81624
 
+       } else if ( operand->class == &string_class ) {
81625
 
+               const struct sieve_opr_string_interface *intf =
81626
 
+                       (const struct sieve_opr_string_interface *) operand->interface; 
81627
 
+       
81628
 
+               if ( intf->dump == NULL ) 
81629
 
+                       return FALSE;
81630
 
+
81631
 
+               return intf->dump(denv, address, field_name);  
81632
 
+       }
81633
 
+       
81634
 
+       return FALSE;
81635
 
+}
81636
 
+
81637
 
+bool sieve_opr_stringlist_dump
81638
 
+(const struct sieve_dumptime_env *denv, sieve_size_t *address,
81639
 
+       const char *field_name) 
81640
 
+{
81641
 
+       const struct sieve_operand *operand;
81642
 
+
81643
 
+       sieve_code_mark(denv);
81644
 
+       operand = sieve_operand_read(denv->sbin, address);
81645
 
+
81646
 
+       return sieve_opr_stringlist_dump_data(denv, operand, address, field_name);
81647
 
+}
81648
 
+
81649
 
+struct sieve_coded_stringlist *sieve_opr_stringlist_read_data
81650
 
+(const struct sieve_runtime_env *renv, const struct sieve_operand *operand,
81651
 
+       sieve_size_t op_address, sieve_size_t *address)
81652
 
+{
81653
 
+       if ( operand == NULL )
81654
 
+               return NULL;
81655
 
+               
81656
 
+       if ( operand->class == &stringlist_class ) {
81657
 
+               const struct sieve_opr_stringlist_interface *intf = 
81658
 
+                       (const struct sieve_opr_stringlist_interface *) operand->interface;
81659
 
+                       
81660
 
+               if ( intf->read == NULL ) 
81661
 
+                       return NULL;
81662
 
+
81663
 
+               return intf->read(renv, address);  
81664
 
+       } else if ( operand->class == &string_class ) {
81665
 
+               /* Special case, accept single string as string list as well. */
81666
 
+               const struct sieve_opr_string_interface *intf = 
81667
 
+                       (const struct sieve_opr_string_interface *) operand->interface;
81668
 
+                               
81669
 
+               if ( intf->read == NULL || !intf->read(renv, address, NULL) ) {
81670
 
+                       return NULL;
81671
 
+               }
81672
 
+               
81673
 
+               return sieve_coded_stringlist_create(renv, op_address, 1, *address); 
81674
 
+       }       
81675
 
+       
81676
 
+       return NULL;
81677
 
+}
81678
 
+
81679
 
+struct sieve_coded_stringlist *sieve_opr_stringlist_read
81680
 
+(const struct sieve_runtime_env *renv, sieve_size_t *address)
81681
 
+{
81682
 
+       sieve_size_t op_address = *address;
81683
 
+       const struct sieve_operand *operand = sieve_operand_read(renv->sbin, address);
81684
 
+       
81685
 
+       return sieve_opr_stringlist_read_data(renv, operand, op_address, address);
81686
 
+}
81687
 
+
81688
 
+static bool opr_stringlist_dump
81689
 
+(const struct sieve_dumptime_env *denv, sieve_size_t *address, 
81690
 
+       const char *field_name) 
81691
 
+{
81692
 
+       sieve_size_t pc = *address;
81693
 
+       sieve_size_t end; 
81694
 
+       unsigned int length = 0; 
81695
 
+       int end_offset;
81696
 
+
81697
 
+       if ( !sieve_binary_read_offset(denv->sbin, address, &end_offset) )
81698
 
+               return FALSE;
81699
 
+
81700
 
+       end = pc + end_offset;
81701
 
+
81702
 
+       if ( !sieve_binary_read_unsigned(denv->sbin, address, &length) ) 
81703
 
+               return FALSE;   
81704
 
+       
81705
 
+       return sieve_coded_stringlist_dump(denv, address, length, end, field_name); 
81706
 
+}
81707
 
+
81708
 
+static struct sieve_coded_stringlist *opr_stringlist_read
81709
 
+(const struct sieve_runtime_env *renv, sieve_size_t *address )
81710
 
+{
81711
 
+       struct sieve_coded_stringlist *strlist;
81712
 
+       sieve_size_t pc = *address;
81713
 
+       sieve_size_t end; 
81714
 
+       unsigned int length = 0;  
81715
 
+       int end_offset;
81716
 
+       
81717
 
+       if ( !sieve_binary_read_offset(renv->sbin, address, &end_offset) )
81718
 
+               return NULL;
81719
 
+
81720
 
+       end = pc + end_offset;
81721
 
+
81722
 
+       if ( !sieve_binary_read_unsigned(renv->sbin, address, &length) ) 
81723
 
+               return NULL;    
81724
 
+       
81725
 
+       strlist = sieve_coded_stringlist_create(renv, *address, (unsigned int) length, end); 
81726
 
+
81727
 
+       /* Skip over the string list for now */
81728
 
+       *address = end;
81729
 
+  
81730
 
+       return strlist;
81731
 
+}  
81732
 
+
81733
 
+/* Catenated String */
81734
 
+
81735
 
+void sieve_opr_catenated_string_emit
81736
 
+(struct sieve_binary *sbin, unsigned int elements) 
81737
 
+{
81738
 
+       (void) sieve_operand_emit_code(sbin, &catenated_string_operand);
81739
 
+       (void) sieve_binary_emit_unsigned(sbin, elements);
81740
 
+}
81741
 
+
81742
 
+static bool opr_catenated_string_dump
81743
 
+(const struct sieve_dumptime_env *denv, sieve_size_t *address,
81744
 
+       const char *field_name) 
81745
 
+{
81746
 
+       unsigned int elements = 0;
81747
 
+       unsigned int i;
81748
 
+       
81749
 
+       if (!sieve_binary_read_unsigned(denv->sbin, address, &elements) )
81750
 
+               return FALSE;
81751
 
+       
81752
 
+       if ( field_name != NULL ) 
81753
 
+               sieve_code_dumpf(denv, "%s: CAT-STR [%ld]:", 
81754
 
+                       field_name, (long) elements);
81755
 
+       else
81756
 
+               sieve_code_dumpf(denv, "CAT-STR [%ld]:", (long) elements);
81757
 
+
81758
 
+       sieve_code_descend(denv);
81759
 
+       for ( i = 0; i < (unsigned int) elements; i++ ) {
81760
 
+               if ( !sieve_opr_string_dump(denv, address, NULL) )
81761
 
+                       return FALSE;
81762
 
+       }
81763
 
+       sieve_code_ascend(denv);
81764
 
+       
81765
 
+       return TRUE;
81766
 
+}
81767
 
+
81768
 
+static bool opr_catenated_string_read
81769
 
+(const struct sieve_runtime_env *renv, sieve_size_t *address, string_t **str)
81770
 
+{ 
81771
 
+       unsigned int elements = 0;
81772
 
+       unsigned int i;
81773
 
+               
81774
 
+       if ( !sieve_binary_read_unsigned(renv->sbin, address, &elements) )
81775
 
+               return FALSE;
81776
 
+
81777
 
+       /* Parameter str can be NULL if we are requested to only skip and not 
81778
 
+        * actually read the argument.
81779
 
+        */
81780
 
+       if ( str == NULL ) {
81781
 
+               for ( i = 0; i < (unsigned int) elements; i++ ) {               
81782
 
+                       if ( !sieve_opr_string_read(renv, address, NULL) ) 
81783
 
+                               return FALSE;
81784
 
+               }
81785
 
+       } else {
81786
 
+               string_t *strelm;
81787
 
+               string_t **elm = &strelm;
81788
 
+
81789
 
+               *str = t_str_new(128);
81790
 
+               for ( i = 0; i < (unsigned int) elements; i++ ) {
81791
 
+               
81792
 
+                       if ( !sieve_opr_string_read(renv, address, elm) ) 
81793
 
+                               return FALSE;
81794
 
+               
81795
 
+                       if ( elm != NULL ) {
81796
 
+                               str_append_str(*str, strelm);
81797
 
+
81798
 
+                               if ( str_len(*str) > SIEVE_MAX_STRING_LEN ) {
81799
 
+                                       str_truncate(*str, SIEVE_MAX_STRING_LEN);
81800
 
+                                       elm = NULL;
81801
 
+                               }
81802
 
+                       }
81803
 
+               }
81804
 
+       }
81805
 
+
81806
 
+       return TRUE;
81807
 
+}
81808
 
+
81809
 
+/* 
81810
 
+ * Core operations
81811
 
+ */
81812
 
81813
 
+/* Forward declarations */
81814
 
+
81815
 
+static bool opc_jmp_dump
81816
 
+       (const struct sieve_operation *op, 
81817
 
+               const struct sieve_dumptime_env *denv, sieve_size_t *address);
81818
 
+
81819
 
+static int opc_jmp_execute
81820
 
+       (const struct sieve_operation *op, 
81821
 
+               const struct sieve_runtime_env *renv, sieve_size_t *address);
81822
 
+static int opc_jmptrue_execute
81823
 
+       (const struct sieve_operation *op, 
81824
 
+               const struct sieve_runtime_env *renv, sieve_size_t *address);
81825
 
+static int opc_jmpfalse_execute
81826
 
+       (const struct sieve_operation *op, 
81827
 
+               const struct sieve_runtime_env *renv, sieve_size_t *address);
81828
 
+
81829
 
+/* Operation objects defined in this file */
81830
 
+
81831
 
+const struct sieve_operation sieve_jmp_operation = { 
81832
 
+       "JMP",
81833
 
+       NULL,
81834
 
+       SIEVE_OPERATION_JMP,
81835
 
+       opc_jmp_dump, 
81836
 
+       opc_jmp_execute 
81837
 
+};
81838
 
+
81839
 
+const struct sieve_operation sieve_jmptrue_operation = { 
81840
 
+       "JMPTRUE",
81841
 
+       NULL,
81842
 
+       SIEVE_OPERATION_JMPTRUE,
81843
 
+       opc_jmp_dump, 
81844
 
+       opc_jmptrue_execute 
81845
 
+};
81846
 
+
81847
 
+const struct sieve_operation sieve_jmpfalse_operation = { 
81848
 
+       "JMPFALSE",
81849
 
+       NULL,
81850
 
+       SIEVE_OPERATION_JMPFALSE,
81851
 
+       opc_jmp_dump, 
81852
 
+       opc_jmpfalse_execute 
81853
 
+};
81854
 
+
81855
 
+/* Operation objects defined in other files */
81856
 
+       
81857
 
+extern const struct sieve_operation cmd_stop_operation;
81858
 
+extern const struct sieve_operation cmd_keep_operation;
81859
 
+extern const struct sieve_operation cmd_discard_operation;
81860
 
+extern const struct sieve_operation cmd_redirect_operation;
81861
 
+
81862
 
+extern const struct sieve_operation tst_address_operation;
81863
 
+extern const struct sieve_operation tst_header_operation;
81864
 
+extern const struct sieve_operation tst_exists_operation;
81865
 
+extern const struct sieve_operation tst_size_over_operation;
81866
 
+extern const struct sieve_operation tst_size_under_operation;
81867
 
+
81868
 
+const struct sieve_operation *sieve_operations[] = {
81869
 
+       NULL, 
81870
 
+       
81871
 
+       &sieve_jmp_operation,
81872
 
+       &sieve_jmptrue_operation, 
81873
 
+       &sieve_jmpfalse_operation,
81874
 
+       
81875
 
+       &cmd_stop_operation,
81876
 
+       &cmd_keep_operation,
81877
 
+       &cmd_discard_operation,
81878
 
+       &cmd_redirect_operation,
81879
 
+
81880
 
+       &tst_address_operation,
81881
 
+       &tst_header_operation,
81882
 
+       &tst_exists_operation,
81883
 
+       &tst_size_over_operation,
81884
 
+       &tst_size_under_operation
81885
 
+}; 
81886
 
+
81887
 
+const unsigned int sieve_operation_count =
81888
 
+       N_ELEMENTS(sieve_operations);
81889
 
+
81890
 
+/* 
81891
 
+ * Operation functions 
81892
 
+ */
81893
 
+
81894
 
+sieve_size_t sieve_operation_emit_code
81895
 
+(struct sieve_binary *sbin, const struct sieve_operation *op)
81896
 
+{
81897
 
+       sieve_size_t address;
81898
 
+
81899
 
+    if ( op->extension != NULL ) {
81900
 
+        address = sieve_binary_emit_extension
81901
 
+            (sbin, op->extension, sieve_operation_count);
81902
 
+
81903
 
+        sieve_binary_emit_extension_object
81904
 
+            (sbin, &op->extension->operations, op->code);
81905
 
+
81906
 
+        return address;
81907
 
+    }
81908
 
+
81909
 
+    return  sieve_binary_emit_byte(sbin, op->code);
81910
 
+}
81911
 
+
81912
 
+const struct sieve_operation *sieve_operation_read
81913
 
+(struct sieve_binary *sbin, sieve_size_t *address) 
81914
 
+{
81915
 
+       const struct sieve_extension *ext;
81916
 
+       unsigned int code = sieve_operation_count;
81917
 
+
81918
 
+       if ( !sieve_binary_read_extension(sbin, address, &code, &ext) )
81919
 
+               return NULL;
81920
 
+
81921
 
+       if ( !ext )
81922
 
+               return code < sieve_operation_count ? sieve_operations[code] : NULL;
81923
 
+
81924
 
+    return (const struct sieve_operation *) sieve_binary_read_extension_object
81925
 
+        (sbin, address, &ext->operations);
81926
 
+}
81927
 
+
81928
 
+/*
81929
 
+ * Jump operations
81930
 
+ */
81931
 
+       
81932
 
+/* Code dump */
81933
 
+
81934
 
+static bool opc_jmp_dump
81935
 
+(const struct sieve_operation *op,
81936
 
+       const struct sieve_dumptime_env *denv, sieve_size_t *address)
81937
 
+{
81938
 
+       unsigned int pc = *address;
81939
 
+       int offset;
81940
 
+       
81941
 
+       if ( sieve_binary_read_offset(denv->sbin, address, &offset) ) 
81942
 
+               sieve_code_dumpf(denv, "%s %d [%08x]", 
81943
 
+                       op->mnemonic, offset, pc + offset);
81944
 
+       else
81945
 
+               return FALSE;
81946
 
+       
81947
 
+       return TRUE;
81948
 
+}      
81949
 
+                       
81950
 
+/* Code execution */
81951
 
+
81952
 
+static int opc_jmp_execute
81953
 
+(const struct sieve_operation *op ATTR_UNUSED, 
81954
 
+       const struct sieve_runtime_env *renv, sieve_size_t *address ATTR_UNUSED) 
81955
 
+{
81956
 
+       sieve_runtime_trace(renv, "JMP");
81957
 
+       
81958
 
+       return sieve_interpreter_program_jump(renv->interp, TRUE);
81959
 
+}      
81960
 
+               
81961
 
+static int opc_jmptrue_execute
81962
 
+(const struct sieve_operation *op ATTR_UNUSED, 
81963
 
+       const struct sieve_runtime_env *renv, sieve_size_t *address ATTR_UNUSED)
81964
 
+{      
81965
 
+       bool result = sieve_interpreter_get_test_result(renv->interp);
81966
 
+       
81967
 
+       sieve_runtime_trace(renv, "JMPTRUE (%s)", result ? "true" : "false");
81968
 
+       
81969
 
+       return sieve_interpreter_program_jump(renv->interp, result);
81970
 
+}
81971
 
+
81972
 
+static int opc_jmpfalse_execute
81973
 
+(const struct sieve_operation *op ATTR_UNUSED, 
81974
 
+       const struct sieve_runtime_env *renv, sieve_size_t *address ATTR_UNUSED)
81975
 
+{      
81976
 
+       bool result = sieve_interpreter_get_test_result(renv->interp);
81977
 
+       
81978
 
+       sieve_runtime_trace(renv, "JMPFALSE (%s)", result ? "true" : "false" );
81979
 
+       
81980
 
+       return sieve_interpreter_program_jump(renv->interp, !result);
81981
 
+}      
81982
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-code-dumper.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-code-dumper.c
81983
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-code-dumper.c    1970-01-01 01:00:00.000000000 +0100
81984
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-code-dumper.c     2009-02-02 10:17:30.000000000 +0100
81985
 
@@ -0,0 +1,292 @@
81986
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
81987
 
+ */
81988
 
+
81989
 
+#include <stdio.h>
81990
 
+#include <string.h>
81991
 
+
81992
 
+#include "lib.h"
81993
 
+#include "str.h"
81994
 
+#include "mempool.h"
81995
 
+#include "ostream.h"
81996
 
+
81997
 
+#include "sieve-common.h"
81998
 
+#include "sieve-extensions.h"
81999
 
+#include "sieve-commands.h"
82000
 
+#include "sieve-code.h"
82001
 
+#include "sieve-actions.h"
82002
 
+#include "sieve-generator.h"
82003
 
+#include "sieve-binary.h"
82004
 
+#include "sieve-result.h"
82005
 
+#include "sieve-comparators.h"
82006
 
+
82007
 
+#include "sieve-dump.h"
82008
 
+
82009
 
+/* 
82010
 
+ * Code dumper extension
82011
 
+ */
82012
 
+
82013
 
+struct sieve_code_dumper_extension_reg {
82014
 
+       const struct sieve_code_dumper_extension *val_ext;
82015
 
+       void *context;
82016
 
+};
82017
 
+
82018
 
+struct sieve_code_dumper {
82019
 
+       pool_t pool;
82020
 
+                                       
82021
 
+       /* Dump status */
82022
 
+       sieve_size_t pc;          /* Program counter */
82023
 
+       
82024
 
+       const struct sieve_operation *operation;
82025
 
+       sieve_size_t mark_address;
82026
 
+       unsigned int indent;
82027
 
+       
82028
 
+       /* Dump environment */
82029
 
+       struct sieve_dumptime_env *dumpenv; 
82030
 
+       
82031
 
+       ARRAY_DEFINE(extensions, struct sieve_code_dumper_extension_reg);
82032
 
+};
82033
 
+
82034
 
+struct sieve_code_dumper *sieve_code_dumper_create
82035
 
+       (struct sieve_dumptime_env *denv) 
82036
 
+{
82037
 
+       pool_t pool;
82038
 
+       struct sieve_code_dumper *dumper;
82039
 
+       
82040
 
+       pool = pool_alloconly_create("sieve_code_dumper", 4096);        
82041
 
+       dumper = p_new(pool, struct sieve_code_dumper, 1);
82042
 
+       dumper->pool = pool;
82043
 
+       dumper->dumpenv = denv;
82044
 
+       dumper->pc = 0;
82045
 
+       
82046
 
+       /* Setup storage for extension contexts */              
82047
 
+       p_array_init(&dumper->extensions, pool, sieve_extensions_get_count());
82048
 
+
82049
 
+       return dumper;
82050
 
+}
82051
 
+
82052
 
+void sieve_code_dumper_free(struct sieve_code_dumper **dumper) 
82053
 
+{
82054
 
+       pool_unref(&((*dumper)->pool));
82055
 
+       
82056
 
+       *dumper = NULL;
82057
 
+}
82058
 
+
82059
 
+pool_t sieve_code_dumper_pool(struct sieve_code_dumper *dumper)
82060
 
+{
82061
 
+       return dumper->pool;
82062
 
+}
82063
 
+
82064
 
+/* EXtension support */
82065
 
+
82066
 
+void sieve_dump_extension_register
82067
 
+(struct sieve_code_dumper *dumper, 
82068
 
+       const struct sieve_code_dumper_extension *dump_ext, void *context)
82069
 
+{
82070
 
+       struct sieve_code_dumper_extension_reg reg = { dump_ext, context };
82071
 
+       int ext_id = SIEVE_EXT_ID(dump_ext->ext);
82072
 
+
82073
 
+       if ( ext_id < 0 ) return;
82074
 
+       
82075
 
+       array_idx_set(&dumper->extensions, (unsigned int) ext_id, &reg);        
82076
 
+}
82077
 
+
82078
 
+void sieve_dump_extension_set_context
82079
 
+(struct sieve_code_dumper *dumper, const struct sieve_extension *ext, 
82080
 
+       void *context)
82081
 
+{
82082
 
+       struct sieve_code_dumper_extension_reg reg = { NULL, context };
82083
 
+       int ext_id = SIEVE_EXT_ID(ext);
82084
 
+
82085
 
+       if ( ext_id < 0 ) return;
82086
 
+       
82087
 
+       array_idx_set(&dumper->extensions, (unsigned int) ext_id, &reg);        
82088
 
+}
82089
 
+
82090
 
+void *sieve_dump_extension_get_context
82091
 
+(struct sieve_code_dumper *dumper, const struct sieve_extension *ext) 
82092
 
+{
82093
 
+       int ext_id = SIEVE_EXT_ID(ext);
82094
 
+       const struct sieve_code_dumper_extension_reg *reg;
82095
 
+
82096
 
+       if  ( ext_id < 0 || ext_id >= (int) array_count(&dumper->extensions) )
82097
 
+               return NULL;
82098
 
+       
82099
 
+       reg = array_idx(&dumper->extensions, (unsigned int) ext_id);            
82100
 
+
82101
 
+       return reg->context;
82102
 
+}
82103
 
+
82104
 
+/* Dump functions */
82105
 
+
82106
 
+void sieve_code_dumpf
82107
 
+(const struct sieve_dumptime_env *denv, const char *fmt, ...)
82108
 
+{
82109
 
+       struct sieve_code_dumper *cdumper = denv->cdumper;      
82110
 
+       unsigned tab = cdumper->indent;
82111
 
+        
82112
 
+       string_t *outbuf = t_str_new(128);
82113
 
+       va_list args;
82114
 
+       
82115
 
+       va_start(args, fmt);    
82116
 
+       str_printfa(outbuf, "%08llx: ", (unsigned long long) cdumper->mark_address);
82117
 
+       
82118
 
+       while ( tab > 0 )       {
82119
 
+               str_append(outbuf, "  ");
82120
 
+               tab--;
82121
 
+       }
82122
 
+       
82123
 
+       str_vprintfa(outbuf, fmt, args);
82124
 
+       str_append_c(outbuf, '\n');
82125
 
+       va_end(args);
82126
 
+       
82127
 
+       o_stream_send(denv->stream, str_data(outbuf), str_len(outbuf));
82128
 
+}
82129
 
+
82130
 
+void sieve_code_mark(const struct sieve_dumptime_env *denv)
82131
 
+{
82132
 
+       denv->cdumper->mark_address = denv->cdumper->pc;
82133
 
+}
82134
 
+
82135
 
+void sieve_code_mark_specific
82136
 
+(const struct sieve_dumptime_env *denv, sieve_size_t location)
82137
 
+{
82138
 
+       denv->cdumper->mark_address = location;
82139
 
+}
82140
 
+
82141
 
+void sieve_code_descend(const struct sieve_dumptime_env *denv)
82142
 
+{
82143
 
+       denv->cdumper->indent++;
82144
 
+}
82145
 
+
82146
 
+void sieve_code_ascend(const struct sieve_dumptime_env *denv)
82147
 
+{
82148
 
+       if ( denv->cdumper->indent > 0 )
82149
 
+               denv->cdumper->indent--;
82150
 
+}
82151
 
+
82152
 
+/* Operations and operands */
82153
 
+
82154
 
+bool sieve_code_dumper_print_optional_operands
82155
 
+       (const struct sieve_dumptime_env *denv, sieve_size_t *address)
82156
 
+{
82157
 
+       int opt_code = -1;
82158
 
+       
82159
 
+       if ( sieve_operand_optional_present(denv->sbin, address) ) {
82160
 
+               
82161
 
+               while ( opt_code != 0 ) {                       
82162
 
+                       if ( !sieve_operand_optional_read(denv->sbin, address, &opt_code) ) {
82163
 
+                               return FALSE;
82164
 
+                       }
82165
 
+
82166
 
+                       if ( opt_code == SIEVE_OPT_SIDE_EFFECT ) {
82167
 
+                               if ( !sieve_opr_side_effect_dump(denv, address) )
82168
 
+                                       return FALSE;
82169
 
+                       }
82170
 
+               }
82171
 
+       } 
82172
 
+       return TRUE;
82173
 
+}
82174
 
82175
 
+/* Code Dump */
82176
 
+
82177
 
+static bool sieve_code_dumper_print_operation
82178
 
+       (struct sieve_code_dumper *dumper) 
82179
 
+{      
82180
 
+       const struct sieve_operation *op;
82181
 
+       struct sieve_dumptime_env *denv = dumper->dumpenv;
82182
 
+       sieve_size_t address;
82183
 
+       
82184
 
+       /* Mark start address of operation */
82185
 
+       dumper->indent = 0;
82186
 
+       address = dumper->mark_address = dumper->pc;
82187
 
+
82188
 
+       /* Read operation */
82189
 
+       dumper->operation = op = 
82190
 
+               sieve_operation_read(denv->sbin, &(dumper->pc));
82191
 
+
82192
 
+       /* Try to dump it */
82193
 
+       if ( op != NULL ) {
82194
 
+               if ( op->dump != NULL )
82195
 
+                       return op->dump(op, denv, &(dumper->pc));
82196
 
+               else if ( op->mnemonic != NULL )
82197
 
+                       sieve_code_dumpf(denv, "%s", op->mnemonic);
82198
 
+               else
82199
 
+                       return FALSE;
82200
 
+                       
82201
 
+               return TRUE;
82202
 
+       }               
82203
 
+       
82204
 
+       sieve_code_dumpf(denv, "Failed to read opcode.");
82205
 
+       return FALSE;
82206
 
+}
82207
 
+
82208
 
+void sieve_code_dumper_run(struct sieve_code_dumper *dumper) 
82209
 
+{
82210
 
+       const struct sieve_dumptime_env *denv = dumper->dumpenv;
82211
 
+       struct sieve_binary *sbin = denv->sbin;
82212
 
+       unsigned int ext_count;
82213
 
+       bool success = TRUE;
82214
 
+
82215
 
+       dumper->pc = 0;
82216
 
+       
82217
 
+       /* Load and dump extensions listed in code */
82218
 
+       sieve_code_mark(denv);
82219
 
+       
82220
 
+       if ( sieve_binary_read_unsigned(sbin, &dumper->pc, &ext_count) ) {
82221
 
+               unsigned int i;
82222
 
+               
82223
 
+               sieve_code_dumpf(denv, "EXTENSIONS [%d]:", ext_count);
82224
 
+               sieve_code_descend(denv);
82225
 
+               
82226
 
+               for ( i = 0; i < ext_count; i++ ) {
82227
 
+                       unsigned int code = 0;
82228
 
+                       const struct sieve_extension *ext;
82229
 
+                       
82230
 
+                       T_BEGIN {
82231
 
+                               sieve_code_mark(denv);
82232
 
+                       
82233
 
+                               if ( !sieve_binary_read_extension(sbin, &dumper->pc, &code, &ext) ) {
82234
 
+                                       success = FALSE;
82235
 
+                                       break;
82236
 
+                               }
82237
 
+       
82238
 
+                               sieve_code_dumpf(denv, "%s", ext->name);
82239
 
+      
82240
 
+                               if ( ext->code_dump != NULL ) {
82241
 
+                                       sieve_code_descend(denv);
82242
 
+                                       if ( !ext->code_dump(denv, &dumper->pc) ) {
82243
 
+                                               success = FALSE;
82244
 
+                                               break;
82245
 
+                                       }
82246
 
+                                       sieve_code_ascend(denv);
82247
 
+                               }
82248
 
+                       } T_END;
82249
 
+               }
82250
 
+               
82251
 
+               sieve_code_ascend(denv);
82252
 
+       }       else
82253
 
+               success = FALSE;
82254
 
+               
82255
 
+       if ( !success ) {
82256
 
+               sieve_code_dumpf(denv, "Binary code header is corrupt.");
82257
 
+               return;
82258
 
+       }
82259
 
+       
82260
 
+       while ( dumper->pc < 
82261
 
+               sieve_binary_get_code_size(sbin) ) {
82262
 
+
82263
 
+               T_BEGIN {
82264
 
+                       success = sieve_code_dumper_print_operation(dumper);
82265
 
+               } T_END;
82266
 
+
82267
 
+               if ( !success ) {
82268
 
+                       sieve_code_dumpf(dumper->dumpenv, "Binary is corrupt.");
82269
 
+                       return;
82270
 
+               }
82271
 
+       }
82272
 
+       
82273
 
+       /* Mark end of the binary */
82274
 
+       dumper->indent = 0;
82275
 
+       dumper->mark_address = sieve_binary_get_code_size(sbin);
82276
 
+       sieve_code_dumpf(dumper->dumpenv, "[End of code]");     
82277
 
+}
82278
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-code-dumper.h dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-code-dumper.h
82279
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-code-dumper.h    1970-01-01 01:00:00.000000000 +0100
82280
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-code-dumper.h     2009-01-06 00:15:52.000000000 +0100
82281
 
@@ -0,0 +1,58 @@
82282
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
82283
 
+ */
82284
 
+
82285
 
+#ifndef __SIEVE_CODE_DUMPER_H
82286
 
+#define __SIEVE_CODE_DUMPER_H
82287
 
+
82288
 
+#include "sieve-common.h"
82289
 
+
82290
 
+struct sieve_code_dumper;
82291
 
+
82292
 
+struct sieve_code_dumper *sieve_code_dumper_create
82293
 
+       (struct sieve_dumptime_env *denv);
82294
 
+void sieve_code_dumper_free
82295
 
+       (struct sieve_code_dumper **dumper);
82296
 
+pool_t sieve_code_dumper_pool
82297
 
+       (struct sieve_code_dumper *dumper);
82298
 
+       
82299
 
+/* 
82300
 
+ * Extension support
82301
 
+ */
82302
 
+
82303
 
+struct sieve_code_dumper_extension {
82304
 
+       const struct sieve_extension *ext;      
82305
 
+
82306
 
+       void (*free)(struct sieve_code_dumper *dumper, void *context);
82307
 
+};
82308
 
+
82309
 
+void sieve_dump_extension_register
82310
 
+(struct sieve_code_dumper *dumper, 
82311
 
+       const struct sieve_code_dumper_extension *dump_ext, void *context);
82312
 
+void sieve_dump_extension_set_context
82313
 
+       (struct sieve_code_dumper *dumper, const struct sieve_extension *ext, 
82314
 
+               void *context);
82315
 
+void *sieve_dump_extension_get_context
82316
 
+       (struct sieve_code_dumper *dumper, const struct sieve_extension *ext); 
82317
 
+       
82318
 
+/* Dump functions */   
82319
 
+       
82320
 
+void sieve_code_dumpf
82321
 
+       (const struct sieve_dumptime_env *denv, const char *fmt, ...)
82322
 
+               ATTR_FORMAT(2, 3);
82323
 
+
82324
 
+void sieve_code_mark(const struct sieve_dumptime_env *denv);
82325
 
+void sieve_code_mark_specific
82326
 
+       (const struct sieve_dumptime_env *denv, sieve_size_t location);
82327
 
+void sieve_code_descend(const struct sieve_dumptime_env *denv);
82328
 
+void sieve_code_ascend(const struct sieve_dumptime_env *denv);
82329
 
+
82330
 
+/* Operations and operands */
82331
 
+       
82332
 
+bool sieve_code_dumper_print_optional_operands
82333
 
+       (const struct sieve_dumptime_env *denv, sieve_size_t *address);
82334
 
+
82335
 
+/* Code dump (debugging purposes) */
82336
 
+
82337
 
+void sieve_code_dumper_run(struct sieve_code_dumper *dumper);
82338
 
+
82339
 
+#endif /* __SIEVE_CODE_DUMPER_H */
82340
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-code.h dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-code.h
82341
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-code.h   1970-01-01 01:00:00.000000000 +0100
82342
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-code.h    2009-08-05 13:09:10.000000000 +0200
82343
 
@@ -0,0 +1,295 @@
82344
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
82345
 
+ */
82346
 
82347
 
+#ifndef __SIEVE_CODE_H
82348
 
+#define __SIEVE_CODE_H
82349
 
+
82350
 
+#include "lib.h"
82351
 
+#include "buffer.h"
82352
 
+#include "mempool.h"
82353
 
+#include "array.h"
82354
 
+
82355
 
+#include "sieve-common.h"
82356
 
+
82357
 
+/* 
82358
 
+ * Coded string list 
82359
 
+ */
82360
 
+
82361
 
+struct sieve_coded_stringlist;
82362
 
+
82363
 
+bool sieve_coded_stringlist_next_item
82364
 
+       (struct sieve_coded_stringlist *strlist, string_t **str_r);
82365
 
+void sieve_coded_stringlist_reset
82366
 
+       (struct sieve_coded_stringlist *strlist);
82367
 
+bool sieve_coded_stringlist_read_all
82368
 
+       (struct sieve_coded_stringlist *strlist, pool_t pool,
82369
 
+               const char * const **list_r);
82370
 
+
82371
 
+unsigned int sieve_coded_stringlist_get_length
82372
 
+       (struct sieve_coded_stringlist *strlist);
82373
 
+sieve_size_t sieve_coded_stringlist_get_end_address
82374
 
+       (struct sieve_coded_stringlist *strlist);
82375
 
+sieve_size_t sieve_coded_stringlist_get_current_offset
82376
 
+       (struct sieve_coded_stringlist *strlist);
82377
 
+
82378
 
+/* 
82379
 
+ * Source line coding
82380
 
+ */
82381
 
+
82382
 
+void sieve_code_source_line_emit
82383
 
+       (struct sieve_binary *sbin, unsigned int source_line);
82384
 
+bool sieve_code_source_line_dump
82385
 
+       (const struct sieve_dumptime_env *denv, sieve_size_t *address);
82386
 
+bool sieve_code_source_line_read
82387
 
+       (const struct sieve_runtime_env *renv, sieve_size_t *address, 
82388
 
+       unsigned int *source_line_r);
82389
 
+
82390
 
+/* 
82391
 
+ * Operand object
82392
 
+ */
82393
 
+
82394
 
+struct sieve_operand_class {
82395
 
+       const char *name;
82396
 
+};
82397
 
+
82398
 
+struct sieve_operand {
82399
 
+       const char *name;
82400
 
+       
82401
 
+       const struct sieve_extension *extension;
82402
 
+       unsigned int code;
82403
 
+       
82404
 
+       const struct sieve_operand_class *class;
82405
 
+       const void *interface;
82406
 
+};
82407
 
+
82408
 
+sieve_size_t sieve_operand_emit_code
82409
 
+       (struct sieve_binary *sbin, const struct sieve_operand *opr);
82410
 
+const struct sieve_operand *sieve_operand_read
82411
 
+       (struct sieve_binary *sbin, sieve_size_t *address);
82412
 
+
82413
 
+bool sieve_operand_optional_present
82414
 
+       (struct sieve_binary *sbin, sieve_size_t *address);
82415
 
+bool sieve_operand_optional_read       
82416
 
+       (struct sieve_binary *sbin, sieve_size_t *address, 
82417
 
+               signed int *id_code);
82418
 
+
82419
 
+/*
82420
 
+ * Core operands
82421
 
+ */
82422
 
82423
 
+/* Operand codes */
82424
 
+
82425
 
+enum sieve_core_operand {
82426
 
+       SIEVE_OPERAND_OPTIONAL = 0x00,
82427
 
+       SIEVE_OPERAND_NUMBER,
82428
 
+       SIEVE_OPERAND_STRING,
82429
 
+       SIEVE_OPERAND_STRING_LIST,
82430
 
+       SIEVE_OPERAND_COMPARATOR,
82431
 
+       SIEVE_OPERAND_MATCH_TYPE,
82432
 
+       SIEVE_OPERAND_ADDRESS_PART,
82433
 
+       SIEVE_OPERAND_CATENATED_STRING,
82434
 
+
82435
 
+       SIEVE_OPERAND_CUSTOM
82436
 
+};
82437
 
+
82438
 
+/* Operand classes */
82439
 
+
82440
 
+extern const struct sieve_operand_class number_class;
82441
 
+extern const struct sieve_operand_class string_class;
82442
 
+extern const struct sieve_operand_class stringlist_class;
82443
 
+
82444
 
+/* Operand objects */
82445
 
+
82446
 
+extern const struct sieve_operand omitted_operand;
82447
 
+extern const struct sieve_operand number_operand;
82448
 
+extern const struct sieve_operand string_operand;
82449
 
+extern const struct sieve_operand stringlist_operand;
82450
 
+extern const struct sieve_operand catenated_string_operand;
82451
 
+
82452
 
+extern const struct sieve_operand *sieve_operands[];
82453
 
+extern const unsigned int sieve_operand_count;
82454
 
+
82455
 
+/* Operand object interfaces */
82456
 
+
82457
 
+struct sieve_opr_number_interface {
82458
 
+       bool (*dump)    
82459
 
+               (const struct sieve_dumptime_env *denv, sieve_size_t *address,
82460
 
+                       const char *field_name);
82461
 
+       bool (*read)
82462
 
+         (const struct sieve_runtime_env *renv, sieve_size_t *address, 
82463
 
+               sieve_number_t *number_r);
82464
 
+};
82465
 
+
82466
 
+struct sieve_opr_string_interface {
82467
 
+       bool (*dump)
82468
 
+               (const struct sieve_dumptime_env *denv, sieve_size_t *address,
82469
 
+                       const char *field_name);
82470
 
+       bool (*read)
82471
 
+               (const struct sieve_runtime_env *renv, sieve_size_t *address, 
82472
 
+                       string_t **str_r);
82473
 
+};
82474
 
+
82475
 
+struct sieve_opr_stringlist_interface {
82476
 
+       bool (*dump)
82477
 
+               (const struct sieve_dumptime_env *denv, sieve_size_t *address,
82478
 
+                       const char *field_name);
82479
 
+       struct sieve_coded_stringlist *(*read)
82480
 
+               (const struct sieve_runtime_env *renv, sieve_size_t *address);
82481
 
+};
82482
 
+
82483
 
+/* 
82484
 
+ * Core operand functions 
82485
 
+ */
82486
 
+
82487
 
+/* Omitted */
82488
 
+
82489
 
+void sieve_opr_omitted_emit(struct sieve_binary *sbin);
82490
 
+
82491
 
+static inline bool sieve_operand_is_omitted
82492
 
+(const struct sieve_operand *operand)
82493
 
+{
82494
 
+       return ( operand != NULL && operand == &omitted_operand );
82495
 
+}
82496
 
+
82497
 
+/* Number */
82498
 
+
82499
 
+void sieve_opr_number_emit(struct sieve_binary *sbin, sieve_number_t number);
82500
 
+bool sieve_opr_number_dump_data        
82501
 
+       (const struct sieve_dumptime_env *denv, const struct sieve_operand *operand,
82502
 
+               sieve_size_t *address, const char *field_name); 
82503
 
+bool sieve_opr_number_dump     
82504
 
+       (const struct sieve_dumptime_env *denv, sieve_size_t *address,
82505
 
+               const char *field_name); 
82506
 
+bool sieve_opr_number_read_data
82507
 
+       (const struct sieve_runtime_env *renv, const struct sieve_operand *operand,
82508
 
+               sieve_size_t *address, sieve_number_t *number_r);
82509
 
+bool sieve_opr_number_read
82510
 
+       (const struct sieve_runtime_env *renv, sieve_size_t *address, 
82511
 
+               sieve_number_t *number_r);
82512
 
+
82513
 
+static inline bool sieve_operand_is_number
82514
 
+(const struct sieve_operand *operand)
82515
 
+{
82516
 
+       return ( operand != NULL && operand->class == &number_class );
82517
 
+}
82518
 
+
82519
 
+/* String */
82520
 
+
82521
 
+void sieve_opr_string_emit(struct sieve_binary *sbin, string_t *str);
82522
 
+bool sieve_opr_string_dump_data
82523
 
+       (const struct sieve_dumptime_env *denv, const struct sieve_operand *operand,
82524
 
+               sieve_size_t *address, const char *field_name); 
82525
 
+bool sieve_opr_string_dump
82526
 
+       (const struct sieve_dumptime_env *denv, sieve_size_t *address,
82527
 
+               const char *field_name); 
82528
 
+bool sieve_opr_string_dump_ex
82529
 
+       (const struct sieve_dumptime_env *denv, sieve_size_t *address, 
82530
 
+               const char *field_name, bool *literal_r); 
82531
 
+bool sieve_opr_string_read_data
82532
 
+       (const struct sieve_runtime_env *renv, const struct sieve_operand *operand,
82533
 
+               sieve_size_t *address, string_t **str_r);
82534
 
+bool sieve_opr_string_read
82535
 
+       (const struct sieve_runtime_env *renv, sieve_size_t *address, string_t **str_r);
82536
 
+bool sieve_opr_string_read_ex
82537
 
+       (const struct sieve_runtime_env *renv, sieve_size_t *address, string_t **str_r,
82538
 
+               bool *literal_r);
82539
 
+
82540
 
+static inline bool sieve_operand_is_string
82541
 
+(const struct sieve_operand *operand)
82542
 
+{
82543
 
+       return ( operand != NULL && operand->class == &string_class );
82544
 
+}
82545
 
+
82546
 
+/* String list */
82547
 
+
82548
 
+void sieve_opr_stringlist_emit_start
82549
 
+       (struct sieve_binary *sbin, unsigned int listlen, void **context);
82550
 
+void sieve_opr_stringlist_emit_item
82551
 
+       (struct sieve_binary *sbin, void *context ATTR_UNUSED, string_t *item);
82552
 
+void sieve_opr_stringlist_emit_end
82553
 
+       (struct sieve_binary *sbin, void *context);
82554
 
+bool sieve_opr_stringlist_dump_data
82555
 
+       (const struct sieve_dumptime_env *denv, const struct sieve_operand *operand, 
82556
 
+               sieve_size_t *address, const char *field_name);
82557
 
+bool sieve_opr_stringlist_dump
82558
 
+       (const struct sieve_dumptime_env *denv, sieve_size_t *address,
82559
 
+               const char *field_name);
82560
 
+struct sieve_coded_stringlist *sieve_opr_stringlist_read_data
82561
 
+       (const struct sieve_runtime_env *renv, const struct sieve_operand *operand, 
82562
 
+               sieve_size_t op_address, sieve_size_t *address);
82563
 
+struct sieve_coded_stringlist *sieve_opr_stringlist_read
82564
 
+       (const struct sieve_runtime_env *renv, sieve_size_t *address);
82565
 
+
82566
 
+static inline bool sieve_operand_is_stringlist
82567
 
+(const struct sieve_operand *operand)
82568
 
+{
82569
 
+       return ( operand != NULL && 
82570
 
+               (operand->class == &stringlist_class || operand->class == &string_class) );
82571
 
+}
82572
 
+
82573
 
+/* Catenated string */
82574
 
+
82575
 
+void sieve_opr_catenated_string_emit
82576
 
+       (struct sieve_binary *sbin, unsigned int elements);
82577
 
+       
82578
 
+/*
82579
 
+ * Operation object
82580
 
+ */
82581
 
82582
 
+struct sieve_operation {
82583
 
+       const char *mnemonic;
82584
 
+       
82585
 
+       const struct sieve_extension *extension;
82586
 
+       unsigned int code;
82587
 
+       
82588
 
+       bool (*dump)
82589
 
+               (const struct sieve_operation *op, 
82590
 
+                       const struct sieve_dumptime_env *denv, sieve_size_t *address);
82591
 
+       int (*execute)
82592
 
+               (const struct sieve_operation *op, 
82593
 
+                       const struct sieve_runtime_env *renv, sieve_size_t *address);
82594
 
+};
82595
 
+
82596
 
+sieve_size_t sieve_operation_emit_code
82597
 
+       (struct sieve_binary *sbin, const struct sieve_operation *op);  
82598
 
+const struct sieve_operation *sieve_operation_read
82599
 
+       (struct sieve_binary *sbin, sieve_size_t *address);
82600
 
+const char *sieve_operation_read_string
82601
 
+    (struct sieve_binary *sbin, sieve_size_t *address);
82602
 
+
82603
 
+/* 
82604
 
+ * Core operations 
82605
 
+ */
82606
 
+
82607
 
+/* Opcodes */
82608
 
+
82609
 
+enum sieve_operation_code {
82610
 
+       SIEVE_OPERATION_INVALID,
82611
 
+       SIEVE_OPERATION_JMP,
82612
 
+       SIEVE_OPERATION_JMPTRUE,
82613
 
+       SIEVE_OPERATION_JMPFALSE,
82614
 
+       
82615
 
+       SIEVE_OPERATION_STOP,
82616
 
+       SIEVE_OPERATION_KEEP,
82617
 
+       SIEVE_OPERATION_DISCARD,
82618
 
+       SIEVE_OPERATION_REDIRECT,
82619
 
+       
82620
 
+       SIEVE_OPERATION_ADDRESS,
82621
 
+       SIEVE_OPERATION_HEADER, 
82622
 
+       SIEVE_OPERATION_EXISTS, 
82623
 
+       SIEVE_OPERATION_SIZE_OVER,
82624
 
+       SIEVE_OPERATION_SIZE_UNDER,
82625
 
+       
82626
 
+       SIEVE_OPERATION_CUSTOM
82627
 
+};
82628
 
+
82629
 
+/* Operation objects */
82630
 
+
82631
 
+extern const struct sieve_operation sieve_jmp_operation;
82632
 
+extern const struct sieve_operation sieve_jmptrue_operation;
82633
 
+extern const struct sieve_operation sieve_jmpfalse_operation; 
82634
 
+
82635
 
+extern const struct sieve_operation *sieve_operations[];
82636
 
+extern const unsigned int sieve_operations_count;
82637
 
+
82638
 
+#endif
82639
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-commands.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-commands.c
82640
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-commands.c       1970-01-01 01:00:00.000000000 +0100
82641
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-commands.c        2009-01-06 00:15:52.000000000 +0100
82642
 
@@ -0,0 +1,371 @@
82643
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
82644
 
+ */
82645
 
+
82646
 
+#include "lib.h"
82647
 
+#include "str.h"
82648
 
+#include "str-sanitize.h"
82649
 
+
82650
 
+#include "rfc2822.h"
82651
 
+
82652
 
+#include "sieve-common.h"
82653
 
+#include "sieve-ast.h"
82654
 
+#include "sieve-validator.h"
82655
 
+#include "sieve-generator.h"
82656
 
+#include "sieve-binary.h"
82657
 
+#include "sieve-commands.h"
82658
 
+#include "sieve-code.h"
82659
 
+#include "sieve-interpreter.h"
82660
 
+
82661
 
+/* 
82662
 
+ * Literal arguments
82663
 
+ */
82664
 
+
82665
 
+/* Forward declarations */
82666
 
+
82667
 
+static bool arg_number_generate
82668
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, 
82669
 
+               struct sieve_command_context *context);
82670
 
+static bool arg_string_generate
82671
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, 
82672
 
+               struct sieve_command_context *context);
82673
 
+static bool arg_string_list_validate
82674
 
+       (struct sieve_validator *validator, struct sieve_ast_argument **arg, 
82675
 
+               struct sieve_command_context *context);
82676
 
+static bool arg_string_list_generate
82677
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, 
82678
 
+               struct sieve_command_context *context);
82679
 
+
82680
 
+/* Argument objects */
82681
 
+
82682
 
+const struct sieve_argument number_argument = { 
82683
 
+       "@number", 
82684
 
+       NULL, NULL, NULL, NULL,
82685
 
+       arg_number_generate 
82686
 
+};
82687
 
+
82688
 
+const struct sieve_argument string_argument = { 
82689
 
+       "@string", 
82690
 
+       NULL, NULL, NULL, NULL,
82691
 
+       arg_string_generate 
82692
 
+};
82693
 
+
82694
 
+const struct sieve_argument string_list_argument = { 
82695
 
+       "@string-list", 
82696
 
+       NULL, NULL,
82697
 
+       arg_string_list_validate, 
82698
 
+       NULL, 
82699
 
+       arg_string_list_generate 
82700
 
+};     
82701
 
+
82702
 
+/* Argument implementations */
82703
 
+
82704
 
+static bool arg_number_generate
82705
 
+(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, 
82706
 
+       struct sieve_command_context *context ATTR_UNUSED)
82707
 
+{
82708
 
+       sieve_opr_number_emit(cgenv->sbin, sieve_ast_argument_number(arg));
82709
 
+
82710
 
+       return TRUE;
82711
 
+}
82712
 
+
82713
 
+static bool arg_string_generate
82714
 
+(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, 
82715
 
+       struct sieve_command_context *context ATTR_UNUSED)
82716
 
+{
82717
 
+       sieve_opr_string_emit(cgenv->sbin, sieve_ast_argument_str(arg));
82718
 
+  
82719
 
+       return TRUE;
82720
 
+}
82721
 
+
82722
 
+static bool arg_string_list_validate
82723
 
+(struct sieve_validator *validator, struct sieve_ast_argument **arg, 
82724
 
+       struct sieve_command_context *context)
82725
 
+{
82726
 
+       struct sieve_ast_argument *stritem;
82727
 
+
82728
 
+       stritem = sieve_ast_strlist_first(*arg);        
82729
 
+       while ( stritem != NULL ) {
82730
 
+               if ( !sieve_validator_argument_activate(validator, context, stritem, FALSE) )
82731
 
+                       return FALSE;
82732
 
+                       
82733
 
+               stritem = sieve_ast_strlist_next(stritem);
82734
 
+       }
82735
 
+
82736
 
+       return TRUE;    
82737
 
+}
82738
 
+
82739
 
+static bool emit_string_list_operand
82740
 
+(const struct sieve_codegen_env *cgenv, const struct sieve_ast_argument *strlist,
82741
 
+       struct sieve_command_context *context)
82742
 
+{      
82743
 
+       void *list_context;
82744
 
+       struct sieve_ast_argument *stritem;
82745
 
+       
82746
 
+       sieve_opr_stringlist_emit_start
82747
 
+               (cgenv->sbin, sieve_ast_strlist_count(strlist), &list_context);
82748
 
+
82749
 
+       stritem = sieve_ast_strlist_first(strlist);
82750
 
+       while ( stritem != NULL ) {
82751
 
+               if ( !sieve_generate_argument(cgenv, stritem, context) )
82752
 
+                       return FALSE;
82753
 
+                       
82754
 
+               stritem = sieve_ast_strlist_next(stritem);
82755
 
+       }
82756
 
+
82757
 
+       sieve_opr_stringlist_emit_end(cgenv->sbin, list_context);
82758
 
+       
82759
 
+       return TRUE;
82760
 
+}
82761
 
+
82762
 
+static bool arg_string_list_generate
82763
 
+(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, 
82764
 
+       struct sieve_command_context *context)
82765
 
+{
82766
 
+       if ( sieve_ast_argument_type(arg) == SAAT_STRING ) {
82767
 
+               return ( sieve_generate_argument(cgenv, arg, context) );
82768
 
+
82769
 
+       } else if ( sieve_ast_argument_type(arg) == SAAT_STRING_LIST ) {
82770
 
+               bool result = TRUE;
82771
 
+               
82772
 
+               if ( sieve_ast_strlist_count(arg) == 1 ) 
82773
 
+                       return ( sieve_generate_argument
82774
 
+                               (cgenv, sieve_ast_strlist_first(arg), context) );
82775
 
+               else {
82776
 
+                       T_BEGIN { 
82777
 
+                               result=emit_string_list_operand(cgenv, arg, context);
82778
 
+                       } T_END;
82779
 
+               }
82780
 
+
82781
 
+               return result;
82782
 
+       }
82783
 
+       
82784
 
+       return FALSE;
82785
 
+}
82786
 
+
82787
 
+/*
82788
 
+ * Abstract arguments 
82789
 
+ *
82790
 
+ *   (Generated by processing and not by parsing the grammar)
82791
 
+ */
82792
 
82793
 
+/* Catenated string */
82794
 
+
82795
 
+struct sieve_arg_catenated_string {
82796
 
+       struct sieve_ast_arg_list *str_parts;
82797
 
+};
82798
 
82799
 
+struct sieve_arg_catenated_string *sieve_arg_catenated_string_create
82800
 
+(struct sieve_ast_argument *orig_arg)
82801
 
+{
82802
 
+       pool_t pool = sieve_ast_pool(orig_arg->ast);
82803
 
+       struct sieve_ast_arg_list *arglist;
82804
 
+       struct sieve_arg_catenated_string *catstr;
82805
 
+
82806
 
+       arglist = sieve_ast_arg_list_create(pool);
82807
 
+                                       
82808
 
+       catstr = p_new(pool, struct sieve_arg_catenated_string, 1);
82809
 
+       catstr->str_parts = arglist;
82810
 
+       (orig_arg)->context = (void *) catstr;
82811
 
+       
82812
 
+       return catstr;
82813
 
+}
82814
 
+
82815
 
+void sieve_arg_catenated_string_add_element
82816
 
+(struct sieve_arg_catenated_string *catstr, 
82817
 
+       struct sieve_ast_argument *element)
82818
 
+{
82819
 
+       sieve_ast_arg_list_add(catstr->str_parts, element);
82820
 
+}
82821
 
+
82822
 
+#define _cat_string_first(catstr) __AST_LIST_FIRST((catstr)->str_parts)
82823
 
+#define _cat_string_count(catstr) __AST_LIST_COUNT((catstr)->str_parts)
82824
 
+#define _cat_string_next(item) __AST_LIST_NEXT(item)
82825
 
+
82826
 
+bool sieve_arg_catenated_string_generate
82827
 
+(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, 
82828
 
+       struct sieve_command_context *cmd) 
82829
 
+{
82830
 
+       struct sieve_binary *sbin = cgenv->sbin;
82831
 
+       struct sieve_arg_catenated_string *catstr = 
82832
 
+               (struct sieve_arg_catenated_string *) arg->context;
82833
 
+       struct sieve_ast_argument *strpart;
82834
 
+       
82835
 
+       if ( _cat_string_count(catstr) == 1 )
82836
 
+               sieve_generate_argument(cgenv, _cat_string_first(catstr), cmd);
82837
 
+       else {
82838
 
+               sieve_opr_catenated_string_emit(sbin, _cat_string_count(catstr));
82839
 
+
82840
 
+               strpart = _cat_string_first(catstr);
82841
 
+               while ( strpart != NULL ) {
82842
 
+                       if ( !sieve_generate_argument(cgenv, strpart, cmd) )
82843
 
+                               return FALSE;
82844
 
+                       
82845
 
+                       strpart = _cat_string_next(strpart);
82846
 
+               }
82847
 
+       }
82848
 
+       
82849
 
+       return TRUE;
82850
 
+}
82851
 
+
82852
 
+/* 
82853
 
+ * Core tests and commands 
82854
 
+ */
82855
 
+
82856
 
+const struct sieve_command *sieve_core_tests[] = {
82857
 
+       &tst_false, &tst_true,
82858
 
+       &tst_not, &tst_anyof, &tst_allof,
82859
 
+       &tst_address, &tst_header, &tst_exists, &tst_size
82860
 
+};
82861
 
+
82862
 
+const unsigned int sieve_core_tests_count = N_ELEMENTS(sieve_core_tests);
82863
 
+
82864
 
+const struct sieve_command *sieve_core_commands[] = {
82865
 
+       &cmd_require, 
82866
 
+       &cmd_stop, &cmd_if, &cmd_elsif, &cmd_else, 
82867
 
+       &cmd_keep, &cmd_discard, &cmd_redirect
82868
 
+};
82869
 
+
82870
 
+const unsigned int sieve_core_commands_count = N_ELEMENTS(sieve_core_commands);
82871
 
+       
82872
 
+/* 
82873
 
+ * Command context 
82874
 
+ */
82875
 
+
82876
 
+struct sieve_command_context *sieve_command_prev_context       
82877
 
+       (struct sieve_command_context *context) 
82878
 
+{
82879
 
+       struct sieve_ast_node *node = sieve_ast_node_prev(context->ast_node);
82880
 
+       
82881
 
+       if ( node != NULL ) {
82882
 
+               return node->context;
82883
 
+       }
82884
 
+       
82885
 
+       return NULL;
82886
 
+}
82887
 
+
82888
 
+struct sieve_command_context *sieve_command_parent_context     
82889
 
+       (struct sieve_command_context *context) 
82890
 
+{
82891
 
+       struct sieve_ast_node *node = sieve_ast_node_parent(context->ast_node);
82892
 
+       
82893
 
+       if ( node != NULL ) {
82894
 
+               return node->context;
82895
 
+       }
82896
 
+       
82897
 
+       return NULL;
82898
 
+}
82899
 
+
82900
 
+struct sieve_command_context *sieve_command_context_create
82901
 
+       (struct sieve_ast_node *cmd_node, const struct sieve_command *command,
82902
 
+               struct sieve_command_registration *reg)
82903
 
+{
82904
 
+       struct sieve_command_context *cmd;
82905
 
+       
82906
 
+       cmd = p_new(sieve_ast_node_pool(cmd_node), struct sieve_command_context, 1);
82907
 
+       
82908
 
+       cmd->ast_node = cmd_node;       
82909
 
+       cmd->command = command;
82910
 
+       cmd->cmd_reg = reg;
82911
 
+       
82912
 
+       cmd->block_exit_command = NULL;
82913
 
+       
82914
 
+       return cmd;
82915
 
+}
82916
 
+
82917
 
+const char *sieve_command_type_name(const struct sieve_command *command) {
82918
 
+       switch ( command->type ) {
82919
 
+       case SCT_NONE: return "command of unspecified type (bug)";
82920
 
+       case SCT_TEST: return "test";
82921
 
+       case SCT_COMMAND: return "command";
82922
 
+       default:
82923
 
+               break;
82924
 
+       }
82925
 
+       return "??COMMAND-TYPE??";
82926
 
+}
82927
 
+
82928
 
+struct sieve_ast_argument *sieve_command_add_dynamic_tag
82929
 
+(struct sieve_command_context *cmd, const struct sieve_argument *tag, 
82930
 
+       int id_code)
82931
 
+{
82932
 
+       struct sieve_ast_argument *arg;
82933
 
+       
82934
 
+       if ( cmd->first_positional != NULL )
82935
 
+               arg = sieve_ast_argument_tag_insert
82936
 
+                       (cmd->first_positional, tag->identifier, cmd->ast_node->source_line);
82937
 
+       else
82938
 
+               arg = sieve_ast_argument_tag_create
82939
 
+                       (cmd->ast_node, tag->identifier, cmd->ast_node->source_line);
82940
 
+       
82941
 
+       arg->argument = tag;
82942
 
+       arg->arg_id_code = id_code;
82943
 
+       
82944
 
+       return arg;
82945
 
+}
82946
 
+
82947
 
+struct sieve_ast_argument *sieve_command_find_argument
82948
 
+(struct sieve_command_context *cmd, const struct sieve_argument *argument)
82949
 
+{
82950
 
+       struct sieve_ast_argument *arg = sieve_ast_argument_first(cmd->ast_node);
82951
 
+               
82952
 
+       /* Visit tagged and optional arguments */
82953
 
+       while ( arg != NULL ) {
82954
 
+               if ( arg->argument == argument ) 
82955
 
+                       return arg;
82956
 
+                       
82957
 
+               arg = sieve_ast_argument_next(arg);
82958
 
+       }
82959
 
+       
82960
 
+       return arg;
82961
 
+}
82962
 
+
82963
 
+/* Use this function with caution. The command commits to exiting the block.
82964
 
+ * When it for some reason does not, the interpretation will break later on, 
82965
 
+ * because exiting jumps are not generated when they would otherwise be 
82966
 
+ * necessary.
82967
 
+ */
82968
 
+void sieve_command_exit_block_unconditionally
82969
 
+       (struct sieve_command_context *cmd)
82970
 
+{
82971
 
+       struct sieve_command_context *parent = sieve_command_parent_context(cmd);
82972
 
+
82973
 
+       /* Only the first unconditional exit is of importance */
82974
 
+       if ( parent != NULL && parent->block_exit_command == NULL ) 
82975
 
+               parent->block_exit_command = cmd;
82976
 
+}
82977
 
+
82978
 
+bool sieve_command_block_exits_unconditionally
82979
 
+       (struct sieve_command_context *cmd)
82980
 
+{
82981
 
+       return ( cmd->block_exit_command != NULL );
82982
 
+}
82983
 
+
82984
 
+/*
82985
 
+ * Command utility functions
82986
 
+ */
82987
 
+
82988
 
+/* NOTE: this may be moved */
82989
 
+
82990
 
+static int _verify_header_name_item
82991
 
+(void *context, struct sieve_ast_argument *header)
82992
 
+{
82993
 
+       struct sieve_validator *valdtr = (struct sieve_validator *) context;
82994
 
+       string_t *name = sieve_ast_argument_str(header);
82995
 
+
82996
 
+       if ( sieve_argument_is_string_literal(header) &&
82997
 
+               !rfc2822_header_field_name_verify(str_c(name), str_len(name)) ) {
82998
 
+               sieve_argument_validate_warning
82999
 
+                       (valdtr, header, "specified header field name '%s' is invalid",
83000
 
+                               str_sanitize(str_c(name), 80));
83001
 
+
83002
 
+               return FALSE;
83003
 
+       }
83004
 
+
83005
 
+       return TRUE;
83006
 
+}
83007
 
+
83008
 
+bool sieve_command_verify_headers_argument
83009
 
+(struct sieve_validator *valdtr, struct sieve_ast_argument *headers)
83010
 
+{      
83011
 
+       return ( sieve_ast_stringlist_map
83012
 
+               (&headers, (void *) valdtr, _verify_header_name_item) >= 0 );
83013
 
+}
83014
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-commands.h dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-commands.h
83015
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-commands.h       1970-01-01 01:00:00.000000000 +0100
83016
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-commands.h        2009-02-14 09:32:55.000000000 +0100
83017
 
@@ -0,0 +1,221 @@
83018
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
83019
 
+ */
83020
 
+
83021
 
+#ifndef __SIEVE_COMMANDS_H
83022
 
+#define __SIEVE_COMMANDS_H
83023
 
+
83024
 
+#include "lib.h"
83025
 
+
83026
 
+#include "sieve-common.h"
83027
 
+#include "sieve-ast.h"
83028
 
+
83029
 
+/* 
83030
 
+ * Argument object
83031
 
+ */
83032
 
+
83033
 
+struct sieve_argument {
83034
 
+       const char *identifier;
83035
 
+       
83036
 
+       bool (*is_instance_of)
83037
 
+               (struct sieve_validator *validator, struct sieve_command_context *cmdctx,
83038
 
+                       struct sieve_ast_argument *arg);
83039
 
+       
83040
 
+       bool (*validate_persistent) // FIXME: this method must be moved down
83041
 
+               (struct sieve_validator *validator, struct sieve_command_context *cmdctx);
83042
 
+       bool (*validate)
83043
 
+               (struct sieve_validator *validator, struct sieve_ast_argument **arg, 
83044
 
+                       struct sieve_command_context *context);
83045
 
+       bool (*validate_context)
83046
 
+               (struct sieve_validator *validator, struct sieve_ast_argument *arg, 
83047
 
+                       struct sieve_command_context *context);
83048
 
+               
83049
 
+       bool (*generate)
83050
 
+               (const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, 
83051
 
+                       struct sieve_command_context *context);
83052
 
+};
83053
 
+
83054
 
+/* Utility macros */
83055
 
+
83056
 
+#define sieve_argument_is_string_literal(arg) \
83057
 
+       ( (arg)->argument == &string_argument )
83058
 
+
83059
 
+/* Error handling */
83060
 
+
83061
 
+#define sieve_argument_validate_error(validator, arg_node, ...) \
83062
 
+       sieve_validator_error(validator, (arg_node)->source_line, __VA_ARGS__)
83063
 
+#define sieve_argument_validate_warning(validator, arg_node, ...) \
83064
 
+       sieve_validator_warning(validator, (arg_node)->source_line, __VA_ARGS__)
83065
 
+
83066
 
+/* Literal arguments */
83067
 
+
83068
 
+extern const struct sieve_argument number_argument;
83069
 
+extern const struct sieve_argument string_argument;
83070
 
+extern const struct sieve_argument string_list_argument;
83071
 
+
83072
 
+/* Catenated string argument */
83073
 
+
83074
 
+bool sieve_arg_catenated_string_generate
83075
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, 
83076
 
+               struct sieve_command_context *context);
83077
 
+
83078
 
+struct sieve_arg_catenated_string;             
83079
 
+
83080
 
+struct sieve_arg_catenated_string *sieve_arg_catenated_string_create
83081
 
+       (struct sieve_ast_argument *orig_arg);
83082
 
+void sieve_arg_catenated_string_add_element
83083
 
+       (struct sieve_arg_catenated_string *strdata, 
83084
 
+               struct sieve_ast_argument *element);
83085
 
+
83086
 
+/* 
83087
 
+ * Command object
83088
 
+ */
83089
 
+
83090
 
+enum sieve_command_type {
83091
 
+       SCT_NONE,
83092
 
+       SCT_COMMAND,
83093
 
+       SCT_TEST,
83094
 
+       SCT_HYBRID
83095
 
+};
83096
 
+
83097
 
+struct sieve_command {
83098
 
+       const char *identifier;
83099
 
+       enum sieve_command_type type;
83100
 
+       
83101
 
+       /* High-level command syntax */
83102
 
+       int positional_arguments;
83103
 
+       int subtests;
83104
 
+       bool block_allowed;
83105
 
+       bool block_required;
83106
 
+       
83107
 
+       bool (*registered)
83108
 
+               (struct sieve_validator *validator, 
83109
 
+                       struct sieve_command_registration *cmd_reg); 
83110
 
+       bool (*pre_validate)
83111
 
+               (struct sieve_validator *validator, struct sieve_command_context *context); 
83112
 
+       bool (*validate)
83113
 
+               (struct sieve_validator *validator, struct sieve_command_context *context); 
83114
 
+       bool (*generate) 
83115
 
+               (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx);
83116
 
+       bool (*control_generate) 
83117
 
+               (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx,
83118
 
+               struct sieve_jumplist *jumps, bool jump_true);
83119
 
+};
83120
 
+
83121
 
+/*
83122
 
+ * Command context
83123
 
+ */
83124
 
+
83125
 
+struct sieve_command_context {
83126
 
+       const struct sieve_command *command;
83127
 
+       
83128
 
+       /* The registration of this command in the validator (sieve-validator.h) */
83129
 
+       struct sieve_command_registration *cmd_reg;
83130
 
+
83131
 
+       /* The ast node of this command */
83132
 
+       struct sieve_ast_node *ast_node;
83133
 
+                       
83134
 
+       /* First positional argument, found during argument validation */
83135
 
+       struct sieve_ast_argument *first_positional;
83136
 
+
83137
 
+       /* The child ast node that unconditionally exits this command's block */
83138
 
+       struct sieve_command_context *block_exit_command;
83139
 
+
83140
 
+       /* Command-specific context data*/
83141
 
+       void *data;
83142
 
+};
83143
 
+
83144
 
+/* Context API */
83145
 
+
83146
 
+struct sieve_command_context *sieve_command_context_create
83147
 
+       (struct sieve_ast_node *cmd_node, const struct sieve_command *command,
83148
 
+               struct sieve_command_registration *reg);
83149
 
+               
83150
 
+const char *sieve_command_type_name(const struct sieve_command *command);              
83151
 
+
83152
 
+struct sieve_command_context *sieve_command_prev_context       
83153
 
+       (struct sieve_command_context *context); 
83154
 
+struct sieve_command_context *sieve_command_parent_context     
83155
 
+       (struct sieve_command_context *context);
83156
 
+       
83157
 
+struct sieve_ast_argument *sieve_command_add_dynamic_tag
83158
 
+       (struct sieve_command_context *cmd, const struct sieve_argument *tag,
83159
 
+               int id_code);
83160
 
+struct sieve_ast_argument *sieve_command_find_argument
83161
 
+       (struct sieve_command_context *cmd, const struct sieve_argument *argument);     
83162
 
+       
83163
 
+void sieve_command_exit_block_unconditionally
83164
 
+       (struct sieve_command_context *cmd);
83165
 
+bool sieve_command_block_exits_unconditionally
83166
 
+       (struct sieve_command_context *cmd);
83167
 
+       
83168
 
+/* Error handling */
83169
 
+               
83170
 
+#define sieve_command_validate_error(validator, context, ...) \
83171
 
+       sieve_validator_error(validator, (context)->ast_node->source_line, __VA_ARGS__)
83172
 
+#define sieve_command_validate_warning(validator, context, ...) \
83173
 
+       sieve_validator_warning(validator, (context)->ast_node->source_line, __VA_ARGS__)
83174
 
+#define sieve_command_validate_critical(validator, context, ...) \
83175
 
+       sieve_validator_critical(validator, (context)->ast_node->source_line, __VA_ARGS__)
83176
 
+
83177
 
+#define sieve_command_generate_error(gentr, context, ...) \
83178
 
+       sieve_generator_error(gentr, (context)->ast_node->source_line, __VA_ARGS__)
83179
 
+#define sieve_command_generate_critical(gentr, context, ...) \
83180
 
+       sieve_generator_critical(gentr, (context)->ast_node->source_line, __VA_ARGS__)
83181
 
+
83182
 
+/* Utility macros */
83183
 
+
83184
 
+#define sieve_command_pool(context) \
83185
 
+       sieve_ast_node_pool((context)->ast_node)
83186
 
+
83187
 
+#define sieve_command_source_line(context) \
83188
 
+       (context)->ast_node->source_line
83189
 
+
83190
 
+#define sieve_command_first_argument(context) \
83191
 
+       sieve_ast_argument_first((context)->ast_node)
83192
 
+       
83193
 
+#define sieve_command_is_toplevel(context) \
83194
 
+       ( sieve_ast_node_type(sieve_ast_node_parent((context)->ast_node)) == SAT_ROOT )
83195
 
+#define sieve_command_is_first(context) \
83196
 
+       ( sieve_ast_node_prev((context)->ast_node) == NULL )    
83197
 
+
83198
 
+/*
83199
 
+ * Core commands
83200
 
+ */
83201
 
83202
 
+extern const struct sieve_command cmd_require;
83203
 
+extern const struct sieve_command cmd_stop;
83204
 
+extern const struct sieve_command cmd_if;
83205
 
+extern const struct sieve_command cmd_elsif;
83206
 
+extern const struct sieve_command cmd_else;
83207
 
+extern const struct sieve_command cmd_redirect;
83208
 
+extern const struct sieve_command cmd_keep;
83209
 
+extern const struct sieve_command cmd_discard;
83210
 
+
83211
 
+extern const struct sieve_command *sieve_core_commands[];
83212
 
+extern const unsigned int sieve_core_commands_count;
83213
 
+
83214
 
+/* 
83215
 
+ * Core tests 
83216
 
+ */
83217
 
+
83218
 
+extern const struct sieve_command tst_true;
83219
 
+extern const struct sieve_command tst_false;
83220
 
+extern const struct sieve_command tst_not;
83221
 
+extern const struct sieve_command tst_anyof;
83222
 
+extern const struct sieve_command tst_allof;
83223
 
+extern const struct sieve_command tst_address;
83224
 
+extern const struct sieve_command tst_header;
83225
 
+extern const struct sieve_command tst_exists;
83226
 
+extern const struct sieve_command tst_size;
83227
 
+
83228
 
+extern const struct sieve_command *sieve_core_tests[];
83229
 
+extern const unsigned int sieve_core_tests_count;
83230
 
+
83231
 
+/*
83232
 
+ * Command utility functions
83233
 
+ */
83234
 
+
83235
 
+bool sieve_command_verify_headers_argument
83236
 
+(struct sieve_validator *valdtr, struct sieve_ast_argument *headers);
83237
 
+
83238
 
+#endif /* __SIEVE_COMMANDS_H */
83239
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-common.h dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-common.h
83240
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-common.h 1970-01-01 01:00:00.000000000 +0100
83241
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-common.h  2009-08-05 08:59:18.000000000 +0200
83242
 
@@ -0,0 +1,123 @@
83243
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
83244
 
+ */
83245
 
+
83246
 
+#ifndef __SIEVE_COMMON_H
83247
 
+#define __SIEVE_COMMON_H
83248
 
+
83249
 
+#include "sieve-config.h"
83250
 
+#include "sieve-types.h"
83251
 
+
83252
 
+#include <sys/types.h>
83253
 
+
83254
 
+/* 
83255
 
+ * Types
83256
 
+ */
83257
 
+
83258
 
+typedef size_t        sieve_size_t; 
83259
 
+typedef uint32_t      sieve_offset_t;
83260
 
+typedef uint32_t      sieve_number_t;
83261
 
+
83262
 
+#define SIEVE_MAX_NUMBER ((sieve_number_t) -1)
83263
 
+
83264
 
+/*
83265
 
+ * Forward declarations
83266
 
+ */
83267
 
+
83268
 
+/* sieve-error.h */
83269
 
+struct sieve_error_handler;
83270
 
+
83271
 
+/* sieve-ast.h */
83272
 
+enum sieve_ast_argument_type;
83273
 
+
83274
 
+struct sieve_ast;
83275
 
+struct sieve_ast_node;
83276
 
+struct sieve_ast_argument;
83277
 
+
83278
 
+/* sieve-commands.h */
83279
 
+struct sieve_argument;
83280
 
+struct sieve_command;
83281
 
+struct sieve_command_context;
83282
 
+struct sieve_command_registration;
83283
 
+
83284
 
+/* sieve-code.h */
83285
 
+struct sieve_operation_extension;
83286
 
+
83287
 
+/* sieve-lexer.h */
83288
 
+struct sieve_lexer;
83289
 
+
83290
 
+/* sieve-parser.h */
83291
 
+struct sieve_parser;
83292
 
+
83293
 
+/* sieve-validator.h */
83294
 
+struct sieve_validator;
83295
 
+
83296
 
+/* sieve-generator.h */
83297
 
+struct sieve_jumplist;
83298
 
+struct sieve_generator;
83299
 
+struct sieve_codegen_env;
83300
 
+
83301
 
+/* sieve-interpreter.h */
83302
 
+struct sieve_runtime_env;
83303
 
+struct sieve_interpreter;
83304
 
+
83305
 
+/* sieve-binary-dumper.h */
83306
 
+struct sieve_dumptime_env;
83307
 
+struct sieve_binary_dumper;
83308
 
+
83309
 
+/* sieve-code-dumper.h */
83310
 
+struct sieve_code_dumper;
83311
 
+
83312
 
+/* sieve-extension.h */
83313
 
+struct sieve_extension;
83314
 
+struct sieve_extension_objects;
83315
 
+
83316
 
+/* sieve-code.h */
83317
 
+struct sieve_operand;
83318
 
+struct sieve_operand_class;
83319
 
+struct sieve_operation;
83320
 
+struct sieve_coded_stringlist;
83321
 
+
83322
 
+/* sieve-binary.h */
83323
 
+struct sieve_binary;
83324
 
+
83325
 
+/* sieve-objects.h */
83326
 
+struct sieve_object;
83327
 
+
83328
 
+/* sieve-comparator.h */
83329
 
+struct sieve_comparator;
83330
 
+
83331
 
+/* sieve-match-types.h */
83332
 
+struct sieve_match_type;
83333
 
+
83334
 
+/* sieve-match.h */
83335
 
+struct sieve_match_context;
83336
 
+
83337
 
+/* sieve-address.h */
83338
 
+struct sieve_address;
83339
 
+
83340
 
+/* sieve-address-parts.h */
83341
 
+struct sieve_address_part;
83342
 
+
83343
 
+/* sieve-result.h */
83344
 
+struct sieve_result;
83345
 
+struct sieve_side_effects_list;
83346
 
+struct sieve_result_print_env;
83347
 
+
83348
 
+/* sieve-actions.h */
83349
 
+struct sieve_action_exec_env;
83350
 
+struct sieve_action;
83351
 
+struct sieve_side_effect;
83352
 
+
83353
 
+/* sieve-script.h */
83354
 
+struct sieve_script;
83355
 
+
83356
 
+/* sieve-message.h */
83357
 
+struct sieve_message_context;
83358
 
+
83359
 
+/* sieve.c */
83360
 
+struct sieve_ast *sieve_parse
83361
 
+       (struct sieve_script *script, struct sieve_error_handler *ehandler);
83362
 
+bool sieve_validate
83363
 
+       (struct sieve_ast *ast, struct sieve_error_handler *ehandler);  
83364
 
+
83365
 
+#endif /* __SIEVE_COMMON_H */
83366
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-comparators.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-comparators.c
83367
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-comparators.c    1970-01-01 01:00:00.000000000 +0100
83368
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-comparators.c     2009-01-06 00:15:52.000000000 +0100
83369
 
@@ -0,0 +1,272 @@
83370
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file 
83371
 
+ */
83372
 
+
83373
 
+#include "lib.h"
83374
 
+#include "str-sanitize.h"
83375
 
+#include "hash.h"
83376
 
+#include "array.h"
83377
 
+
83378
 
+#include "sieve-extensions.h"
83379
 
+#include "sieve-code.h"
83380
 
+#include "sieve-commands.h"
83381
 
+#include "sieve-binary.h"
83382
 
+#include "sieve-validator.h"
83383
 
+#include "sieve-generator.h"
83384
 
+#include "sieve-interpreter.h"
83385
 
+#include "sieve-dump.h"
83386
 
+
83387
 
+#include "sieve-comparators.h"
83388
 
+
83389
 
+#include <string.h>
83390
 
+#include <stdio.h>
83391
 
+
83392
 
+/* 
83393
 
+ * Core comparators
83394
 
+ */
83395
 
83396
 
+const struct sieve_comparator *sieve_core_comparators[] = {
83397
 
+       &i_octet_comparator, &i_ascii_casemap_comparator
83398
 
+};
83399
 
+
83400
 
+const unsigned int sieve_core_comparators_count =
83401
 
+       N_ELEMENTS(sieve_core_comparators);
83402
 
+
83403
 
+/*
83404
 
+ * Forward declarations
83405
 
+ */
83406
 
83407
 
+static void sieve_opr_comparator_emit
83408
 
+       (struct sieve_binary *sbin, const struct sieve_comparator *cmp);
83409
 
+
83410
 
+/* 
83411
 
+ * Comparator 'extension' 
83412
 
+ */
83413
 
+
83414
 
+static int ext_my_id = -1;
83415
 
+
83416
 
+static bool cmp_validator_load(struct sieve_validator *validator);
83417
 
+
83418
 
+const struct sieve_extension comparator_extension = {
83419
 
+       "@comparators",
83420
 
+       &ext_my_id,
83421
 
+       NULL, NULL,
83422
 
+       cmp_validator_load,
83423
 
+       NULL, NULL, NULL, NULL, NULL,
83424
 
+       SIEVE_EXT_DEFINE_NO_OPERATIONS,
83425
 
+       SIEVE_EXT_DEFINE_NO_OPERANDS    /* Defined as core operand */
83426
 
+};
83427
 
+
83428
 
+static const struct sieve_extension *ext_this = &comparator_extension;
83429
 
+       
83430
 
+/* 
83431
 
+ * Validator context:
83432
 
+ *   name-based comparator registry. 
83433
 
+ */
83434
 
83435
 
+void sieve_comparator_register
83436
 
+(struct sieve_validator *validator, const struct sieve_comparator *cmp) 
83437
 
+{
83438
 
+       struct sieve_validator_object_registry *regs = 
83439
 
+               sieve_validator_object_registry_get(validator, ext_this);
83440
 
+       
83441
 
+       sieve_validator_object_registry_add(regs, &cmp->object);
83442
 
+}
83443
 
+
83444
 
+const struct sieve_comparator *sieve_comparator_find
83445
 
+(struct sieve_validator *validator, const char *identifier) 
83446
 
+{
83447
 
+       struct sieve_validator_object_registry *regs = 
83448
 
+               sieve_validator_object_registry_get(validator, ext_this);
83449
 
+       const struct sieve_object *object = 
83450
 
+               sieve_validator_object_registry_find(regs, identifier);
83451
 
+
83452
 
+  return (const struct sieve_comparator *) object;
83453
 
+}
83454
 
+
83455
 
+bool cmp_validator_load(struct sieve_validator *validator)
83456
 
+{
83457
 
+       struct sieve_validator_object_registry *regs = 
83458
 
+               sieve_validator_object_registry_init(validator, ext_this);
83459
 
+       unsigned int i;
83460
 
+               
83461
 
+       /* Register core comparators */
83462
 
+       for ( i = 0; i < sieve_core_comparators_count; i++ ) {
83463
 
+               sieve_validator_object_registry_add
83464
 
+                       (regs, &(sieve_core_comparators[i]->object));
83465
 
+       }
83466
 
+
83467
 
+       return TRUE;
83468
 
+}
83469
 
+
83470
 
+/* 
83471
 
+ * Comparator tagged argument 
83472
 
+ */
83473
 
83474
 
+/* Context data */
83475
 
+
83476
 
+struct sieve_comparator_context {
83477
 
+       struct sieve_command_context *command_ctx;
83478
 
+       const struct sieve_comparator *comparator;
83479
 
+};
83480
 
83481
 
+/* Forward declarations */
83482
 
+
83483
 
+static bool tag_comparator_validate
83484
 
+       (struct sieve_validator *validator, struct sieve_ast_argument **arg, 
83485
 
+       struct sieve_command_context *cmd);
83486
 
+static bool tag_comparator_generate
83487
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, 
83488
 
+       struct sieve_command_context *cmd);
83489
 
+
83490
 
+/* Argument object */
83491
 
+
83492
 
+const struct sieve_argument comparator_tag = { 
83493
 
+       "comparator", 
83494
 
+       NULL, NULL,
83495
 
+       tag_comparator_validate, 
83496
 
+       NULL,
83497
 
+       tag_comparator_generate 
83498
 
+};
83499
 
+
83500
 
+/* Argument implementation */
83501
 
+
83502
 
+static bool tag_comparator_validate
83503
 
+       (struct sieve_validator *validator, struct sieve_ast_argument **arg, 
83504
 
+       struct sieve_command_context *cmd)
83505
 
+{
83506
 
+       struct sieve_comparator_context *cmpctx;
83507
 
+       struct sieve_ast_argument *tag = *arg;
83508
 
+       const struct sieve_comparator *cmp;
83509
 
+       
83510
 
+       /* Skip tag */
83511
 
+       *arg = sieve_ast_argument_next(*arg);
83512
 
+       
83513
 
+       /* Check syntax:
83514
 
+        *   ":comparator" <comparator-name: string>
83515
 
+        */
83516
 
+       if ( (*arg)->type != SAAT_STRING ) {
83517
 
+               sieve_argument_validate_error(validator, *arg, 
83518
 
+                       ":comparator tag requires one string argument, but %s was found", 
83519
 
+                       sieve_ast_argument_name(*arg) );
83520
 
+               return FALSE;
83521
 
+       }
83522
 
+
83523
 
+       if ( !sieve_validator_argument_activate(validator, cmd, *arg, FALSE) )
83524
 
+               return FALSE;
83525
 
+
83526
 
+       /* FIXME: We can currently only handle string literal argument, so
83527
 
+        * variables are not allowed.
83528
 
+        */
83529
 
+       if ( !sieve_argument_is_string_literal(*arg) ) {
83530
 
+               sieve_argument_validate_error(validator, *arg, 
83531
 
+                       "this Sieve implementation currently only supports "
83532
 
+                       "a literal string argument for the :comparator tag");
83533
 
+               return FALSE;
83534
 
+       }
83535
 
+       
83536
 
+       /* Get comparator from registry */
83537
 
+       cmp = sieve_comparator_find(validator, sieve_ast_argument_strc(*arg));
83538
 
+       
83539
 
+       if ( cmp == NULL ) {
83540
 
+               sieve_argument_validate_error(validator, *arg, 
83541
 
+                       "unknown comparator '%s'", 
83542
 
+                       str_sanitize(sieve_ast_argument_strc(*arg),80));
83543
 
+
83544
 
+               return FALSE;
83545
 
+       }
83546
 
+       
83547
 
+       /* String argument not needed during code generation, so detach it from 
83548
 
+        * argument list 
83549
 
+        */
83550
 
+       *arg = sieve_ast_arguments_detach(*arg, 1);
83551
 
+
83552
 
+       /* Create context */
83553
 
+       cmpctx = p_new(sieve_command_pool(cmd), struct sieve_comparator_context, 1);
83554
 
+       cmpctx->command_ctx = cmd;
83555
 
+       cmpctx->comparator = cmp;
83556
 
+
83557
 
+       /* Store comparator in context */
83558
 
+       tag->context = (void *) cmpctx;
83559
 
+       
83560
 
+       return TRUE;
83561
 
+}
83562
 
+
83563
 
+static bool tag_comparator_generate
83564
 
+(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, 
83565
 
+       struct sieve_command_context *cmd ATTR_UNUSED)
83566
 
+{
83567
 
+       struct sieve_comparator_context *cmpctx = 
83568
 
+               (struct sieve_comparator_context *) arg->context;
83569
 
+       const struct sieve_comparator *cmp = cmpctx->comparator;
83570
 
+       
83571
 
+       sieve_opr_comparator_emit(cgenv->sbin, cmp);
83572
 
+               
83573
 
+       return TRUE;
83574
 
+}
83575
 
+
83576
 
+/* Functions to enable and evaluate comparator tag for commands */
83577
 
+
83578
 
+void sieve_comparators_link_tag
83579
 
+(struct sieve_validator *validator, struct sieve_command_registration *cmd_reg,        
83580
 
+       int id_code) 
83581
 
+{
83582
 
+       sieve_validator_register_tag(validator, cmd_reg, &comparator_tag, id_code);     
83583
 
+}
83584
 
+
83585
 
+bool sieve_comparator_tag_is
83586
 
+(struct sieve_ast_argument *tag, const struct sieve_comparator *cmp)
83587
 
+{
83588
 
+       const struct sieve_comparator_context *cmpctx = 
83589
 
+               (const struct sieve_comparator_context *) tag->context;
83590
 
+
83591
 
+       if ( cmpctx == NULL ) return FALSE;
83592
 
+       
83593
 
+       return ( tag->argument == &comparator_tag && cmpctx->comparator == cmp );
83594
 
+}
83595
 
+
83596
 
+const struct sieve_comparator *sieve_comparator_tag_get
83597
 
+(struct sieve_ast_argument *tag)
83598
 
+{
83599
 
+       const struct sieve_comparator_context *cmpctx;
83600
 
+       
83601
 
+       if ( tag->argument != &comparator_tag ) 
83602
 
+               return NULL;
83603
 
+               
83604
 
+       cmpctx = (const struct sieve_comparator_context *) tag->context;
83605
 
+                
83606
 
+       return cmpctx->comparator;
83607
 
+}
83608
 
+
83609
 
+/*
83610
 
+ * Comparator coding
83611
 
+ */
83612
 
83613
 
+const struct sieve_operand_class sieve_comparator_operand_class = 
83614
 
+       { "comparator" };
83615
 
+       
83616
 
+static const struct sieve_extension_objects core_comparators =
83617
 
+       SIEVE_EXT_DEFINE_COMPARATORS(sieve_core_comparators);
83618
 
+
83619
 
+const struct sieve_operand comparator_operand = { 
83620
 
+       "comparator", 
83621
 
+       NULL,
83622
 
+       SIEVE_OPERAND_COMPARATOR, 
83623
 
+       &sieve_comparator_operand_class,
83624
 
+       &core_comparators
83625
 
+};
83626
 
+
83627
 
+/*
83628
 
+ * Trivial/Common comparator method implementations
83629
 
+ */
83630
 
+
83631
 
+bool sieve_comparator_octet_skip
83632
 
+       (const struct sieve_comparator *cmp ATTR_UNUSED, 
83633
 
+               const char **val, const char *val_end)
83634
 
+{
83635
 
+       if ( *val < val_end ) {
83636
 
+               (*val)++;
83637
 
+               return TRUE;
83638
 
+       }
83639
 
+       
83640
 
+       return FALSE;
83641
 
+}
83642
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-comparators.h dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-comparators.h
83643
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-comparators.h    1970-01-01 01:00:00.000000000 +0100
83644
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-comparators.h     2009-01-06 00:15:52.000000000 +0100
83645
 
@@ -0,0 +1,124 @@
83646
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file 
83647
 
+ */
83648
 
83649
 
+#ifndef __SIEVE_COMPARATORS_H
83650
 
+#define __SIEVE_COMPARATORS_H
83651
 
+
83652
 
+#include "sieve-common.h"
83653
 
+#include "sieve-extensions.h"
83654
 
+#include "sieve-commands.h"
83655
 
+#include "sieve-objects.h"
83656
 
+#include "sieve-code.h"
83657
 
+
83658
 
+/* 
83659
 
+ * Core comparators 
83660
 
+ */
83661
 
83662
 
+enum sieve_comparator_code {
83663
 
+       SIEVE_COMPARATOR_I_OCTET,
83664
 
+       SIEVE_COMPARATOR_I_ASCII_CASEMAP,
83665
 
+       SIEVE_COMPARATOR_CUSTOM
83666
 
+};
83667
 
+
83668
 
+extern const struct sieve_comparator i_octet_comparator;
83669
 
+extern const struct sieve_comparator i_ascii_casemap_comparator;
83670
 
+
83671
 
+/*
83672
 
+ * Comparator flags
83673
 
+ */
83674
 
+
83675
 
+enum sieve_comparator_flags {
83676
 
+       SIEVE_COMPARATOR_FLAG_ORDERING = (1 << 0),
83677
 
+       SIEVE_COMPARATOR_FLAG_EQUALITY = (1 << 1),
83678
 
+       SIEVE_COMPARATOR_FLAG_PREFIX_MATCH = (1 << 2),
83679
 
+       SIEVE_COMPARATOR_FLAG_SUBSTRING_MATCH = (1 << 3),       
83680
 
+};
83681
 
+
83682
 
+/*
83683
 
+ * Comparator object
83684
 
+ */
83685
 
+
83686
 
+struct sieve_comparator {
83687
 
+       struct sieve_object object;     
83688
 
+               
83689
 
+       unsigned int flags;
83690
 
+       
83691
 
+       /* Equality and ordering */
83692
 
+
83693
 
+       int (*compare)(const struct sieve_comparator *cmp, 
83694
 
+               const char *val1, size_t val1_size, 
83695
 
+               const char *val2, size_t val2_size);
83696
 
+       
83697
 
+       /* Prefix and substring match */
83698
 
+       
83699
 
+       bool (*char_match)(const struct sieve_comparator *cmp, 
83700
 
+               const char **val, const char *val_end,
83701
 
+               const char **key, const char *key_end);
83702
 
+       bool (*char_skip)(const struct sieve_comparator *cmp, 
83703
 
+               const char **val, const char *val_end);
83704
 
+};
83705
 
+
83706
 
+/*
83707
 
+ * Comparator tagged argument
83708
 
+ */
83709
 
83710
 
+extern const struct sieve_argument comparator_tag;
83711
 
+
83712
 
+static inline bool sieve_argument_is_comparator
83713
 
+       (struct sieve_ast_argument *arg) 
83714
 
+{
83715
 
+       return arg->argument == &comparator_tag;
83716
 
+}
83717
 
+
83718
 
+void sieve_comparators_link_tag
83719
 
+       (struct sieve_validator *validator, 
83720
 
+               struct sieve_command_registration *cmd_reg,     int id_code);
83721
 
+bool sieve_comparator_tag_is
83722
 
+       (struct sieve_ast_argument *tag, const struct sieve_comparator *cmp);
83723
 
+const struct sieve_comparator *sieve_comparator_tag_get
83724
 
+       (struct sieve_ast_argument *tag);
83725
 
+
83726
 
+void sieve_comparator_register
83727
 
+       (struct sieve_validator *validator, const struct sieve_comparator *cmp); 
83728
 
+const struct sieve_comparator *sieve_comparator_find
83729
 
+       (struct sieve_validator *validator, const char *identifier);
83730
 
+               
83731
 
+/*
83732
 
+ * Comparator operand
83733
 
+ */
83734
 
+
83735
 
+#define SIEVE_EXT_DEFINE_COMPARATOR(OP) SIEVE_EXT_DEFINE_OBJECT(OP)
83736
 
+#define SIEVE_EXT_DEFINE_COMPARATORS(OPS) SIEVE_EXT_DEFINE_OBJECTS(OPS)
83737
 
+
83738
 
+extern const struct sieve_operand_class sieve_comparator_operand_class;
83739
 
+extern const struct sieve_operand comparator_operand;
83740
 
+
83741
 
+static inline void sieve_opr_comparator_emit
83742
 
+(struct sieve_binary *sbin, const struct sieve_comparator *cmp)
83743
 
+{ 
83744
 
+       sieve_opr_object_emit(sbin, &cmp->object);
83745
 
+}
83746
 
+
83747
 
+static inline const struct sieve_comparator *sieve_opr_comparator_read
83748
 
+(const struct sieve_runtime_env *renv, sieve_size_t *address)
83749
 
+{
83750
 
+       return (const struct sieve_comparator *) sieve_opr_object_read
83751
 
+               (renv, &sieve_comparator_operand_class, address);
83752
 
+}
83753
 
+
83754
 
+static inline bool sieve_opr_comparator_dump
83755
 
+(const struct sieve_dumptime_env *denv, sieve_size_t *address)
83756
 
+{
83757
 
+       return sieve_opr_object_dump
83758
 
+               (denv, &sieve_comparator_operand_class, address, NULL);
83759
 
+}
83760
 
+       
83761
 
+/*
83762
 
+ * Trivial/Common comparator method implementations
83763
 
+ */
83764
 
+
83765
 
+bool sieve_comparator_octet_skip
83766
 
+       (const struct sieve_comparator *cmp ATTR_UNUSED, 
83767
 
+               const char **val, const char *val_end);
83768
 
+
83769
 
+#endif /* __SIEVE_COMPARATORS_H */
83770
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-config.h dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-config.h
83771
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-config.h 1970-01-01 01:00:00.000000000 +0100
83772
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-config.h  2009-01-06 00:15:52.000000000 +0100
83773
 
@@ -0,0 +1,11 @@
83774
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file 
83775
 
+ */
83776
 
+
83777
 
+#ifndef __SIEVE_CONFIG_H
83778
 
+#define __SIEVE_CONFIG_H
83779
 
+
83780
 
+#include "dsieve-config.h"
83781
 
+
83782
 
+#define SIEVE_IMPLEMENTATION SIEVE_NAME " " SIEVE_VERSION
83783
 
+
83784
 
+#endif
83785
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-dump.h dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-dump.h
83786
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-dump.h   1970-01-01 01:00:00.000000000 +0100
83787
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-dump.h    2009-01-06 00:15:52.000000000 +0100
83788
 
@@ -0,0 +1,24 @@
83789
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
83790
 
+ */
83791
 
+
83792
 
+#ifndef __SIEVE_DUMP_H
83793
 
+#define __SIEVE_DUMP_H
83794
 
+
83795
 
+#include "sieve-common.h"
83796
 
+
83797
 
+#include "sieve-binary-dumper.h"
83798
 
+#include "sieve-code-dumper.h"
83799
 
+
83800
 
+/*
83801
 
+ * Dumptime environment
83802
 
+ */
83803
 
+
83804
 
+struct sieve_dumptime_env {
83805
 
+       struct sieve_binary_dumper *dumper;
83806
 
+       struct sieve_code_dumper *cdumper;
83807
 
+       struct sieve_binary *sbin;
83808
 
+       
83809
 
+       struct ostream *stream;
83810
 
+};
83811
 
+
83812
 
+#endif /* __SIEVE_DUMP_H */
83813
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-error.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-error.c
83814
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-error.c  1970-01-01 01:00:00.000000000 +0100
83815
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-error.c   2009-08-21 00:52:15.000000000 +0200
83816
 
@@ -0,0 +1,699 @@
83817
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
83818
 
+ */
83819
 
83820
 
+#include "lib.h"
83821
 
+#include "str.h"
83822
 
+#include "ostream.h"
83823
 
+#include "eacces-error.h"
83824
 
+
83825
 
+#include "sieve-common.h"
83826
 
+#include "sieve-script.h"
83827
 
+#include "sieve-error-private.h"
83828
 
+
83829
 
+#include <sys/types.h>
83830
 
+#include <sys/stat.h>
83831
 
+#include <fcntl.h>
83832
 
+#include <stdlib.h>
83833
 
+#include <unistd.h>
83834
 
+#include <stdio.h>
83835
 
+
83836
 
+/*
83837
 
+ * Definitions
83838
 
+ */
83839
 
+
83840
 
+#define CRITICAL_MSG \
83841
 
+       "internal error occurred: refer to server log for more information."
83842
 
+#define CRITICAL_MSG_STAMP CRITICAL_MSG " [%Y-%m-%d %H:%M:%S]"
83843
 
+
83844
 
+/* Logfile error handler will rotate log when it exceeds 10k bytes */
83845
 
+#define LOGFILE_MAX_SIZE (10 * 1024)
83846
 
+
83847
 
+/*
83848
 
+ * Utility
83849
 
+ */
83850
 
+
83851
 
+const char *sieve_error_script_location
83852
 
+(const struct sieve_script *script, unsigned int source_line)
83853
 
+{
83854
 
+    const char *sname;
83855
 
+
83856
 
+       sname = ( script == NULL ? NULL : sieve_script_name(script) );
83857
 
+
83858
 
+    if ( sname == NULL || *sname == '\0' )
83859
 
+        return t_strdup_printf("line %d", source_line);
83860
 
+
83861
 
+    return t_strdup_printf("%s: line %d", sname, source_line);
83862
 
+}
83863
 
+
83864
 
+/*
83865
 
+ * Main error functions
83866
 
+ */
83867
 
+
83868
 
+void sieve_verror
83869
 
+       (struct sieve_error_handler *ehandler, const char *location, 
83870
 
+               const char *fmt, va_list args)
83871
 
+{
83872
 
+       if ( ehandler == NULL ) return;
83873
 
+       
83874
 
+       if ( ehandler->log_master ) {
83875
 
+               va_list args_copy;
83876
 
+
83877
 
+               VA_COPY(args_copy, args);
83878
 
+
83879
 
+               if ( location == NULL || *location == '\0' )
83880
 
+                       sieve_sys_error("%s", t_strdup_vprintf(fmt, args_copy));
83881
 
+               else
83882
 
+                       sieve_sys_error("%s: %s", location, t_strdup_vprintf(fmt, args_copy));
83883
 
+       }
83884
 
+
83885
 
+       if ( sieve_errors_more_allowed(ehandler) ) {
83886
 
+               if ( ehandler->verror != NULL )
83887
 
+                       ehandler->verror(ehandler, location, fmt, args);
83888
 
+               
83889
 
+               if ( ehandler->pool != NULL )
83890
 
+                       ehandler->errors++;
83891
 
+       }
83892
 
+}
83893
 
+
83894
 
+void sieve_vwarning
83895
 
+       (struct sieve_error_handler *ehandler, const char *location, 
83896
 
+               const char *fmt, va_list args)
83897
 
+{
83898
 
+       if ( ehandler == NULL ) return;
83899
 
+
83900
 
+       if ( ehandler->log_master ) {
83901
 
+               va_list args_copy;
83902
 
+
83903
 
+               VA_COPY(args_copy, args);
83904
 
+
83905
 
+               if ( location == NULL || *location == '\0' )
83906
 
+                       sieve_sys_warning("%s", t_strdup_vprintf(fmt, args_copy));
83907
 
+               else
83908
 
+                       sieve_sys_warning("%s: %s", location, t_strdup_vprintf(fmt, args_copy));
83909
 
+       }
83910
 
+       
83911
 
+       if ( ehandler->vwarning != NULL )       
83912
 
+               ehandler->vwarning(ehandler, location, fmt, args);
83913
 
+
83914
 
+       if ( ehandler->pool != NULL )
83915
 
+               ehandler->warnings++;
83916
 
+}
83917
 
+
83918
 
+void sieve_vinfo
83919
 
+       (struct sieve_error_handler *ehandler, const char *location, 
83920
 
+               const char *fmt, va_list args)
83921
 
+{
83922
 
+       if ( ehandler == NULL ) return;
83923
 
+
83924
 
+       if ( ehandler->log_master ) {
83925
 
+               va_list args_copy;
83926
 
+
83927
 
+               VA_COPY(args_copy, args);
83928
 
+
83929
 
+
83930
 
+               if ( location == NULL || *location == '\0' )
83931
 
+                       sieve_sys_info("%s", t_strdup_vprintf(fmt, args_copy));
83932
 
+               else    
83933
 
+                       sieve_sys_info("%s: %s", location, t_strdup_vprintf(fmt, args_copy));
83934
 
+       }
83935
 
+       
83936
 
+       if ( ehandler->log_info && ehandler->vinfo != NULL )    
83937
 
+               ehandler->vinfo(ehandler, location, fmt, args);
83938
 
+}
83939
 
+
83940
 
+void sieve_vcritical
83941
 
+       (struct sieve_error_handler *ehandler, const char *location, 
83942
 
+               const char *fmt, va_list args)
83943
 
+{
83944
 
+       char str[256];
83945
 
+       struct tm *tm; 
83946
 
+       
83947
 
+       tm = localtime(&ioloop_time);
83948
 
+       
83949
 
+       if ( location == NULL || *location == '\0' )
83950
 
+               sieve_sys_error("%s", t_strdup_vprintf(fmt, args));
83951
 
+       else
83952
 
+               sieve_sys_error("%s: %s", location, t_strdup_vprintf(fmt, args));
83953
 
+               
83954
 
+       if ( ehandler == NULL ) return;
83955
 
+       
83956
 
+       sieve_error(ehandler, location, "%s", 
83957
 
+               strftime(str, sizeof(str), CRITICAL_MSG_STAMP, tm) > 0 ? 
83958
 
+                       str : CRITICAL_MSG );   
83959
 
+}
83960
 
+
83961
 
+/*
83962
 
+ * Error statistics
83963
 
+ */
83964
 
+
83965
 
+unsigned int sieve_get_errors(struct sieve_error_handler *ehandler) 
83966
 
+{
83967
 
+       if ( ehandler == NULL || ehandler->pool == NULL ) return 0;
83968
 
+       
83969
 
+       return ehandler->errors;
83970
 
+}
83971
 
+
83972
 
+unsigned int sieve_get_warnings(struct sieve_error_handler *ehandler) 
83973
 
+{
83974
 
+       if ( ehandler == NULL || ehandler->pool == NULL ) return 0;
83975
 
+
83976
 
+       return ehandler->errors;
83977
 
+}
83978
 
+
83979
 
+bool sieve_errors_more_allowed(struct sieve_error_handler *ehandler) 
83980
 
+{
83981
 
+       if ( ehandler == NULL || ehandler->pool == NULL ) 
83982
 
+               return TRUE;
83983
 
+
83984
 
+       return ehandler->max_errors == 0 || ehandler->errors < ehandler->max_errors;
83985
 
+}
83986
 
+
83987
 
+/*
83988
 
+ * Error handler configuration
83989
 
+ */
83990
 
+
83991
 
+void sieve_error_handler_accept_infolog
83992
 
+       (struct sieve_error_handler *ehandler, bool enable)
83993
 
+{
83994
 
+       ehandler->log_info = enable;    
83995
 
+}
83996
 
+
83997
 
+void sieve_error_handler_copy_masterlog
83998
 
+       (struct sieve_error_handler *ehandler, bool enable)
83999
 
+{
84000
 
+       ehandler->log_master = enable;
84001
 
+}
84002
 
+
84003
 
+/*
84004
 
+ * Error handler init
84005
 
+ */
84006
 
+
84007
 
+void sieve_error_handler_init
84008
 
+       (struct sieve_error_handler *ehandler, pool_t pool, unsigned int max_errors)
84009
 
+{
84010
 
+       ehandler->pool = pool;
84011
 
+       ehandler->refcount = 1;
84012
 
+       ehandler->max_errors = max_errors;
84013
 
+       
84014
 
+       ehandler->errors = 0;
84015
 
+       ehandler->warnings = 0;
84016
 
+}
84017
 
+
84018
 
+void sieve_error_handler_ref(struct sieve_error_handler *ehandler)
84019
 
+{
84020
 
+       if ( ehandler == NULL || ehandler->pool == NULL ) return;
84021
 
+
84022
 
+       ehandler->refcount++;
84023
 
+}
84024
 
+
84025
 
+void sieve_error_handler_unref(struct sieve_error_handler **ehandler)
84026
 
+{
84027
 
+       if ( *ehandler == NULL || (*ehandler)->pool == NULL ) return;
84028
 
+
84029
 
+       i_assert((*ehandler)->refcount > 0);
84030
 
+
84031
 
+       if (--(*ehandler)->refcount != 0)
84032
 
+               return;
84033
 
+
84034
 
+       if ( (*ehandler)->free != NULL )
84035
 
+               (*ehandler)->free(*ehandler);
84036
 
+
84037
 
+       pool_unref(&((*ehandler)->pool));
84038
 
+
84039
 
+       *ehandler = NULL;
84040
 
+}
84041
 
+
84042
 
+void sieve_error_handler_reset(struct sieve_error_handler *ehandler)
84043
 
+{
84044
 
+       if ( ehandler == NULL || ehandler->pool == NULL ) return;
84045
 
+
84046
 
+       ehandler->errors = 0;
84047
 
+       ehandler->warnings = 0;
84048
 
+}
84049
 
+
84050
 
+/* 
84051
 
+ * Master/System error handler
84052
 
+ *
84053
 
+ * - Output errors directly to Dovecot master log
84054
 
+ */
84055
 
+
84056
 
+static void sieve_master_verror
84057
 
+(struct sieve_error_handler *ehandler, const char *location, 
84058
 
+       const char *fmt, va_list args) 
84059
 
+{
84060
 
+       if ( ehandler->log_master ) return;
84061
 
+
84062
 
+       if ( location == NULL || *location == '\0' )
84063
 
+               i_error("sieve: %s", t_strdup_vprintf(fmt, args));
84064
 
+       else
84065
 
+               i_error("sieve: %s: %s", location, t_strdup_vprintf(fmt, args));
84066
 
+}
84067
 
+
84068
 
+static void sieve_master_vwarning
84069
 
+(struct sieve_error_handler *ehandler ATTR_UNUSED, const char *location, 
84070
 
+       const char *fmt, va_list args) 
84071
 
+{
84072
 
+       if ( ehandler->log_master ) return;
84073
 
+
84074
 
+       if ( location == NULL || *location == '\0' )
84075
 
+               i_warning("sieve: %s", t_strdup_vprintf(fmt, args));
84076
 
+       else
84077
 
+               i_warning("sieve: %s: %s", location, t_strdup_vprintf(fmt, args));
84078
 
+}
84079
 
+
84080
 
+static void sieve_master_vinfo
84081
 
+(struct sieve_error_handler *ehandler ATTR_UNUSED, const char *location, 
84082
 
+       const char *fmt, va_list args) 
84083
 
+{
84084
 
+       if ( ehandler->log_master ) return;
84085
 
+
84086
 
+       if ( location == NULL || *location == '\0' )
84087
 
+               i_info("sieve: %s", t_strdup_vprintf(fmt, args));
84088
 
+       else
84089
 
+               i_info("sieve: %s: %s", location, t_strdup_vprintf(fmt, args));
84090
 
+}
84091
 
+
84092
 
+struct sieve_error_handler *sieve_master_ehandler_create
84093
 
+(unsigned int max_errors) 
84094
 
+{
84095
 
+       pool_t pool;
84096
 
+       struct sieve_error_handler *ehandler;
84097
 
+       
84098
 
+       /* Pool is not strictly necessary, but other handler types will need a pool,
84099
 
+        * so this one will have one too.
84100
 
+        */
84101
 
+       pool = pool_alloconly_create
84102
 
+               ("master_error_handler", sizeof(struct sieve_error_handler));
84103
 
+       ehandler = p_new(pool, struct sieve_error_handler, 1);
84104
 
+       sieve_error_handler_init(ehandler, pool, max_errors);
84105
 
+
84106
 
+       ehandler->verror = sieve_master_verror;
84107
 
+       ehandler->vwarning = sieve_master_vwarning;
84108
 
+       ehandler->vinfo = sieve_master_vinfo;
84109
 
+       
84110
 
+       return ehandler;        
84111
 
+}
84112
 
+
84113
 
+struct sieve_error_handler _sieve_system_ehandler_object = {
84114
 
+       NULL, 0, 0, 0, 0,
84115
 
+       FALSE,
84116
 
+       TRUE,
84117
 
+       sieve_master_verror,
84118
 
+       sieve_master_vwarning,
84119
 
+       sieve_master_vinfo,
84120
 
+       NULL
84121
 
+};
84122
 
+
84123
 
+struct sieve_error_handler *_sieve_system_ehandler = &_sieve_system_ehandler_object;
84124
 
+
84125
 
+void sieve_system_ehandler_set(struct sieve_error_handler *ehandler)
84126
 
+{
84127
 
+       sieve_error_handler_unref(&_sieve_system_ehandler);
84128
 
+       _sieve_system_ehandler = ehandler;
84129
 
+       sieve_error_handler_ref(_sieve_system_ehandler);
84130
 
+}
84131
 
+
84132
 
+void sieve_system_ehandler_reset(void)
84133
 
+{
84134
 
+       sieve_error_handler_unref(&_sieve_system_ehandler);
84135
 
+       _sieve_system_ehandler = &_sieve_system_ehandler_object;        
84136
 
+}
84137
 
+
84138
 
+/* 
84139
 
+ * STDERR error handler
84140
 
+ *
84141
 
+ * - Output errors directly to stderror 
84142
 
+ */
84143
 
+
84144
 
+static void sieve_stderr_verror
84145
 
+(struct sieve_error_handler *ehandler ATTR_UNUSED, const char *location, 
84146
 
+       const char *fmt, va_list args) 
84147
 
+{
84148
 
+       if ( location == NULL || *location == '\0' )
84149
 
+               fprintf(stderr, "error: %s.\n", t_strdup_vprintf(fmt, args));
84150
 
+       else
84151
 
+               fprintf(stderr, "%s: error: %s.\n", location, t_strdup_vprintf(fmt, args));
84152
 
+}
84153
 
+
84154
 
+static void sieve_stderr_vwarning
84155
 
+(struct sieve_error_handler *ehandler ATTR_UNUSED, const char *location, 
84156
 
+       const char *fmt, va_list args) 
84157
 
+{
84158
 
+       if ( location == NULL || *location == '\0' )
84159
 
+               fprintf(stderr, "warning: %s.\n", t_strdup_vprintf(fmt, args));
84160
 
+       else
84161
 
+               fprintf(stderr, "%s: warning: %s.\n", location, t_strdup_vprintf(fmt, args));
84162
 
+}
84163
 
+
84164
 
+static void sieve_stderr_vinfo
84165
 
+(struct sieve_error_handler *ehandler ATTR_UNUSED, const char *location, 
84166
 
+       const char *fmt, va_list args) 
84167
 
+{
84168
 
+       if ( location == NULL || *location == '\0' )
84169
 
+               fprintf(stderr, "info: %s.\n", t_strdup_vprintf(fmt, args));
84170
 
+       else
84171
 
+               fprintf(stderr, "%s: info: %s.\n", location, t_strdup_vprintf(fmt, args));
84172
 
+}
84173
 
+
84174
 
+struct sieve_error_handler *sieve_stderr_ehandler_create
84175
 
+(unsigned int max_errors) 
84176
 
+{
84177
 
+       pool_t pool;
84178
 
+       struct sieve_error_handler *ehandler;
84179
 
+       
84180
 
+       /* Pool is not strictly necessary, but other handler types will need a pool,
84181
 
+        * so this one will have one too.
84182
 
+        */
84183
 
+       pool = pool_alloconly_create
84184
 
+               ("stderr_error_handler", sizeof(struct sieve_error_handler));
84185
 
+       ehandler = p_new(pool, struct sieve_error_handler, 1);
84186
 
+       sieve_error_handler_init(ehandler, pool, max_errors);
84187
 
+
84188
 
+       ehandler->verror = sieve_stderr_verror;
84189
 
+       ehandler->vwarning = sieve_stderr_vwarning;
84190
 
+       ehandler->vinfo = sieve_stderr_vinfo;
84191
 
+       
84192
 
+       return ehandler;        
84193
 
+}
84194
 
+
84195
 
+/* String buffer error handler
84196
 
+ *
84197
 
+ * - Output errors to a string buffer 
84198
 
+ */
84199
 
+
84200
 
+struct sieve_strbuf_ehandler {
84201
 
+       struct sieve_error_handler handler;
84202
 
+
84203
 
+       string_t *errors;
84204
 
+       bool crlf;
84205
 
+};
84206
 
+
84207
 
+static void sieve_strbuf_verror
84208
 
+(struct sieve_error_handler *ehandler, const char *location,
84209
 
+    const char *fmt, va_list args)
84210
 
+{
84211
 
+       struct sieve_strbuf_ehandler *handler =
84212
 
+               (struct sieve_strbuf_ehandler *) ehandler;
84213
 
+
84214
 
+       if ( location != NULL && *location != '\0' )
84215
 
+               str_printfa(handler->errors, "%s: ", location);
84216
 
+       str_append(handler->errors, "error: ");
84217
 
+       str_vprintfa(handler->errors, fmt, args);
84218
 
+
84219
 
+       if ( !handler->crlf )
84220
 
+               str_append(handler->errors, ".\n");
84221
 
+       else
84222
 
+               str_append(handler->errors, ".\r\n");
84223
 
+}
84224
 
+
84225
 
+static void sieve_strbuf_vwarning
84226
 
+(struct sieve_error_handler *ehandler, const char *location,
84227
 
+    const char *fmt, va_list args)
84228
 
+{
84229
 
+       struct sieve_strbuf_ehandler *handler =
84230
 
+               (struct sieve_strbuf_ehandler *) ehandler;
84231
 
+
84232
 
+       if ( location != NULL && *location != '\0' )
84233
 
+               str_printfa(handler->errors, "%s: ", location);
84234
 
+       str_printfa(handler->errors, "warning: ");
84235
 
+       str_vprintfa(handler->errors, fmt, args);
84236
 
+
84237
 
+       if ( !handler->crlf )
84238
 
+               str_append(handler->errors, ".\n");
84239
 
+       else
84240
 
+               str_append(handler->errors, ".\r\n");
84241
 
+}
84242
 
+
84243
 
+static void sieve_strbuf_vinfo
84244
 
+(struct sieve_error_handler *ehandler, const char *location,
84245
 
+    const char *fmt, va_list args)
84246
 
+{
84247
 
+       struct sieve_strbuf_ehandler *handler =
84248
 
+               (struct sieve_strbuf_ehandler *) ehandler;
84249
 
+
84250
 
+       if ( location != NULL && *location != '\0' )
84251
 
+               str_printfa(handler->errors, "%s: ", location); 
84252
 
+       str_printfa(handler->errors, "info: ");
84253
 
+       str_vprintfa(handler->errors, fmt, args);
84254
 
+
84255
 
+       if ( !handler->crlf )
84256
 
+               str_append(handler->errors, ".\n");
84257
 
+       else
84258
 
+               str_append(handler->errors, ".\r\n");
84259
 
+}
84260
 
+
84261
 
+struct sieve_error_handler *sieve_strbuf_ehandler_create
84262
 
+(string_t *strbuf, bool crlf, unsigned int max_errors)
84263
 
+{
84264
 
+       pool_t pool;
84265
 
+       struct sieve_strbuf_ehandler *ehandler;
84266
 
+
84267
 
+       pool = pool_alloconly_create("strbuf_error_handler", 256);
84268
 
+       ehandler = p_new(pool, struct sieve_strbuf_ehandler, 1);
84269
 
+       ehandler->errors = strbuf;
84270
 
+    
84271
 
+       sieve_error_handler_init(&ehandler->handler, pool, max_errors);
84272
 
+
84273
 
+       ehandler->handler.verror = sieve_strbuf_verror;
84274
 
+       ehandler->handler.vwarning = sieve_strbuf_vwarning;
84275
 
+       ehandler->handler.vinfo = sieve_strbuf_vinfo;
84276
 
+
84277
 
+       ehandler->crlf = crlf;
84278
 
+
84279
 
+       return &(ehandler->handler);
84280
 
+}
84281
 
+
84282
 
+/* 
84283
 
+ * Logfile error handler
84284
 
+ * 
84285
 
+ * - Output errors to a log file 
84286
 
+ */
84287
 
+
84288
 
+struct sieve_logfile_ehandler {
84289
 
+       struct sieve_error_handler handler;
84290
 
+       
84291
 
+       const char *logfile;
84292
 
+       bool started;
84293
 
+       int fd;
84294
 
+       struct ostream *stream;
84295
 
+};
84296
 
+
84297
 
+static void sieve_logfile_vprintf
84298
 
+(struct sieve_logfile_ehandler *ehandler, const char *location, 
84299
 
+       const char *prefix, const char *fmt, va_list args) 
84300
 
+{
84301
 
+       string_t *outbuf;
84302
 
+       ssize_t ret = 0, remain;
84303
 
+       const char *data;
84304
 
+       
84305
 
+       if ( ehandler->stream == NULL ) return;
84306
 
+       
84307
 
+       T_BEGIN {
84308
 
+               outbuf = t_str_new(256);
84309
 
+               if ( location != NULL && *location != '\0' )
84310
 
+                       str_printfa(outbuf, "%s: ", location);
84311
 
+               str_printfa(outbuf, "%s: ", prefix);    
84312
 
+               str_vprintfa(outbuf, fmt, args);
84313
 
+               str_append(outbuf, ".\n");
84314
 
+       
84315
 
+               remain = str_len(outbuf);
84316
 
+               data = (const char *) str_data(outbuf);
84317
 
+
84318
 
+               while ( remain > 0 ) { 
84319
 
+                       if ( (ret=o_stream_send(ehandler->stream, data, remain)) < 0 )
84320
 
+                               break;
84321
 
+
84322
 
+                       remain -= ret;
84323
 
+                       data += ret;
84324
 
+               }
84325
 
+       } T_END;
84326
 
+
84327
 
+       if ( ret < 0 ) {
84328
 
+               sieve_sys_error(
84329
 
+                       "o_stream_send() failed on logfile %s: %m", ehandler->logfile);         
84330
 
+       }
84331
 
+}
84332
 
+
84333
 
+inline static void sieve_logfile_printf
84334
 
+(struct sieve_logfile_ehandler *ehandler, const char *location, const char *prefix,
84335
 
+       const char *fmt, ...) 
84336
 
+{
84337
 
+       va_list args;
84338
 
+       va_start(args, fmt);
84339
 
+       
84340
 
+       sieve_logfile_vprintf(ehandler, location, prefix, fmt, args);
84341
 
+       
84342
 
+       va_end(args);
84343
 
+}
84344
 
+
84345
 
+static void sieve_logfile_start(struct sieve_logfile_ehandler *ehandler)
84346
 
+{
84347
 
+       int fd;
84348
 
+       struct ostream *ostream = NULL;
84349
 
+       struct stat st;
84350
 
+       struct tm *tm;
84351
 
+       char buf[256];
84352
 
+       time_t now;
84353
 
+
84354
 
+       /* Open the logfile */
84355
 
+
84356
 
+       fd = open(ehandler->logfile, O_CREAT | O_APPEND | O_WRONLY, 0600);
84357
 
+       if (fd == -1) {
84358
 
+               if ( errno == EACCES ) {
84359
 
+                       sieve_sys_error("failed to open logfile (LOGGING TO STDERR): %s",
84360
 
+                               eacces_error_get_creating("open", ehandler->logfile));
84361
 
+               } else {
84362
 
+                       sieve_sys_error("failed to open logfile (LOGGING TO STDERR): "
84363
 
+                               "open(%s) failed: %m", ehandler->logfile);
84364
 
+               }
84365
 
+               fd = STDERR_FILENO;
84366
 
+       } else {
84367
 
+               /* fd_close_on_exec(fd, TRUE); Necessary? */
84368
 
+
84369
 
+               /* Stat the log file to obtain size information */
84370
 
+               if ( fstat(fd, &st) != 0 ) {
84371
 
+                       sieve_sys_error("failed to stat logfile (logging to STDERR): "
84372
 
+                               "fstat(fd=%s) failed: %m", ehandler->logfile);
84373
 
+                       
84374
 
+                       if ( close(fd) < 0 ) {
84375
 
+                               sieve_sys_error("failed to close logfile after error: "
84376
 
+                                       "close(fd=%s) failed: %m", ehandler->logfile);
84377
 
+                       }
84378
 
+
84379
 
+                       fd = STDERR_FILENO;
84380
 
+               }
84381
 
+               
84382
 
+               /* Rotate log when it has grown too large */
84383
 
+               if ( st.st_size >= LOGFILE_MAX_SIZE ) {
84384
 
+                       const char *rotated;
84385
 
+                       
84386
 
+                       /* Close open file */
84387
 
+                       if ( close(fd) < 0 ) {
84388
 
+                               sieve_sys_error("failed to close logfile: close(fd=%s) failed: %m",
84389
 
+                                       ehandler->logfile);
84390
 
+                       }
84391
 
+                       
84392
 
+                       /* Rotate logfile */
84393
 
+                       rotated = t_strconcat(ehandler->logfile, ".0", NULL);
84394
 
+                       if ( rename(ehandler->logfile, rotated) < 0 ) {
84395
 
+                               sieve_sys_error("failed to rotate logfile: rename(%s, %s) failed: %m", 
84396
 
+                                       ehandler->logfile, rotated);
84397
 
+                       }
84398
 
+                       
84399
 
+                       /* Open clean logfile (overwrites existing if rename() failed earlier) */
84400
 
+                       fd = open(ehandler->logfile, O_CREAT | O_WRONLY | O_TRUNC, 0600);
84401
 
+                       if (fd == -1) {
84402
 
+                               if ( errno == EACCES ) {
84403
 
+                                       sieve_sys_error("failed to open logfile (LOGGING TO STDERR): %s",
84404
 
+                                               eacces_error_get_creating("open", ehandler->logfile));
84405
 
+                               } else {
84406
 
+                                       sieve_sys_error("failed to open logfile (LOGGING TO STDERR): "
84407
 
+                                               "open(%s) failed: %m", ehandler->logfile);
84408
 
+                               }
84409
 
+                               fd = STDERR_FILENO;
84410
 
+                       }
84411
 
+               }
84412
 
+       }
84413
 
+
84414
 
+       ostream = o_stream_create_fd(fd, 0, FALSE);
84415
 
+       if ( ostream == NULL ) {
84416
 
+               /* Can't we do anything else in this most awkward situation? */
84417
 
+               sieve_sys_error("failed to open log stream on open file: "
84418
 
+                       "o_stream_create_fd(fd=%s) failed "
84419
 
+                       "(non-critical messages are not logged!)", ehandler->logfile);
84420
 
+       } 
84421
 
+
84422
 
+       ehandler->fd = fd;
84423
 
+       ehandler->stream = ostream;
84424
 
+       ehandler->started = TRUE;
84425
 
+       
84426
 
+       if ( ostream != NULL ) {
84427
 
+               now = time(NULL);       
84428
 
+               tm = localtime(&now);
84429
 
+
84430
 
+               if (strftime(buf, sizeof(buf), "%b %d %H:%M:%S", tm) > 0) {
84431
 
+                       sieve_logfile_printf(ehandler, "sieve", "info",
84432
 
+                               "started log at %s", buf);
84433
 
+               }
84434
 
+       }
84435
 
+}
84436
 
+
84437
 
+static void sieve_logfile_verror
84438
 
+(struct sieve_error_handler *ehandler, const char *location, 
84439
 
+       const char *fmt, va_list args) 
84440
 
+{
84441
 
+       struct sieve_logfile_ehandler *handler = 
84442
 
+               (struct sieve_logfile_ehandler *) ehandler;
84443
 
+
84444
 
+       if ( !handler->started ) sieve_logfile_start(handler);  
84445
 
+
84446
 
+       sieve_logfile_vprintf(handler, location, "error", fmt, args);
84447
 
+}
84448
 
+
84449
 
+static void sieve_logfile_vwarning
84450
 
+(struct sieve_error_handler *ehandler, const char *location, 
84451
 
+       const char *fmt, va_list args) 
84452
 
+{
84453
 
+       struct sieve_logfile_ehandler *handler = 
84454
 
+               (struct sieve_logfile_ehandler *) ehandler;
84455
 
+
84456
 
+       if ( !handler->started ) sieve_logfile_start(handler);  
84457
 
+
84458
 
+       sieve_logfile_vprintf(handler, location, "warning", fmt, args);
84459
 
+}
84460
 
+
84461
 
+static void sieve_logfile_vinfo
84462
 
+(struct sieve_error_handler *ehandler, const char *location, 
84463
 
+       const char *fmt, va_list args) 
84464
 
+{
84465
 
+       struct sieve_logfile_ehandler *handler = 
84466
 
+               (struct sieve_logfile_ehandler *) ehandler;
84467
 
+
84468
 
+       if ( !handler->started ) sieve_logfile_start(handler);  
84469
 
+
84470
 
+       sieve_logfile_vprintf(handler, location, "info", fmt, args);
84471
 
+}
84472
 
+
84473
 
+static void sieve_logfile_free
84474
 
+(struct sieve_error_handler *ehandler)
84475
 
+{
84476
 
+       struct sieve_logfile_ehandler *handler = 
84477
 
+               (struct sieve_logfile_ehandler *) ehandler;
84478
 
+               
84479
 
+       if ( handler->stream != NULL ) {
84480
 
+               o_stream_destroy(&(handler->stream));
84481
 
+               if ( handler->fd != STDERR_FILENO ){
84482
 
+                       if ( close(handler->fd) < 0 ) {
84483
 
+                               sieve_sys_error("failed to close logfile: "
84484
 
+                                       "close(fd=%s) failed: %m", handler->logfile);
84485
 
+                       }
84486
 
+               }
84487
 
+       }
84488
 
+}
84489
 
+
84490
 
+struct sieve_error_handler *sieve_logfile_ehandler_create
84491
 
+(const char *logfile, unsigned int max_errors) 
84492
 
+{
84493
 
+       pool_t pool;
84494
 
+       struct sieve_logfile_ehandler *ehandler;
84495
 
+       
84496
 
+       pool = pool_alloconly_create("logfile_error_handler", 256);     
84497
 
+       ehandler = p_new(pool, struct sieve_logfile_ehandler, 1);
84498
 
+       sieve_error_handler_init(&ehandler->handler, pool, max_errors);
84499
 
+
84500
 
+       ehandler->handler.verror = sieve_logfile_verror;
84501
 
+       ehandler->handler.vwarning = sieve_logfile_vwarning;
84502
 
+       ehandler->handler.vinfo = sieve_logfile_vinfo;
84503
 
+       ehandler->handler.free = sieve_logfile_free;
84504
 
+       
84505
 
+       /* Don't open logfile until something is actually logged. 
84506
 
+        * Let's not pullute the sieve directory with useless logfiles.
84507
 
+        */
84508
 
+       ehandler->logfile = p_strdup(pool, logfile);
84509
 
+       ehandler->started = FALSE;
84510
 
+       ehandler->stream = NULL;
84511
 
+       ehandler->fd = -1;
84512
 
+       
84513
 
+       return &(ehandler->handler);    
84514
 
+}
84515
 
+
84516
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-error.h dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-error.h
84517
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-error.h  1970-01-01 01:00:00.000000000 +0100
84518
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-error.h   2009-07-21 01:19:26.000000000 +0200
84519
 
@@ -0,0 +1,172 @@
84520
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
84521
 
+ */
84522
 
+
84523
 
+#ifndef __SIEVE_ERROR_H
84524
 
+#define __SIEVE_ERROR_H
84525
 
+
84526
 
+#include "lib.h"
84527
 
+#include "compat.h"
84528
 
+
84529
 
+#include <stdarg.h>
84530
 
+
84531
 
+/*
84532
 
+ * Forward declarations
84533
 
+ */
84534
 
+
84535
 
+struct sieve_script;
84536
 
+struct sieve_error_handler;
84537
 
+
84538
 
+/*
84539
 
+ * Types
84540
 
+ */
84541
 
+
84542
 
+typedef void (*sieve_error_vfunc_t)
84543
 
+       (struct sieve_error_handler *ehandler, const char *location, 
84544
 
+               const char *fmt, va_list args);
84545
 
+
84546
 
+/*
84547
 
+ * System errors
84548
 
+ */
84549
 
+
84550
 
+extern struct sieve_error_handler *_sieve_system_ehandler;
84551
 
+
84552
 
+#define sieve_sys_error(...) sieve_error(_sieve_system_ehandler, NULL, __VA_ARGS__ )
84553
 
+#define sieve_sys_warning(...) sieve_warning(_sieve_system_ehandler, NULL, __VA_ARGS__ )
84554
 
+#define sieve_sys_info(...) sieve_info(_sieve_system_ehandler, NULL, __VA_ARGS__ )
84555
 
+
84556
 
+void sieve_system_ehandler_set(struct sieve_error_handler *ehandler);
84557
 
+void sieve_system_ehandler_reset(void);
84558
 
+
84559
 
+/*
84560
 
+ * Main error functions
84561
 
+ */
84562
 
+
84563
 
+/* For these functions it is the responsibility of the caller to
84564
 
+ * manage the datastack.
84565
 
+ */
84566
 
+
84567
 
+const char *sieve_error_script_location
84568
 
+       (const struct sieve_script *script, unsigned int source_line);
84569
 
+
84570
 
+void sieve_verror
84571
 
+       (struct sieve_error_handler *ehandler, const char *location, 
84572
 
+               const char *fmt, va_list args);
84573
 
+void sieve_vwarning
84574
 
+       (struct sieve_error_handler *ehandler, const char *location, 
84575
 
+               const char *fmt, va_list args); 
84576
 
+void sieve_vinfo
84577
 
+       (struct sieve_error_handler *ehandler, const char *location, 
84578
 
+               const char *fmt, va_list args); 
84579
 
+void sieve_vcritical
84580
 
+       (struct sieve_error_handler *ehandler, const char *location, 
84581
 
+               const char *fmt, va_list args); 
84582
 
+
84583
 
+inline static void sieve_error
84584
 
+(struct sieve_error_handler *ehandler, const char *location, 
84585
 
+       const char *fmt, ...) ATTR_FORMAT(3, 4);
84586
 
+inline static void sieve_warning
84587
 
+(struct sieve_error_handler *ehandler, const char *location, 
84588
 
+       const char *fmt, ...) ATTR_FORMAT(3, 4);
84589
 
+inline static void sieve_info
84590
 
+(struct sieve_error_handler *ehandler, const char *location, 
84591
 
+       const char *fmt, ...) ATTR_FORMAT(3, 4);
84592
 
+inline static void sieve_critical
84593
 
+(struct sieve_error_handler *ehandler, const char *location, 
84594
 
+       const char *fmt, ...) ATTR_FORMAT(3, 4);
84595
 
+
84596
 
+inline static void sieve_error
84597
 
+(struct sieve_error_handler *ehandler, const char *location, 
84598
 
+       const char *fmt, ...)
84599
 
+{
84600
 
+       va_list args;
84601
 
+       va_start(args, fmt);
84602
 
+       
84603
 
+       T_BEGIN { sieve_verror(ehandler, location, fmt, args); } T_END;
84604
 
+       
84605
 
+       va_end(args);
84606
 
+}
84607
 
+
84608
 
+inline static void sieve_warning
84609
 
+(struct sieve_error_handler *ehandler, const char *location, 
84610
 
+       const char *fmt, ...)
84611
 
+{
84612
 
+       va_list args;
84613
 
+       va_start(args, fmt);
84614
 
+       
84615
 
+       T_BEGIN { sieve_vwarning(ehandler, location, fmt, args); } T_END;
84616
 
+
84617
 
+       va_end(args);
84618
 
+}
84619
 
+
84620
 
+inline static void sieve_info
84621
 
+(struct sieve_error_handler *ehandler, const char *location, 
84622
 
+       const char *fmt, ...)
84623
 
+{
84624
 
+       va_list args;
84625
 
+       va_start(args, fmt);
84626
 
+       
84627
 
+       T_BEGIN { sieve_vinfo(ehandler, location, fmt, args); } T_END;
84628
 
+       
84629
 
+       va_end(args);
84630
 
+}
84631
 
+
84632
 
+inline static void sieve_critical
84633
 
+(struct sieve_error_handler *ehandler, const char *location, 
84634
 
+       const char *fmt, ...)
84635
 
+{
84636
 
+       va_list args;
84637
 
+       va_start(args, fmt);
84638
 
+       
84639
 
+       T_BEGIN { sieve_vcritical(ehandler, location, fmt, args); } T_END;
84640
 
+       
84641
 
+       va_end(args);
84642
 
+}
84643
 
+
84644
 
+/*
84645
 
+ * Error handler configuration
84646
 
+ */
84647
 
+
84648
 
+void sieve_error_handler_accept_infolog
84649
 
+       (struct sieve_error_handler *ehandler, bool enable);
84650
 
+void sieve_error_handler_copy_masterlog
84651
 
+       (struct sieve_error_handler *ehandler, bool enable);
84652
 
+
84653
 
+/*
84654
 
+ * Error handler statistics
84655
 
+ */
84656
 
+
84657
 
+unsigned int sieve_get_errors(struct sieve_error_handler *ehandler);
84658
 
+unsigned int sieve_get_warnings(struct sieve_error_handler *ehandler);
84659
 
+
84660
 
+bool sieve_errors_more_allowed(struct sieve_error_handler *ehandler);
84661
 
+
84662
 
+/*
84663
 
+ * Error handler object
84664
 
+ */
84665
 
+
84666
 
+void sieve_error_handler_ref(struct sieve_error_handler *ehandler);
84667
 
+void sieve_error_handler_unref(struct sieve_error_handler **ehandler);
84668
 
+
84669
 
+void sieve_error_handler_reset(struct sieve_error_handler *ehandler);
84670
 
+
84671
 
+/* 
84672
 
+ * Error handlers 
84673
 
+ */
84674
 
+
84675
 
+/* Write errors to dovecot master log */
84676
 
+struct sieve_error_handler *sieve_master_ehandler_create
84677
 
+       (unsigned int max_errors);
84678
 
+
84679
 
+/* Write errors to stderr */
84680
 
+struct sieve_error_handler *sieve_stderr_ehandler_create
84681
 
+       (unsigned int max_errors);
84682
 
+
84683
 
+/* Write errors into a string buffer */
84684
 
+struct sieve_error_handler *sieve_strbuf_ehandler_create
84685
 
+       (string_t *strbuf, bool crlf, unsigned int max_errors);
84686
 
+
84687
 
+/* Write errors to a logfile */
84688
 
+struct sieve_error_handler *sieve_logfile_ehandler_create
84689
 
+       (const char *logfile, unsigned int max_errors);  
84690
 
+
84691
 
+#endif /* __SIEVE_ERROR_H */
84692
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-error-private.h dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-error-private.h
84693
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-error-private.h  1970-01-01 01:00:00.000000000 +0100
84694
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-error-private.h   2009-04-09 21:45:29.000000000 +0200
84695
 
@@ -0,0 +1,47 @@
84696
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
84697
 
+ */
84698
 
+
84699
 
+#ifndef __SIEVE_ERROR_PRIVATE_H
84700
 
+#define __SIEVE_ERROR_PRIVATE_H
84701
 
+
84702
 
+#include "sieve-error.h"
84703
 
+
84704
 
+/*
84705
 
+ * Error handler object
84706
 
+ */
84707
 
+
84708
 
+struct sieve_error_handler {
84709
 
+       pool_t pool;
84710
 
+       int refcount;
84711
 
+
84712
 
+       unsigned int max_errors;
84713
 
+
84714
 
+       unsigned int errors;
84715
 
+       unsigned int warnings;
84716
 
+
84717
 
+       /* Should we copy log to i_error, i_warning and i_info? */
84718
 
+       bool log_master;
84719
 
+
84720
 
+       /* Should the errorhandler handle or discard info log?
84721
 
+        * (This does not influence the previous setting)
84722
 
+        */
84723
 
+       bool log_info;
84724
 
+
84725
 
+       void (*verror)
84726
 
+               (struct sieve_error_handler *ehandler, const char *location,
84727
 
+                       const char *fmt, va_list args);
84728
 
+       void (*vwarning)
84729
 
+               (struct sieve_error_handler *ehandler, const char *location,
84730
 
+                       const char *fmt, va_list args);
84731
 
+       void (*vinfo)
84732
 
+               (struct sieve_error_handler *ehandler, const char *location,
84733
 
+                       const char *fmt, va_list args);
84734
 
+
84735
 
+       void (*free)
84736
 
+               (struct sieve_error_handler *ehandler);
84737
 
+};
84738
 
+
84739
 
+void sieve_error_handler_init
84740
 
+       (struct sieve_error_handler *ehandler, pool_t pool, unsigned int max_errors);
84741
 
+
84742
 
+#endif /* __SIEVE_ERROR_PRIVATE_H */
84743
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-extensions.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-extensions.c
84744
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-extensions.c     1970-01-01 01:00:00.000000000 +0100
84745
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-extensions.c      2009-08-21 00:52:15.000000000 +0200
84746
 
@@ -0,0 +1,555 @@
84747
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
84748
 
+ */
84749
 
+
84750
 
+#include "lib.h"
84751
 
+#include "str.h"
84752
 
+#include "mempool.h"
84753
 
+#include "hash.h"
84754
 
+#include "array.h"
84755
 
+
84756
 
+#include "sieve-error.h"
84757
 
+#include "sieve-extensions.h"
84758
 
+
84759
 
+/*
84760
 
+ * Forward declarations 
84761
 
+ */
84762
 
+
84763
 
+static void sieve_extensions_init_registry(void);
84764
 
+static void sieve_extensions_deinit_registry(void);
84765
 
+
84766
 
+static void sieve_extensions_init_capabilities(void);
84767
 
+static void sieve_extensions_deinit_capabilities(void);
84768
 
+
84769
 
+/* 
84770
 
+ * Pre-loaded 'extensions' 
84771
 
+ */
84772
 
+
84773
 
+extern const struct sieve_extension comparator_extension;
84774
 
+extern const struct sieve_extension match_type_extension;
84775
 
+extern const struct sieve_extension address_part_extension;
84776
 
+
84777
 
+const struct sieve_extension *sieve_preloaded_extensions[] = {
84778
 
+       &comparator_extension, &match_type_extension, &address_part_extension
84779
 
+};
84780
 
+
84781
 
+const unsigned int sieve_preloaded_extensions_count = 
84782
 
+       N_ELEMENTS(sieve_preloaded_extensions);
84783
 
+
84784
 
+/* 
84785
 
+ * Dummy extensions 
84786
 
+ */
84787
 
84788
 
+/* FIXME: This is stupid. Define a comparator-* extension and be done with it */
84789
 
+
84790
 
+static const struct sieve_extension comparator_i_octet_extension = {
84791
 
+       "comparator-i;octet", 
84792
 
+       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
84793
 
+       SIEVE_EXT_DEFINE_NO_OPERATIONS, 
84794
 
+       SIEVE_EXT_DEFINE_NO_OPERANDS
84795
 
+};
84796
 
+
84797
 
+static const struct sieve_extension comparator_i_ascii_casemap_extension = {
84798
 
+       "comparator-i;ascii-casemap", 
84799
 
+       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 
84800
 
+       SIEVE_EXT_DEFINE_NO_OPERATIONS, 
84801
 
+       SIEVE_EXT_DEFINE_NO_OPERANDS
84802
 
+};
84803
 
+
84804
 
+/* 
84805
 
+ * Core extensions 
84806
 
+ */
84807
 
+
84808
 
+extern const struct sieve_extension fileinto_extension;
84809
 
+extern const struct sieve_extension reject_extension;
84810
 
+extern const struct sieve_extension envelope_extension;
84811
 
+extern const struct sieve_extension encoded_character_extension;
84812
 
+
84813
 
+/* 
84814
 
+ * Native 'plugin' extensions 
84815
 
+ */
84816
 
+
84817
 
+extern const struct sieve_extension vacation_extension;
84818
 
+extern const struct sieve_extension subaddress_extension;
84819
 
+extern const struct sieve_extension comparator_i_ascii_numeric_extension;
84820
 
+extern const struct sieve_extension relational_extension;
84821
 
+extern const struct sieve_extension regex_extension;
84822
 
+extern const struct sieve_extension imap4flags_extension;
84823
 
+extern const struct sieve_extension copy_extension;
84824
 
+extern const struct sieve_extension include_extension;
84825
 
+extern const struct sieve_extension body_extension;
84826
 
+extern const struct sieve_extension variables_extension;
84827
 
+extern const struct sieve_extension enotify_extension;
84828
 
+extern const struct sieve_extension environment_extension;
84829
 
+extern const struct sieve_extension mailbox_extension;
84830
 
+extern const struct sieve_extension date_extension;
84831
 
+
84832
 
+/*
84833
 
+ * List of native extensions
84834
 
+ */
84835
 
+
84836
 
+const struct sieve_extension *sieve_core_extensions[] = {
84837
 
+       /* Preloaded 'extensions' */
84838
 
+       &comparator_extension, &match_type_extension, &address_part_extension,
84839
 
+       
84840
 
+       /* Dummy extensions */ 
84841
 
+       &comparator_i_octet_extension, &comparator_i_ascii_casemap_extension, 
84842
 
+       
84843
 
+       /* Core extensions */
84844
 
+       &fileinto_extension, &reject_extension, &envelope_extension, 
84845
 
+       &encoded_character_extension,
84846
 
+       
84847
 
+       /* 'Plugins' */
84848
 
+       &vacation_extension, &subaddress_extension, 
84849
 
+       &comparator_i_ascii_numeric_extension, 
84850
 
+       &relational_extension, &regex_extension, &imap4flags_extension,
84851
 
+       &copy_extension, &include_extension, &body_extension,
84852
 
+       &variables_extension, &enotify_extension, &environment_extension,
84853
 
+       &mailbox_extension, &date_extension
84854
 
+};
84855
 
+
84856
 
+const unsigned int sieve_core_extensions_count =
84857
 
+       N_ELEMENTS(sieve_core_extensions);
84858
 
+
84859
 
+/*
84860
 
+ * Deprecated extensions
84861
 
+ */
84862
 
+
84863
 
+extern const struct sieve_extension imapflags_extension;
84864
 
+extern const struct sieve_extension notify_extension;
84865
 
+
84866
 
+const struct sieve_extension *sieve_deprecated_extensions[] = {
84867
 
+       &imapflags_extension,
84868
 
+       &notify_extension
84869
 
+};
84870
 
+
84871
 
+const unsigned int sieve_deprecated_extensions_count =
84872
 
+       N_ELEMENTS(sieve_deprecated_extensions);
84873
 
+
84874
 
+/*
84875
 
+ * Unfinished extensions
84876
 
+ */
84877
 
+
84878
 
+#ifdef HAVE_SIEVE_UNFINISHED
84879
 
+
84880
 
+extern const struct sieve_extension ereject_extension;
84881
 
+
84882
 
+const struct sieve_extension *sieve_unfinished_extensions[] = {
84883
 
+       &ereject_extension,
84884
 
+};
84885
 
+
84886
 
+const unsigned int sieve_unfinished_extensions_count =
84887
 
+       N_ELEMENTS(sieve_unfinished_extensions);
84888
 
+
84889
 
+#endif /* HAVE_SIEVE_UNFINISHED */
84890
 
+
84891
 
+/* 
84892
 
+ * Extensions init/deinit
84893
 
+ */
84894
 
+
84895
 
+bool sieve_extensions_init(void) 
84896
 
+{
84897
 
+       unsigned int i;
84898
 
+       
84899
 
+       sieve_extensions_init_registry();
84900
 
+       sieve_extensions_init_capabilities();
84901
 
+       
84902
 
+       /* Pre-load core extensions */
84903
 
+       for ( i = 0; i < sieve_core_extensions_count; i++ ) {
84904
 
+               (void)sieve_extension_register(sieve_core_extensions[i], TRUE);
84905
 
+       }
84906
 
+
84907
 
+       /* Register deprecated extensions */
84908
 
+       for ( i = 0; i < sieve_deprecated_extensions_count; i++ ) {
84909
 
+               (void)sieve_extension_register(sieve_deprecated_extensions[i], FALSE);
84910
 
+       }
84911
 
+
84912
 
+#ifdef HAVE_SIEVE_UNFINISHED
84913
 
+       /* Register unfinished extensions */
84914
 
+       for ( i = 0; i < sieve_unfinished_extensions_count; i++ ) {
84915
 
+               (void)sieve_extension_register(sieve_unfinished_extensions[i], FALSE);
84916
 
+       }
84917
 
+#endif
84918
 
+
84919
 
+       /* More extensions can be added through plugins */
84920
 
+       
84921
 
+       return TRUE;
84922
 
+}
84923
 
+
84924
 
+void sieve_extensions_deinit(void)
84925
 
+{      
84926
 
+       sieve_extensions_deinit_capabilities();
84927
 
+       sieve_extensions_deinit_registry();
84928
 
+}
84929
 
+
84930
 
+/* 
84931
 
+ * Extension registry
84932
 
+ */
84933
 
84934
 
+struct sieve_extension_registration {
84935
 
+       const struct sieve_extension *extension;
84936
 
+       int id;
84937
 
+       bool required;
84938
 
+       bool loaded;
84939
 
+};
84940
 
+
84941
 
+static ARRAY_DEFINE(extensions, struct sieve_extension_registration); 
84942
 
+static struct hash_table *extension_index; 
84943
 
+
84944
 
+static void sieve_extensions_init_registry(void)
84945
 
+{      
84946
 
+       i_array_init(&extensions, 30);
84947
 
+       extension_index = hash_table_create
84948
 
+               (default_pool, default_pool, 0, str_hash, (hash_cmp_callback_t *)strcmp);
84949
 
+}
84950
 
+
84951
 
+static bool _sieve_extension_load
84952
 
+(const struct sieve_extension *extension)
84953
 
+{
84954
 
+       /* Call load handler */
84955
 
+       if ( extension->load != NULL && !extension->load() ) {
84956
 
+               sieve_sys_error("failed to load '%s' extension support.", 
84957
 
+                       extension->name);
84958
 
+               return FALSE;
84959
 
+       }
84960
 
+
84961
 
+       return TRUE;
84962
 
+}
84963
 
+
84964
 
+static struct sieve_extension_registration *_sieve_extension_register
84965
 
+(const struct sieve_extension *extension, bool load)
84966
 
+{
84967
 
+       struct sieve_extension_registration *ereg = 
84968
 
+               (struct sieve_extension_registration *) 
84969
 
+               hash_table_lookup(extension_index, extension->name);
84970
 
+
84971
 
+       /* Register extension if it is not registered already */
84972
 
+       if ( ereg == NULL ) {
84973
 
+               int ext_id = array_count(&extensions);
84974
 
+
84975
 
+               /* Add extension to the registry */
84976
 
+
84977
 
+               ereg = array_append_space(&extensions);
84978
 
+               ereg->id = ext_id;
84979
 
+
84980
 
+               hash_table_insert(extension_index, (void *) extension->name, (void *) ereg);
84981
 
+       }
84982
 
+
84983
 
+       /* Enable extension */
84984
 
+       if ( extension->_id != NULL && load ) {
84985
 
+               /* Make sure extension is enabled */
84986
 
+               *(extension->_id) = ereg->id;
84987
 
+
84988
 
+               /* Call load handler if extension was not loaded already */
84989
 
+               if ( !ereg->loaded ) {
84990
 
+                       if ( !_sieve_extension_load(extension) )
84991
 
+                               return NULL;
84992
 
+               }
84993
 
+
84994
 
+               ereg->loaded = TRUE;
84995
 
+       }
84996
 
+
84997
 
+       ereg->extension = extension;
84998
 
+
84999
 
+       return ereg;
85000
 
+}
85001
 
+
85002
 
+int sieve_extension_register
85003
 
+(const struct sieve_extension *extension, bool load) 
85004
 
+{
85005
 
+       struct sieve_extension_registration *ereg;
85006
 
+
85007
 
+       /* Register the extension */
85008
 
+       if ( (ereg=_sieve_extension_register(extension, load)) == NULL ) {
85009
 
+               return -1;
85010
 
+       }
85011
 
+
85012
 
+       return ereg->id;
85013
 
+}
85014
 
+
85015
 
+int sieve_extension_require(const struct sieve_extension *extension)
85016
 
+{
85017
 
+       struct sieve_extension_registration *ereg;
85018
 
+
85019
 
+       /* Register (possibly unknown) extension */
85020
 
+    if ( (ereg=_sieve_extension_register(extension, TRUE)) == NULL ) {
85021
 
+        return -1;
85022
 
+    }
85023
 
+
85024
 
+       ereg->required = TRUE;
85025
 
+       return ereg->id;
85026
 
+}
85027
 
+
85028
 
+int sieve_extensions_get_count(void)
85029
 
+{
85030
 
+       return array_count(&extensions);
85031
 
+}
85032
 
+
85033
 
+const struct sieve_extension *sieve_extension_get_by_id(unsigned int ext_id) 
85034
 
+{
85035
 
+       const struct sieve_extension_registration *ereg;
85036
 
+       
85037
 
+       if ( ext_id < array_count(&extensions) ) {
85038
 
+               ereg = array_idx(&extensions, ext_id);
85039
 
+
85040
 
+               if ( SIEVE_EXT_ENABLED(ereg->extension) )
85041
 
+                       return ereg->extension;
85042
 
+       }
85043
 
+       
85044
 
+       return NULL;
85045
 
+}
85046
 
+
85047
 
+const struct sieve_extension *sieve_extension_get_by_name(const char *name) 
85048
 
+{
85049
 
+       struct sieve_extension_registration *ereg;
85050
 
+       
85051
 
+       if ( *name == '@' )
85052
 
+               return NULL;    
85053
 
+               
85054
 
+       ereg = (struct sieve_extension_registration *) 
85055
 
+               hash_table_lookup(extension_index, name);
85056
 
+
85057
 
+       if ( ereg == NULL || !SIEVE_EXT_ENABLED(ereg->extension) )
85058
 
+               return NULL;
85059
 
+               
85060
 
+       return ereg->extension;
85061
 
+}
85062
 
+
85063
 
+static inline bool _list_extension
85064
 
+       (const struct sieve_extension_registration *ereg)
85065
 
+{
85066
 
+       return 
85067
 
+               ( SIEVE_EXT_ENABLED(ereg->extension) && 
85068
 
+                       *(ereg->extension->name) != '@' );
85069
 
+}
85070
 
+
85071
 
+const char *sieve_extensions_get_string(void)
85072
 
+{
85073
 
+       unsigned int i, ext_count;
85074
 
+       const struct sieve_extension_registration *eregs;
85075
 
+       string_t *extstr = t_str_new(256);
85076
 
+
85077
 
+       eregs = array_get(&extensions, &ext_count);
85078
 
+
85079
 
+       if ( ext_count > 0 ) {
85080
 
+               i = 0;
85081
 
+               
85082
 
+               /* Find first listable extension */
85083
 
+               while ( i < ext_count && !_list_extension(&eregs[i]) )
85084
 
+                       i++;
85085
 
+
85086
 
+               if ( i < ext_count ) {
85087
 
+                       /* Add first to string */
85088
 
+                       str_append(extstr, eregs[i].extension->name);
85089
 
+                       i++;     
85090
 
+
85091
 
+                       /* Add others */
85092
 
+                       for ( ; i < ext_count; i++ ) {
85093
 
+                               if ( _list_extension(&eregs[i]) ) {
85094
 
+                                       str_append_c(extstr, ' ');
85095
 
+                                       str_append(extstr, eregs[i].extension->name);
85096
 
+                               }
85097
 
+                       }
85098
 
+               }
85099
 
+       }
85100
 
+
85101
 
+       return str_c(extstr);
85102
 
+}
85103
 
+
85104
 
+static void sieve_extension_enable(struct sieve_extension_registration *ereg)
85105
 
+{
85106
 
+       if ( ereg->extension->_id != NULL ) {
85107
 
+               *(ereg->extension->_id) = ereg->id;
85108
 
+       
85109
 
+               if ( !ereg->loaded ) {
85110
 
+                       (void)_sieve_extension_load(ereg->extension);
85111
 
+               }
85112
 
+       }
85113
 
+
85114
 
+       ereg->loaded = TRUE;
85115
 
+}
85116
 
+
85117
 
+static void sieve_extension_disable(struct sieve_extension_registration *ereg)
85118
 
+{
85119
 
+       if ( ereg->extension->_id != NULL )
85120
 
+               *(ereg->extension->_id) = -1;   
85121
 
+}
85122
 
+
85123
 
+void sieve_extensions_set_string(const char *ext_string)
85124
 
+{
85125
 
+       ARRAY_DEFINE(enabled_extensions, const struct sieve_extension *);
85126
 
+       ARRAY_DEFINE(disabled_extensions, const struct sieve_extension *);
85127
 
+       const struct sieve_extension *const *ext_enabled;
85128
 
+       const struct sieve_extension *const *ext_disabled;
85129
 
+       struct sieve_extension_registration *eregs;
85130
 
+       const char **ext_names;
85131
 
+       unsigned int i, ext_count, ena_count, dis_count;
85132
 
+       bool relative = FALSE;
85133
 
+
85134
 
+       if ( ext_string == NULL ) {
85135
 
+               /* Enable all */
85136
 
+               eregs = array_get_modifiable(&extensions, &ext_count);
85137
 
+               
85138
 
+               for ( i = 0; i < ext_count; i++ )
85139
 
+                       sieve_extension_enable(&eregs[i]);
85140
 
+
85141
 
+               return; 
85142
 
+       }
85143
 
+
85144
 
+       T_BEGIN {
85145
 
+               t_array_init(&enabled_extensions, array_count(&extensions));
85146
 
+               t_array_init(&disabled_extensions, array_count(&extensions));
85147
 
+
85148
 
+               ext_names = t_strsplit_spaces(ext_string, " \t");
85149
 
+
85150
 
+               while ( *ext_names != NULL ) {
85151
 
+                       const char *name = *ext_names;
85152
 
+
85153
 
+                       ext_names++;
85154
 
+
85155
 
+                       if ( *name != '\0' ) {
85156
 
+                               const struct sieve_extension_registration *ereg;
85157
 
+                               char op = '\0'; /* No add/remove operation */
85158
 
+       
85159
 
+                               if ( *name == '+'               /* Add to existing config */
85160
 
+                                       || *name == '-' ) {     /* Remove from existing config */
85161
 
+                                       op = *name++;
85162
 
+                                       relative = TRUE;
85163
 
+                               }
85164
 
+
85165
 
+                               if ( *name == '@' )
85166
 
+                                       ereg = NULL;
85167
 
+                               else
85168
 
+                                       ereg = (const struct sieve_extension_registration *) 
85169
 
+                                               hash_table_lookup(extension_index, name);
85170
 
+       
85171
 
+                               if ( ereg == NULL ) {
85172
 
+                                       sieve_sys_warning(
85173
 
+                                               "ignored unknown extension '%s' while configuring "
85174
 
+                                               "available extensions", name);
85175
 
+                                       continue;
85176
 
+                               }
85177
 
+
85178
 
+                               if ( op == '-' )
85179
 
+                                       array_append(&disabled_extensions, &ereg->extension, 1);
85180
 
+                               else
85181
 
+                                       array_append(&enabled_extensions, &ereg->extension, 1);
85182
 
+                       }
85183
 
+               }
85184
 
+
85185
 
+               eregs = array_get_modifiable(&extensions, &ext_count);
85186
 
+               ext_enabled = array_get(&enabled_extensions, &ena_count);
85187
 
+               ext_disabled = array_get(&disabled_extensions, &dis_count);
85188
 
+
85189
 
+               /* Set new extension status */
85190
 
+
85191
 
+               for ( i = 0; i < ext_count; i++ ) {
85192
 
+                       unsigned int j;
85193
 
+                       bool disabled = TRUE;
85194
 
+
85195
 
+                       /* If extensions are specified relative to the default set,
85196
 
+                        * we first need to check which ones are disabled 
85197
 
+                        */
85198
 
+
85199
 
+                       if ( relative ) {
85200
 
+                               /* Enable if core extension */
85201
 
+                               for ( j = 0; j < sieve_core_extensions_count; j++ ) {
85202
 
+                                       if ( sieve_core_extensions[j] == eregs[i].extension ) {
85203
 
+                                               disabled = FALSE;
85204
 
+                                               break;
85205
 
+                                       }
85206
 
+                       }
85207
 
+
85208
 
+                               /* Disable if explicitly disabled */
85209
 
+                               for ( j = 0; j < dis_count; j++ ) {
85210
 
+                                       if ( ext_disabled[j] == eregs[i].extension ) {
85211
 
+                                               disabled = TRUE;
85212
 
+                                               break;
85213
 
+                                       }
85214
 
+                               }
85215
 
+                       } 
85216
 
+
85217
 
+                       /* Enable if listed with '+' or no prefix */
85218
 
+       
85219
 
+                       for ( j = 0; j < ena_count; j++ ) {
85220
 
+                               if ( ext_enabled[j] == eregs[i].extension ) {
85221
 
+                                       disabled = FALSE;
85222
 
+                                       break;
85223
 
+                               }               
85224
 
+                       }
85225
 
+
85226
 
+                       /* Perform actual activation/deactivation */
85227
 
+
85228
 
+                       if ( eregs[i].extension->_id != NULL && 
85229
 
+                               *(eregs[i].extension->name) != '@' ) {
85230
 
+                               if ( disabled && !eregs[i].required )
85231
 
+                                       sieve_extension_disable(&eregs[i]);
85232
 
+                               else
85233
 
+                                       sieve_extension_enable(&eregs[i]);
85234
 
+                       }
85235
 
+               }
85236
 
+       } T_END;
85237
 
+}
85238
 
+
85239
 
+static void sieve_extensions_deinit_registry(void) 
85240
 
+{
85241
 
+       struct hash_iterate_context *itx = 
85242
 
+               hash_table_iterate_init(extension_index);
85243
 
+       void *key; 
85244
 
+       void *value;
85245
 
+       
85246
 
+       while ( hash_table_iterate(itx, &key, &value) ) {
85247
 
+               struct sieve_extension_registration *ereg =
85248
 
+                       (struct sieve_extension_registration *) value;
85249
 
+               const struct sieve_extension *ext = ereg->extension;
85250
 
+               
85251
 
+               if ( ext->unload != NULL )
85252
 
+                       ext->unload();
85253
 
+       }
85254
 
+
85255
 
+       hash_table_iterate_deinit(&itx);        
85256
 
+
85257
 
+       array_free(&extensions);
85258
 
+       hash_table_destroy(&extension_index);
85259
 
+}
85260
 
+
85261
 
+/*
85262
 
+ * Extension capabilities
85263
 
+ */
85264
 
+
85265
 
+static struct hash_table *capabilities_index; 
85266
 
+
85267
 
+static void sieve_extensions_init_capabilities(void)
85268
 
+{      
85269
 
+       capabilities_index = hash_table_create
85270
 
+               (default_pool, default_pool, 0, str_hash, (hash_cmp_callback_t *)strcmp);
85271
 
+}
85272
 
+
85273
 
+static void sieve_extensions_deinit_capabilities(void) 
85274
 
+{
85275
 
+       hash_table_destroy(&capabilities_index);
85276
 
+}
85277
 
+
85278
 
+void sieve_extension_capabilities_register
85279
 
+       (const struct sieve_extension_capabilities *cap) 
85280
 
+{      
85281
 
+       hash_table_insert
85282
 
+               (capabilities_index, (void *) cap->name, (void *) cap);
85283
 
+}
85284
 
+
85285
 
+const char *sieve_extension_capabilities_get_string
85286
 
+       (const char *cap_name) 
85287
 
+{
85288
 
+  const struct sieve_extension_capabilities *cap = 
85289
 
+               (const struct sieve_extension_capabilities *) 
85290
 
+                       hash_table_lookup(capabilities_index, cap_name);
85291
 
+
85292
 
+       if ( cap == NULL || cap->get_string == NULL || 
85293
 
+               !SIEVE_EXT_ENABLED(cap->extension) )
85294
 
+               return NULL;
85295
 
+               
85296
 
+       return cap->get_string();
85297
 
+}
85298
 
+
85299
 
+
85300
 
+
85301
 
+
85302
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-extensions.h dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-extensions.h
85303
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-extensions.h     1970-01-01 01:00:00.000000000 +0100
85304
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-extensions.h      2009-02-04 23:05:38.000000000 +0100
85305
 
@@ -0,0 +1,118 @@
85306
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
85307
 
+ */
85308
 
+
85309
 
+#ifndef __SIEVE_EXTENSIONS_H
85310
 
+#define __SIEVE_EXTENSIONS_H
85311
 
+
85312
 
+#include "lib.h"
85313
 
+#include "sieve-common.h"
85314
 
+
85315
 
+/* 
85316
 
+ * Per-extension object registry 
85317
 
+ */
85318
 
+
85319
 
+struct sieve_extension_objects {
85320
 
+       const void *objects;
85321
 
+       unsigned int count;
85322
 
+};
85323
 
+
85324
 
+/* 
85325
 
+ * Extension object 
85326
 
+ */
85327
 
+
85328
 
+struct sieve_extension {
85329
 
+       const char *name;
85330
 
+
85331
 
+       int *const _id;
85332
 
+               
85333
 
+       bool (*load)(void);
85334
 
+       void (*unload)(void);
85335
 
+
85336
 
+       bool (*validator_load)
85337
 
+               (struct sieve_validator *validator);    
85338
 
+       bool (*generator_load)
85339
 
+               (const struct sieve_codegen_env *cgenv);
85340
 
+       bool (*interpreter_load)
85341
 
+               (const struct sieve_runtime_env *renv, sieve_size_t *address);
85342
 
+       bool (*binary_load)
85343
 
+               (struct sieve_binary *binary);
85344
 
+       
85345
 
+       bool (*binary_dump)
85346
 
+               (struct sieve_dumptime_env *denv);
85347
 
+       bool (*code_dump)
85348
 
+               (const struct sieve_dumptime_env *denv, sieve_size_t *address);
85349
 
+
85350
 
+       struct sieve_extension_objects operations;
85351
 
+       struct sieve_extension_objects operands;
85352
 
+};
85353
 
+
85354
 
+#define SIEVE_EXT_ID(EXT) (*((EXT)->_id))
85355
 
+#define SIEVE_EXT_ENABLED(EXT) (((EXT)->_id != NULL) && (*((EXT)->_id) >= 0))
85356
 
+
85357
 
+#define SIEVE_EXT_DEFINE_NO_OBJECTS \
85358
 
+       { NULL, 0 }
85359
 
+#define SIEVE_EXT_DEFINE_OBJECT(OBJ) \
85360
 
+       { &OBJ, 1 }
85361
 
+#define SIEVE_EXT_DEFINE_OBJECTS(OBJS) \
85362
 
+       { OBJS, N_ELEMENTS(OBJS) }
85363
 
+
85364
 
+#define SIEVE_EXT_GET_OBJECTS_COUNT(ext, field) \
85365
 
+       ext->field->count;
85366
 
+
85367
 
+/* 
85368
 
+ * Defining opcodes and operands 
85369
 
+ */
85370
 
+
85371
 
+#define SIEVE_EXT_DEFINE_NO_OPERATIONS SIEVE_EXT_DEFINE_NO_OBJECTS
85372
 
+#define SIEVE_EXT_DEFINE_OPERATION(OP) SIEVE_EXT_DEFINE_OBJECT(OP)
85373
 
+#define SIEVE_EXT_DEFINE_OPERATIONS(OPS) SIEVE_EXT_DEFINE_OBJECTS(OPS)
85374
 
+
85375
 
+#define SIEVE_EXT_DEFINE_NO_OPERANDS SIEVE_EXT_DEFINE_NO_OBJECTS
85376
 
+#define SIEVE_EXT_DEFINE_OPERAND(OP) SIEVE_EXT_DEFINE_OBJECT(OP)
85377
 
+#define SIEVE_EXT_DEFINE_OPERANDS(OPS) SIEVE_EXT_DEFINE_OBJECTS(OPS)
85378
 
+
85379
 
+/* 
85380
 
+ * Pre-loaded extensions 
85381
 
+ */
85382
 
+
85383
 
+extern const struct sieve_extension *sieve_preloaded_extensions[];
85384
 
+extern const unsigned int sieve_preloaded_extensions_count;
85385
 
+
85386
 
+/*  
85387
 
+ * Extensions init/deinit 
85388
 
+ */
85389
 
+
85390
 
+bool sieve_extensions_init(void);
85391
 
+void sieve_extensions_deinit(void);
85392
 
+
85393
 
+/* 
85394
 
+ * Extension registry 
85395
 
+ */
85396
 
+
85397
 
+int sieve_extension_register(const struct sieve_extension *extension, bool load);
85398
 
+int sieve_extension_require(const struct sieve_extension *extension);
85399
 
+int sieve_extensions_get_count(void);
85400
 
+const struct sieve_extension *sieve_extension_get_by_id(unsigned int ext_id);
85401
 
+const struct sieve_extension *sieve_extension_get_by_name(const char *name);
85402
 
+
85403
 
+const char *sieve_extensions_get_string(void);
85404
 
+void sieve_extensions_set_string(const char *ext_string);
85405
 
+
85406
 
+/*
85407
 
+ * Capability registries
85408
 
+ */
85409
 
+
85410
 
+struct sieve_extension_capabilities {
85411
 
+       const char *name;
85412
 
+
85413
 
+       const struct sieve_extension *extension;
85414
 
+
85415
 
+       const char *(*get_string)(void);        
85416
 
+};
85417
 
+
85418
 
+void sieve_extension_capabilities_register
85419
 
+       (const struct sieve_extension_capabilities *cap);
85420
 
+const char *sieve_extension_capabilities_get_string
85421
 
+       (const char *cap_name);
85422
 
+
85423
 
+#endif /* __SIEVE_EXTENSIONS_H */
85424
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-generator.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-generator.c
85425
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-generator.c      1970-01-01 01:00:00.000000000 +0100
85426
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-generator.c       2009-01-06 00:15:52.000000000 +0100
85427
 
@@ -0,0 +1,422 @@
85428
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
85429
 
+ */
85430
 
+
85431
 
+#include "lib.h"
85432
 
+#include "mempool.h"
85433
 
+
85434
 
+#include "sieve-common.h"
85435
 
+#include "sieve-extensions.h"
85436
 
+#include "sieve-commands.h"
85437
 
+#include "sieve-code.h"
85438
 
+#include "sieve-binary.h"
85439
 
+
85440
 
+#include "sieve-generator.h"
85441
 
+
85442
 
+/* 
85443
 
+ * Jump list 
85444
 
+ */
85445
 
+
85446
 
+struct sieve_jumplist *sieve_jumplist_create
85447
 
+       (pool_t pool, struct sieve_binary *sbin)
85448
 
+{
85449
 
+       struct sieve_jumplist *jlist;
85450
 
+       
85451
 
+       jlist = p_new(pool, struct sieve_jumplist, 1);
85452
 
+       jlist->binary = sbin;
85453
 
+       p_array_init(&jlist->jumps, pool, 4);
85454
 
+       
85455
 
+       return jlist;
85456
 
+}
85457
 
+
85458
 
+void sieve_jumplist_init_temp
85459
 
+       (struct sieve_jumplist *jlist, struct sieve_binary *sbin)
85460
 
+{
85461
 
+       jlist->binary = sbin;
85462
 
+       t_array_init(&jlist->jumps, 4);
85463
 
+}
85464
 
+
85465
 
+void sieve_jumplist_reset
85466
 
+       (struct sieve_jumplist *jlist)
85467
 
+{
85468
 
+       array_clear(&jlist->jumps);
85469
 
+}
85470
 
+
85471
 
+void sieve_jumplist_add(struct sieve_jumplist *jlist, sieve_size_t jump) 
85472
 
+{
85473
 
+       array_append(&jlist->jumps, &jump, 1);
85474
 
+}
85475
 
+
85476
 
+void sieve_jumplist_resolve(struct sieve_jumplist *jlist) 
85477
 
+{
85478
 
+       unsigned int i;
85479
 
+       
85480
 
+       for ( i = 0; i < array_count(&jlist->jumps); i++ ) {
85481
 
+               const sieve_size_t *jump = array_idx(&jlist->jumps, i);
85482
 
+       
85483
 
+               sieve_binary_resolve_offset(jlist->binary, *jump);
85484
 
+       }
85485
 
+}
85486
 
+
85487
 
+/* 
85488
 
+ * Code Generator 
85489
 
+ */
85490
 
+
85491
 
+struct sieve_generator {
85492
 
+       pool_t pool;
85493
 
+       
85494
 
+       struct sieve_error_handler *ehandler;
85495
 
+
85496
 
+       struct sieve_codegen_env genenv;
85497
 
+       
85498
 
+       ARRAY_DEFINE(ext_contexts, void *);
85499
 
+};
85500
 
+
85501
 
+struct sieve_generator *sieve_generator_create
85502
 
+       (struct sieve_ast *ast, struct sieve_error_handler *ehandler) 
85503
 
+{
85504
 
+       pool_t pool;
85505
 
+       struct sieve_generator *gentr;
85506
 
+       
85507
 
+       pool = pool_alloconly_create("sieve_generator", 4096);  
85508
 
+       gentr = p_new(pool, struct sieve_generator, 1);
85509
 
+       gentr->pool = pool;
85510
 
+
85511
 
+       gentr->ehandler = ehandler;
85512
 
+       sieve_error_handler_ref(ehandler);
85513
 
+       
85514
 
+       gentr->genenv.gentr = gentr;
85515
 
+       gentr->genenv.ast = ast;        
85516
 
+       gentr->genenv.script = sieve_ast_script(ast);
85517
 
+       sieve_ast_ref(ast);
85518
 
+
85519
 
+       /* Setup storage for extension contexts */              
85520
 
+       p_array_init(&gentr->ext_contexts, pool, sieve_extensions_get_count());
85521
 
+               
85522
 
+       return gentr;
85523
 
+}
85524
 
+
85525
 
+void sieve_generator_free(struct sieve_generator **generator) 
85526
 
+{
85527
 
+       sieve_ast_unref(&(*generator)->genenv.ast);
85528
 
+       
85529
 
+       if ( (*generator)->genenv.sbin != NULL )
85530
 
+               sieve_binary_unref(&(*generator)->genenv.sbin);
85531
 
+       
85532
 
+       sieve_error_handler_unref(&(*generator)->ehandler);
85533
 
+
85534
 
+       pool_unref(&((*generator)->pool));
85535
 
+       
85536
 
+       *generator = NULL;
85537
 
+}
85538
 
+
85539
 
+/* 
85540
 
+ * Accessors 
85541
 
+ */
85542
 
+
85543
 
+struct sieve_error_handler *sieve_generator_error_handler
85544
 
+(struct sieve_generator *gentr)
85545
 
+{
85546
 
+       return gentr->ehandler;
85547
 
+}
85548
 
+
85549
 
+pool_t sieve_generator_pool(struct sieve_generator *gentr)
85550
 
+{
85551
 
+       return gentr->pool;
85552
 
+}
85553
 
+
85554
 
+struct sieve_script *sieve_generator_script
85555
 
+(struct sieve_generator *gentr)
85556
 
+{
85557
 
+       return gentr->genenv.script;
85558
 
+}
85559
 
+
85560
 
+struct sieve_binary *sieve_generator_get_binary
85561
 
+       (struct sieve_generator *gentr)
85562
 
+{
85563
 
+       return gentr->genenv.sbin;
85564
 
+}
85565
 
+
85566
 
+/* 
85567
 
+ * Error handling 
85568
 
+ */
85569
 
+
85570
 
+void sieve_generator_warning
85571
 
+(struct sieve_generator *gentr, unsigned int source_line, 
85572
 
+       const char *fmt, ...) 
85573
 
+{ 
85574
 
+       va_list args;
85575
 
+       
85576
 
+       va_start(args, fmt);
85577
 
+       sieve_vwarning(gentr->ehandler,
85578
 
+        sieve_error_script_location(gentr->genenv.script, source_line),
85579
 
+        fmt, args);
85580
 
+       va_end(args);
85581
 
+}
85582
 
85583
 
+void sieve_generator_error
85584
 
+(struct sieve_generator *gentr, unsigned int source_line, 
85585
 
+       const char *fmt, ...) 
85586
 
+{
85587
 
+       va_list args;
85588
 
+       
85589
 
+       va_start(args, fmt);
85590
 
+       sieve_verror(gentr->ehandler,
85591
 
+        sieve_error_script_location(gentr->genenv.script, source_line),
85592
 
+        fmt, args);
85593
 
+       va_end(args);
85594
 
+}
85595
 
+
85596
 
+void sieve_generator_critical
85597
 
+(struct sieve_generator *gentr, unsigned int source_line, 
85598
 
+       const char *fmt, ...) 
85599
 
+{
85600
 
+       va_list args;
85601
 
+       
85602
 
+       va_start(args, fmt);
85603
 
+       sieve_vwarning(gentr->ehandler,
85604
 
+        sieve_error_script_location(gentr->genenv.script, source_line),
85605
 
+        fmt, args);
85606
 
+       va_end(args);
85607
 
+}
85608
 
+
85609
 
+/* 
85610
 
+ * Extension support 
85611
 
+ */
85612
 
+
85613
 
+void sieve_generator_extension_set_context
85614
 
+(struct sieve_generator *gentr, const struct sieve_extension *ext, void *context)
85615
 
+{
85616
 
+       array_idx_set(&gentr->ext_contexts, (unsigned int) SIEVE_EXT_ID(ext), &context);        
85617
 
+}
85618
 
+
85619
 
+const void *sieve_generator_extension_get_context
85620
 
+(struct sieve_generator *gentr, const struct sieve_extension *ext) 
85621
 
+{
85622
 
+       int ext_id = SIEVE_EXT_ID(ext);
85623
 
+       void * const *ctx;
85624
 
+
85625
 
+       if  ( ext_id < 0 || ext_id >= (int) array_count(&gentr->ext_contexts) )
85626
 
+               return NULL;
85627
 
+       
85628
 
+       ctx = array_idx(&gentr->ext_contexts, (unsigned int) ext_id);           
85629
 
+
85630
 
+       return *ctx;
85631
 
+}
85632
 
+
85633
 
+/* 
85634
 
+ * Code generation API
85635
 
+ */
85636
 
+
85637
 
+bool sieve_generate_argument
85638
 
+(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, 
85639
 
+       struct sieve_command_context *cmd)
85640
 
+{
85641
 
+       const struct sieve_argument *argument = arg->argument;
85642
 
+       
85643
 
+       if ( argument == NULL ) return FALSE;
85644
 
+       
85645
 
+       return ( argument->generate == NULL ||  
85646
 
+               argument->generate(cgenv, arg, cmd) );
85647
 
+}
85648
 
+
85649
 
+bool sieve_generate_arguments
85650
 
+(const struct sieve_codegen_env *cgenv, struct sieve_command_context *cmd, 
85651
 
+       struct sieve_ast_argument **last_arg)
85652
 
+{
85653
 
+       enum { ARG_START, ARG_OPTIONAL, ARG_POSITIONAL } state = ARG_START;
85654
 
+       struct sieve_ast_argument *arg = sieve_ast_argument_first(cmd->ast_node);
85655
 
+       
85656
 
+       /* Generate all arguments with assigned generator function */
85657
 
+       
85658
 
+       while ( arg != NULL && arg->argument != NULL) {
85659
 
+               const struct sieve_argument *argument = arg->argument;
85660
 
+               
85661
 
+               switch ( state ) {
85662
 
+               case ARG_START: 
85663
 
+                       if ( arg->arg_id_code == 0 )
85664
 
+                               state = ARG_POSITIONAL;
85665
 
+                       else {
85666
 
+                               /* Mark start of optional operands with 0 operand identifier */
85667
 
+                               sieve_binary_emit_byte(cgenv->sbin, SIEVE_OPERAND_OPTIONAL);
85668
 
+                                                               
85669
 
+                               /* Emit argument id for optional operand */
85670
 
+                               sieve_binary_emit_byte(cgenv->sbin, (unsigned char) arg->arg_id_code);
85671
 
+
85672
 
+                               state = ARG_OPTIONAL;
85673
 
+                       }
85674
 
+                       break;
85675
 
+               case ARG_OPTIONAL: 
85676
 
+                       if ( arg->arg_id_code == 0 )
85677
 
+                               state = ARG_POSITIONAL;
85678
 
+                       
85679
 
+                       /* Emit argument id for optional operand (0 marks the end of the optionals) */
85680
 
+                       sieve_binary_emit_byte(cgenv->sbin, (unsigned char) arg->arg_id_code);
85681
 
+
85682
 
+                       break;
85683
 
+               case ARG_POSITIONAL:
85684
 
+                       if ( arg->arg_id_code != 0 )
85685
 
+                               return FALSE;
85686
 
+                       break;
85687
 
+               }
85688
 
+               
85689
 
+               /* Call the generation function for the argument */ 
85690
 
+               if ( argument->generate != NULL ) { 
85691
 
+                       if ( !argument->generate(cgenv, arg, cmd) ) 
85692
 
+                               return FALSE;
85693
 
+               } else if ( state == ARG_POSITIONAL ) break;
85694
 
+
85695
 
+               arg = sieve_ast_argument_next(arg);
85696
 
+       }
85697
 
+
85698
 
+       /* Mark end of optional list if it is still open */
85699
 
+       if ( state == ARG_OPTIONAL )
85700
 
+               sieve_binary_emit_byte(cgenv->sbin, 0);
85701
 
+       
85702
 
+       if ( last_arg != NULL )
85703
 
+               *last_arg = arg;
85704
 
+       
85705
 
+       return TRUE;
85706
 
+}
85707
 
+
85708
 
+bool sieve_generate_argument_parameters
85709
 
+(const struct sieve_codegen_env *cgenv, 
85710
 
+       struct sieve_command_context *cmd, struct sieve_ast_argument *arg)
85711
 
+{
85712
 
+       struct sieve_ast_argument *param = arg->parameters;
85713
 
+       
85714
 
+       /* Generate all parameters with assigned generator function */
85715
 
+       
85716
 
+       while ( param != NULL && param->argument != NULL) {
85717
 
+               const struct sieve_argument *parameter = param->argument;
85718
 
+                               
85719
 
+               /* Call the generation function for the parameter */ 
85720
 
+               if ( parameter->generate != NULL ) { 
85721
 
+                       if ( !parameter->generate(cgenv, param, cmd) ) 
85722
 
+                               return FALSE;
85723
 
+               }
85724
 
+
85725
 
+               param = sieve_ast_argument_next(param);
85726
 
+       }
85727
 
+               
85728
 
+       return TRUE;
85729
 
+}
85730
 
+
85731
 
+bool sieve_generate_test
85732
 
+(const struct sieve_codegen_env *cgenv, struct sieve_ast_node *tst_node,
85733
 
+       struct sieve_jumplist *jlist, bool jump_true) 
85734
 
+{
85735
 
+       i_assert( tst_node->context != NULL && tst_node->context->command != NULL );
85736
 
+
85737
 
+       if ( tst_node->context->command->control_generate != NULL ) {
85738
 
+               if ( tst_node->context->command->control_generate
85739
 
+                       (cgenv, tst_node->context, jlist, jump_true) ) 
85740
 
+                       return TRUE;
85741
 
+               
85742
 
+               return FALSE;
85743
 
+       }
85744
 
+       
85745
 
+       if ( tst_node->context->command->generate != NULL ) {
85746
 
+
85747
 
+               if ( tst_node->context->command->generate(cgenv, tst_node->context) ) {
85748
 
+                       
85749
 
+                       if ( jump_true ) 
85750
 
+                               sieve_operation_emit_code(cgenv->sbin, &sieve_jmptrue_operation);
85751
 
+                       else
85752
 
+                               sieve_operation_emit_code(cgenv->sbin, &sieve_jmpfalse_operation);
85753
 
+                       sieve_jumplist_add(jlist, sieve_binary_emit_offset(cgenv->sbin, 0));
85754
 
+                                               
85755
 
+                       return TRUE;
85756
 
+               }       
85757
 
+               
85758
 
+               return FALSE;
85759
 
+       }
85760
 
+       
85761
 
+       return TRUE;
85762
 
+}
85763
 
+
85764
 
+static bool sieve_generate_command
85765
 
+(const struct sieve_codegen_env *cgenv, struct sieve_ast_node *cmd_node) 
85766
 
+{
85767
 
+       i_assert( cmd_node->context != NULL && cmd_node->context->command != NULL );
85768
 
+
85769
 
+       if ( cmd_node->context->command->generate != NULL ) {
85770
 
+               return cmd_node->context->command->generate(cgenv, cmd_node->context);
85771
 
+       }
85772
 
+       
85773
 
+       return TRUE;            
85774
 
+}
85775
 
+
85776
 
+bool sieve_generate_block
85777
 
+(const struct sieve_codegen_env *cgenv, struct sieve_ast_node *block) 
85778
 
+{
85779
 
+       bool result = TRUE;
85780
 
+       struct sieve_ast_node *command;
85781
 
+
85782
 
+       T_BEGIN {       
85783
 
+               command = sieve_ast_command_first(block);
85784
 
+               while ( result && command != NULL ) {   
85785
 
+                       result = sieve_generate_command(cgenv, command);        
85786
 
+                       command = sieve_ast_command_next(command);
85787
 
+               }               
85788
 
+       } T_END;
85789
 
+       
85790
 
+       return result;
85791
 
+}
85792
 
+
85793
 
+bool sieve_generator_run
85794
 
+(struct sieve_generator *gentr, struct sieve_binary **sbin) 
85795
 
+{
85796
 
+       bool topmost = ( *sbin == NULL );
85797
 
+       bool result = TRUE;
85798
 
+       const struct sieve_extension *const *extensions;
85799
 
+       unsigned int i, ext_count;
85800
 
+       
85801
 
+       /* Initialize */
85802
 
+       
85803
 
+       if ( topmost )
85804
 
+               *sbin = sieve_binary_create_new(sieve_ast_script(gentr->genenv.ast));
85805
 
+       
85806
 
+       sieve_binary_ref(*sbin);
85807
 
+               
85808
 
+       gentr->genenv.sbin = *sbin;
85809
 
+               
85810
 
+       /* Load extensions linked to the AST and emit a list in code */
85811
 
+       extensions = sieve_ast_extensions_get(gentr->genenv.ast, &ext_count);
85812
 
+       (void) sieve_binary_emit_unsigned(*sbin, ext_count);
85813
 
+       for ( i = 0; i < ext_count; i++ ) {
85814
 
+               const struct sieve_extension *ext = extensions[i];
85815
 
+
85816
 
+               /* Link to binary */
85817
 
+               (void)sieve_binary_extension_link(*sbin, ext);
85818
 
+       
85819
 
+               /* Emit */
85820
 
+               sieve_binary_emit_extension(*sbin, ext, 0);
85821
 
+       
85822
 
+               /* Load */
85823
 
+               if ( ext->generator_load != NULL && !ext->generator_load(&gentr->genenv) )
85824
 
+                       return FALSE;
85825
 
+       }
85826
 
+
85827
 
+       /* Generate code */
85828
 
+       
85829
 
+       if ( !sieve_generate_block
85830
 
+               (&gentr->genenv, sieve_ast_root(gentr->genenv.ast))) 
85831
 
+               result = FALSE;
85832
 
+       else if ( topmost ) 
85833
 
+               sieve_binary_activate(*sbin);
85834
 
+
85835
 
+       /* Cleanup */
85836
 
+               
85837
 
+       gentr->genenv.sbin = NULL;
85838
 
+       sieve_binary_unref(sbin);
85839
 
+
85840
 
+       if ( topmost && !result ) {
85841
 
+               sieve_binary_unref(sbin);
85842
 
+               *sbin = NULL;
85843
 
+       }
85844
 
+       
85845
 
+       return result;
85846
 
+}
85847
 
+
85848
 
+
85849
 
+
85850
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-generator.h dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-generator.h
85851
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-generator.h      1970-01-01 01:00:00.000000000 +0100
85852
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-generator.h       2009-01-06 00:15:52.000000000 +0100
85853
 
@@ -0,0 +1,106 @@
85854
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
85855
 
+ */
85856
 
+
85857
 
+#ifndef __SIEVE_GENERATOR_H
85858
 
+#define __SIEVE_GENERATOR_H
85859
 
+
85860
 
+#include "sieve-common.h"
85861
 
+
85862
 
+/*
85863
 
+ * Code generator
85864
 
+ */
85865
 
+
85866
 
+struct sieve_generator;
85867
 
+
85868
 
+struct sieve_codegen_env {
85869
 
+       struct sieve_generator *gentr;
85870
 
+
85871
 
+    struct sieve_script *script;
85872
 
+       struct sieve_ast *ast;
85873
 
+       struct sieve_binary *sbin;
85874
 
+};
85875
 
+
85876
 
+struct sieve_generator *sieve_generator_create
85877
 
+       (struct sieve_ast *ast, struct sieve_error_handler *ehandler);
85878
 
+void sieve_generator_free(struct sieve_generator **generator);
85879
 
+
85880
 
+/* 
85881
 
+ * Accessors 
85882
 
+ */
85883
 
+
85884
 
+struct sieve_error_handler *sieve_generator_error_handler
85885
 
+       (struct sieve_generator *gentr);
85886
 
+pool_t sieve_generator_pool(struct sieve_generator *gentr);
85887
 
+struct sieve_script *sieve_generator_script
85888
 
+       (struct sieve_generator *gentr);
85889
 
+struct sieve_binary *sieve_generator_get_binary
85890
 
+       (struct sieve_generator *gentr);
85891
 
+
85892
 
+/* 
85893
 
+ * Error handling 
85894
 
+ */
85895
 
+
85896
 
+void sieve_generator_warning
85897
 
+(struct sieve_generator *gentr, unsigned int source_line, 
85898
 
+       const char *fmt, ...) ATTR_FORMAT(3, 4);; 
85899
 
+void sieve_generator_error
85900
 
+(struct sieve_generator *gentr, unsigned int source_line, 
85901
 
+       const char *fmt, ...) ATTR_FORMAT(3, 4);
85902
 
+void sieve_generator_critical
85903
 
+(struct sieve_generator *gentr, unsigned int source_line, 
85904
 
+       const char *fmt, ...) ATTR_FORMAT(3, 4); 
85905
 
+
85906
 
+/* 
85907
 
+ * Extension support 
85908
 
+ */
85909
 
+
85910
 
+void sieve_generator_extension_set_context
85911
 
+       (struct sieve_generator *gentr, const struct sieve_extension *ext, 
85912
 
+               void *context);
85913
 
+const void *sieve_generator_extension_get_context
85914
 
+       (struct sieve_generator *gentr, const struct sieve_extension *ext);
85915
 
+               
85916
 
+/* 
85917
 
+ * Jump list 
85918
 
+ */
85919
 
+
85920
 
+struct sieve_jumplist {
85921
 
+       pool_t pool;
85922
 
+       struct sieve_binary *binary;
85923
 
+       ARRAY_DEFINE(jumps, sieve_size_t);
85924
 
+};
85925
 
+
85926
 
+struct sieve_jumplist *sieve_jumplist_create
85927
 
+       (pool_t pool, struct sieve_binary *sbin);
85928
 
+void sieve_jumplist_init_temp
85929
 
+       (struct sieve_jumplist *jlist, struct sieve_binary *sbin);
85930
 
+void sieve_jumplist_reset
85931
 
+       (struct sieve_jumplist *jlist);
85932
 
+void sieve_jumplist_add
85933
 
+       (struct sieve_jumplist *jlist, sieve_size_t jump);
85934
 
+void sieve_jumplist_resolve(struct sieve_jumplist *jlist);
85935
 
+
85936
 
+/* 
85937
 
+ * Code generation API 
85938
 
+ */
85939
 
+
85940
 
+bool sieve_generate_argument
85941
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, 
85942
 
+               struct sieve_command_context *cmd);
85943
 
+bool sieve_generate_arguments
85944
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_command_context *cmd, 
85945
 
+               struct sieve_ast_argument **arg);
85946
 
+bool sieve_generate_argument_parameters
85947
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_command_context *cmd, 
85948
 
+               struct sieve_ast_argument *arg);
85949
 
+
85950
 
+bool sieve_generate_block
85951
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_ast_node *block);
85952
 
+bool sieve_generate_test
85953
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_ast_node *tst_node, 
85954
 
+               struct sieve_jumplist *jlist, bool jump_true);
85955
 
+bool sieve_generator_run
85956
 
+       (struct sieve_generator *gentr, struct sieve_binary **sbin);
85957
 
+
85958
 
+#endif /* __SIEVE_GENERATOR_H */
85959
 
+
85960
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve.h dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve.h
85961
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve.h        1970-01-01 01:00:00.000000000 +0100
85962
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve.h 2009-08-02 15:20:14.000000000 +0200
85963
 
@@ -0,0 +1,160 @@
85964
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file 
85965
 
+ */
85966
 
+
85967
 
+#ifndef __SIEVE_H
85968
 
+#define __SIEVE_H
85969
 
+
85970
 
+#include <stdio.h>
85971
 
+
85972
 
+struct sieve_script;
85973
 
+struct sieve_binary;
85974
 
+
85975
 
+#include "sieve-config.h"
85976
 
+#include "sieve-types.h"
85977
 
+#include "sieve-error.h"
85978
 
+
85979
 
+/*
85980
 
+ * Main Sieve library interface
85981
 
+ */
85982
 
+
85983
 
+/* sieve_init(): 
85984
 
+ *   Initializes the sieve engine. Must be called before any sieve functionality
85985
 
+ *   is used.
85986
 
+ */
85987
 
+bool sieve_init(void);
85988
 
+
85989
 
+/* sieve_deinit():
85990
 
+ *   Frees all memory allocated by the sieve engine. 
85991
 
+ */
85992
 
+void sieve_deinit(void);
85993
 
+
85994
 
+/* sieve_get_capabilities():
85995
 
+ *
85996
 
+ */
85997
 
+const char *sieve_get_capabilities(const char *name);
85998
 
+
85999
 
+/* sieve_set_extensions():
86000
 
+ *
86001
 
+ */
86002
 
+void sieve_set_extensions(const char *extensions);
86003
 
+
86004
 
+/*
86005
 
+ * Script compilation
86006
 
+ */
86007
 
+
86008
 
+/* sieve_compile_script:
86009
 
+ */
86010
 
+struct sieve_binary *sieve_compile_script
86011
 
+       (struct sieve_script *script, struct sieve_error_handler *ehandler);
86012
 
+
86013
 
+/* sieve_compile:
86014
 
+ *
86015
 
+ *   Compiles the script into a binary.
86016
 
+ */
86017
 
+struct sieve_binary *sieve_compile
86018
 
+       (const char *script_path, const char *script_name, 
86019
 
+               struct sieve_error_handler *ehandler);
86020
 
+
86021
 
+/* 
86022
 
+ * Reading/writing Sieve binaries
86023
 
+ */
86024
 
+
86025
 
+/* sieve_open:
86026
 
+ *
86027
 
+ *   First tries to open the binary version of the specified script and
86028
 
+ *   if it does not exist or if it contains errors, the script is
86029
 
+ *   (re-)compiled. The binary is updated if the script is recompiled.
86030
 
+ *   Note that errors in the bytecode are not caught here.
86031
 
+ *
86032
 
+ */
86033
 
+struct sieve_binary *sieve_open
86034
 
+       (const char *scriptpath, const char *script_name, 
86035
 
+               struct sieve_error_handler *ehandler, bool *exists_r);
86036
 
+
86037
 
+/* sieve_save:
86038
 
+ *
86039
 
+ *  Saves the binary as the file indicated by the path parameter. If 
86040
 
+ *  path is NULL, it chooses the default path relative to the original
86041
 
+ *  script.
86042
 
+ */
86043
 
+bool sieve_save
86044
 
+    (struct sieve_binary *sbin, const char *bin_path);
86045
 
+
86046
 
+/* sieve_load:
86047
 
+ *
86048
 
+ *  Loads the sieve binary indicated by the provided path.
86049
 
+ */
86050
 
+struct sieve_binary *sieve_load
86051
 
+       (const char *bin_path);
86052
 
+
86053
 
+/* sieve_close:
86054
 
+ *
86055
 
+ *   Closes a compiled/opened sieve binary.
86056
 
+ */
86057
 
+void sieve_close(struct sieve_binary **sbin);
86058
 
+
86059
 
+/*
86060
 
+ * Debugging
86061
 
+ */
86062
 
+
86063
 
+/* sieve_dump:
86064
 
+ *
86065
 
+ *   Dumps the byte code in human-readable form to the specified ostream.
86066
 
+ */
86067
 
+void sieve_dump(struct sieve_binary *sbin, struct ostream *stream);
86068
 
+
86069
 
+/* sieve_test:
86070
 
+ *
86071
 
+ *   Executes the bytecode, but only prints the result to the given stream.
86072
 
+ */ 
86073
 
+int sieve_test
86074
 
+       (struct sieve_binary *sbin, const struct sieve_message_data *msgdata, 
86075
 
+               const struct sieve_script_env *senv, struct sieve_error_handler *ehandler, 
86076
 
+               struct ostream *stream, bool *keep);
86077
 
+
86078
 
+/*
86079
 
+ * Script execution
86080
 
+ */
86081
 
+
86082
 
+/* sieve_execute:
86083
 
+ *
86084
 
+ *   Executes the binary, including the result.  
86085
 
+ */
86086
 
+int sieve_execute
86087
 
+       (struct sieve_binary *sbin, const struct sieve_message_data *msgdata,
86088
 
+               const struct sieve_script_env *senv, struct sieve_error_handler *ehandler,
86089
 
+               bool *keep);
86090
 
+               
86091
 
+/*
86092
 
+ * Multiscript support
86093
 
+ */
86094
 
86095
 
+struct sieve_multiscript;
86096
 
86097
 
+struct sieve_multiscript *sieve_multiscript_start_execute
86098
 
+       (const struct sieve_message_data *msgdata, const struct sieve_script_env *senv);
86099
 
+struct sieve_multiscript *sieve_multiscript_start_test
86100
 
+       (const struct sieve_message_data *msgdata, const struct sieve_script_env *senv,
86101
 
+               struct ostream *stream);
86102
 
+
86103
 
+bool sieve_multiscript_run
86104
 
+       (struct sieve_multiscript *mscript, struct sieve_binary *sbin, 
86105
 
+               struct sieve_error_handler *ehandler, bool final);
86106
 
+
86107
 
+int sieve_multiscript_status(struct sieve_multiscript *mscript);
86108
 
+
86109
 
+int sieve_multiscript_finish
86110
 
+       (struct sieve_multiscript **mscript, struct sieve_error_handler *ehandler,
86111
 
+               bool *keep);
86112
 
+
86113
 
+/*
86114
 
+ * Script directory
86115
 
+ */
86116
 
+
86117
 
+struct sieve_directory;
86118
 
+
86119
 
+struct sieve_directory *sieve_directory_open(const char *path);
86120
 
+const char *sieve_directory_get_scriptfile(struct sieve_directory *sdir);
86121
 
+void sieve_directory_close(struct sieve_directory **sdir);
86122
 
+
86123
 
+#endif
86124
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-interpreter.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-interpreter.c
86125
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-interpreter.c    1970-01-01 01:00:00.000000000 +0100
86126
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-interpreter.c     2009-08-05 13:10:01.000000000 +0200
86127
 
@@ -0,0 +1,528 @@
86128
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
86129
 
+ */
86130
 
+
86131
 
+#include "lib.h"
86132
 
+#include "ostream.h"
86133
 
+#include "mempool.h"
86134
 
+#include "array.h"
86135
 
+#include "hash.h"
86136
 
+#include "mail-storage.h"
86137
 
+
86138
 
+#include "sieve-common.h"
86139
 
+#include "sieve-script.h"
86140
 
+#include "sieve-error.h"
86141
 
+#include "sieve-extensions.h"
86142
 
+#include "sieve-message.h"
86143
 
+#include "sieve-commands.h"
86144
 
+#include "sieve-code.h"
86145
 
+#include "sieve-actions.h"
86146
 
+#include "sieve-generator.h"
86147
 
+#include "sieve-binary.h"
86148
 
+#include "sieve-result.h"
86149
 
+#include "sieve-comparators.h"
86150
 
+
86151
 
+#include "sieve-interpreter.h"
86152
 
+
86153
 
+#include <string.h>
86154
 
+
86155
 
+/* 
86156
 
+ * Interpreter extension 
86157
 
+ */
86158
 
+
86159
 
+struct sieve_interpreter_extension_reg {
86160
 
+       const struct sieve_interpreter_extension *int_ext;
86161
 
+       void *context;
86162
 
+};
86163
 
+
86164
 
+/* 
86165
 
+ * Interpreter 
86166
 
+ */
86167
 
+
86168
 
+struct sieve_interpreter {
86169
 
+       pool_t pool;
86170
 
+                       
86171
 
+       struct sieve_error_handler *ehandler;
86172
 
+
86173
 
+       /* Runtime data for extensions */
86174
 
+       ARRAY_DEFINE(extensions, struct sieve_interpreter_extension_reg); 
86175
 
+       
86176
 
+       sieve_size_t reset_vector;      
86177
 
+               
86178
 
+       /* Execution status */
86179
 
+       
86180
 
+       sieve_size_t pc;          /* Program counter */
86181
 
+       bool interrupted;         /* Interpreter interrupt requested */
86182
 
+       bool test_result;         /* Result of previous test command */
86183
 
+
86184
 
+       /* Current operation */ 
86185
 
+       const struct sieve_operation *current_op;
86186
 
+       
86187
 
+       /* Start address of current operation */
86188
 
+       sieve_size_t current_op_addr;             
86189
 
+       
86190
 
+       /* Runtime environment */
86191
 
+       struct sieve_runtime_env runenv; 
86192
 
+};
86193
 
+
86194
 
+struct sieve_interpreter *sieve_interpreter_create
86195
 
+(struct sieve_binary *sbin, struct sieve_error_handler *ehandler) 
86196
 
+{
86197
 
+       unsigned int i, ext_count;
86198
 
+       bool success = TRUE;
86199
 
+
86200
 
+       pool_t pool;
86201
 
+       struct sieve_interpreter *interp;
86202
 
+       
86203
 
+       pool = pool_alloconly_create("sieve_interpreter", 4096);        
86204
 
+       interp = p_new(pool, struct sieve_interpreter, 1);
86205
 
+       interp->pool = pool;
86206
 
+
86207
 
+       interp->ehandler = ehandler;
86208
 
+       sieve_error_handler_ref(ehandler);
86209
 
+
86210
 
+       interp->runenv.interp = interp; 
86211
 
+       interp->runenv.sbin = sbin;
86212
 
+       interp->runenv.script = sieve_binary_script(sbin);
86213
 
+       sieve_binary_ref(sbin);
86214
 
+       
86215
 
+       interp->pc = 0;
86216
 
+
86217
 
+       p_array_init(&interp->extensions, pool, sieve_extensions_get_count());
86218
 
+
86219
 
+       /* Pre-load core language features implemented as 'extensions' */
86220
 
+       for ( i = 0; i < sieve_preloaded_extensions_count; i++ ) {
86221
 
+               const struct sieve_extension *ext = sieve_preloaded_extensions[i];
86222
 
+               
86223
 
+               if ( ext->interpreter_load != NULL )
86224
 
+                       (void)ext->interpreter_load(&interp->runenv, &interp->pc);              
86225
 
+       }
86226
 
+
86227
 
+       /* Load other extensions listed in code */
86228
 
+       if ( sieve_binary_read_unsigned(sbin, &interp->pc, &ext_count) ) {
86229
 
+               for ( i = 0; i < ext_count; i++ ) {
86230
 
+                       unsigned int code = 0;
86231
 
+                       const struct sieve_extension *ext;
86232
 
+                       
86233
 
+                       if ( !sieve_binary_read_extension(sbin, &interp->pc, &code, &ext) ) {
86234
 
+                               success = FALSE;
86235
 
+                               break;
86236
 
+                       }
86237
 
86238
 
+                       if ( ext->interpreter_load != NULL && 
86239
 
+                               !ext->interpreter_load(&interp->runenv, &interp->pc) ) {
86240
 
+                               success = FALSE;
86241
 
+                               break;
86242
 
+                       }
86243
 
+               }
86244
 
+       }       else
86245
 
+               success = FALSE;
86246
 
+       
86247
 
+       if ( !success ) {
86248
 
+               sieve_interpreter_free(&interp);
86249
 
+       } else {
86250
 
+               interp->reset_vector = interp->pc;
86251
 
+       }
86252
 
+       
86253
 
+       return interp;
86254
 
+}
86255
 
+
86256
 
+void sieve_interpreter_free(struct sieve_interpreter **interp) 
86257
 
+{
86258
 
+       const struct sieve_interpreter_extension_reg *extrs;
86259
 
+       unsigned int ext_count, i;
86260
 
+
86261
 
+       sieve_binary_unref(&(*interp)->runenv.sbin);
86262
 
+
86263
 
+       sieve_error_handler_unref(&(*interp)->ehandler);
86264
 
+
86265
 
+       /* Signal registered extensions that the interpreter is being destroyed */
86266
 
+       extrs = array_get(&(*interp)->extensions, &ext_count);
86267
 
+       for ( i = 0; i < ext_count; i++ ) {
86268
 
+               if ( extrs[i].int_ext != NULL && extrs[i].int_ext->free != NULL )
86269
 
+                       extrs[i].int_ext->free(*interp, extrs[i].context);
86270
 
+       }
86271
 
+                
86272
 
+       pool_unref(&((*interp)->pool)); 
86273
 
+       *interp = NULL;
86274
 
+}
86275
 
+
86276
 
+/*
86277
 
+ * Accessors
86278
 
+ */
86279
 
+
86280
 
+pool_t sieve_interpreter_pool(struct sieve_interpreter *interp)
86281
 
+{
86282
 
+       return interp->pool;
86283
 
+}
86284
 
+
86285
 
+struct sieve_script *sieve_interpreter_script
86286
 
+(struct sieve_interpreter *interp)
86287
 
+{
86288
 
+       return interp->runenv.script;
86289
 
+}
86290
 
+
86291
 
+struct sieve_error_handler *sieve_interpreter_get_error_handler
86292
 
+(struct sieve_interpreter *interp)
86293
 
+{
86294
 
+       return interp->ehandler;
86295
 
+}
86296
 
+
86297
 
+/* Do not use this function for normal sieve extensions. This is intended for
86298
 
+ * the testsuite only.
86299
 
+ */
86300
 
+void sieve_interpreter_set_result
86301
 
+(struct sieve_interpreter *interp, struct sieve_result *result)
86302
 
+{
86303
 
+       sieve_result_unref(&interp->runenv.result);
86304
 
+       interp->runenv.result = result;
86305
 
+       sieve_result_ref(result);
86306
 
+}
86307
 
+
86308
 
+/* 
86309
 
+ * Error handling 
86310
 
+ */
86311
 
+
86312
 
+/* This is not particularly user friendly, so avoid using this
86313
 
+ */
86314
 
+const char *sieve_runtime_location(const struct sieve_runtime_env *runenv)
86315
 
+{
86316
 
+       const char *op = runenv->interp->current_op == NULL ?
86317
 
+               "<<NOOP>>" : runenv->interp->current_op->mnemonic;
86318
 
+       return t_strdup_printf("%s: #%08llx: %s", sieve_script_name(runenv->script),
86319
 
+               (unsigned long long) runenv->interp->current_op_addr, op);
86320
 
+}
86321
 
+
86322
 
+void sieve_runtime_error
86323
 
+(const struct sieve_runtime_env *runenv, const char *location,
86324
 
+       const char *fmt, ...)
86325
 
+{
86326
 
+       va_list args;
86327
 
+       
86328
 
+       va_start(args, fmt);
86329
 
+       T_BEGIN {
86330
 
+               sieve_verror(runenv->interp->ehandler, location, fmt, args); 
86331
 
+       } T_END;
86332
 
+       va_end(args);
86333
 
+}
86334
 
+
86335
 
+void sieve_runtime_warning
86336
 
+(const struct sieve_runtime_env *runenv, const char *location,
86337
 
+       const char *fmt, ...)
86338
 
+{      
86339
 
+       va_list args;
86340
 
+       
86341
 
+       va_start(args, fmt);
86342
 
+       T_BEGIN {
86343
 
+               sieve_vwarning(runenv->interp->ehandler, location, fmt, args);
86344
 
+       } T_END; 
86345
 
+       va_end(args);
86346
 
+}
86347
 
+
86348
 
+void sieve_runtime_log
86349
 
+(const struct sieve_runtime_env *runenv, const char *location,
86350
 
+       const char *fmt, ...)
86351
 
+{      
86352
 
+       va_list args;
86353
 
+       
86354
 
+       va_start(args, fmt);
86355
 
+       T_BEGIN {
86356
 
+               sieve_vinfo(runenv->interp->ehandler, location, fmt, args); 
86357
 
+       } T_END;
86358
 
+       va_end(args);
86359
 
+}
86360
 
+
86361
 
+/*
86362
 
+ * Runtime trace
86363
 
+ */
86364
 
+
86365
 
+#ifdef SIEVE_RUNTIME_TRACE
86366
 
+void _sieve_runtime_trace
86367
 
+(const struct sieve_runtime_env *runenv, const char *fmt, ...)
86368
 
+{      
86369
 
+       string_t *outbuf = t_str_new(128);
86370
 
+       va_list args;
86371
 
+       
86372
 
+       va_start(args, fmt);    
86373
 
+       str_printfa(outbuf, "%08llx: ", (unsigned long long) runenv->interp->current_op_addr); 
86374
 
+       str_vprintfa(outbuf, fmt, args); 
86375
 
+       str_append_c(outbuf, '\n');
86376
 
+       va_end(args);
86377
 
+       
86378
 
+       o_stream_send(runenv->trace_stream, str_data(outbuf), str_len(outbuf)); 
86379
 
+}
86380
 
+
86381
 
+void _sieve_runtime_trace_error
86382
 
+(const struct sieve_runtime_env *runenv, const char *fmt, ...)
86383
 
+{
86384
 
+       string_t *outbuf = t_str_new(128);
86385
 
+       va_list args;
86386
 
+
86387
 
+       va_start(args, fmt);
86388
 
+       str_printfa(outbuf, "%08llx: [[ERROR: %s: ", 
86389
 
+               (unsigned long long) runenv->interp->pc, 
86390
 
+               runenv->interp->current_op->mnemonic);
86391
 
+       str_vprintfa(outbuf, fmt, args);
86392
 
+    str_append(outbuf, "]]\n");
86393
 
+       va_end(args);
86394
 
+
86395
 
+       o_stream_send(runenv->trace_stream, str_data(outbuf), str_len(outbuf));
86396
 
+}
86397
 
+#endif
86398
 
+
86399
 
+/* 
86400
 
+ * Extension support 
86401
 
+ */
86402
 
+
86403
 
+void sieve_interpreter_extension_register
86404
 
+(struct sieve_interpreter *interp, 
86405
 
+       const struct sieve_interpreter_extension *int_ext, void *context)
86406
 
+{
86407
 
+       struct sieve_interpreter_extension_reg reg = { int_ext, context };
86408
 
+       int ext_id = SIEVE_EXT_ID(int_ext->ext);
86409
 
+
86410
 
+       if ( ext_id < 0 ) return;
86411
 
+       
86412
 
+       array_idx_set(&interp->extensions, (unsigned int) ext_id, &reg);        
86413
 
+}
86414
 
+
86415
 
+void sieve_interpreter_extension_set_context
86416
 
+(struct sieve_interpreter *interp, const struct sieve_extension *ext, 
86417
 
+       void *context)
86418
 
+{
86419
 
+       struct sieve_interpreter_extension_reg reg = { NULL, context };
86420
 
+       int ext_id = SIEVE_EXT_ID(ext);
86421
 
+
86422
 
+       if ( ext_id < 0 ) return;
86423
 
+       
86424
 
+       array_idx_set(&interp->extensions, (unsigned int) ext_id, &reg);        
86425
 
+}
86426
 
+
86427
 
+void *sieve_interpreter_extension_get_context
86428
 
+(struct sieve_interpreter *interp, const struct sieve_extension *ext) 
86429
 
+{
86430
 
+       int ext_id = SIEVE_EXT_ID(ext);
86431
 
+       const struct sieve_interpreter_extension_reg *reg;
86432
 
+
86433
 
+       if  ( ext_id < 0 || ext_id >= (int) array_count(&interp->extensions) )
86434
 
+               return NULL;
86435
 
+       
86436
 
+       reg = array_idx(&interp->extensions, (unsigned int) ext_id);            
86437
 
+
86438
 
+       return reg->context;
86439
 
+}
86440
 
+
86441
 
+/* 
86442
 
+ * Program flow 
86443
 
+ */
86444
 
+
86445
 
+void sieve_interpreter_reset(struct sieve_interpreter *interp) 
86446
 
+{
86447
 
+       interp->pc = interp->reset_vector;
86448
 
+       interp->interrupted = FALSE;
86449
 
+       interp->test_result = FALSE;
86450
 
+       interp->runenv.msgdata = NULL;
86451
 
+       interp->runenv.result = NULL;
86452
 
+}
86453
 
+
86454
 
+void sieve_interpreter_interrupt(struct sieve_interpreter *interp)
86455
 
+{
86456
 
+       interp->interrupted = TRUE;
86457
 
+}
86458
 
+
86459
 
+sieve_size_t sieve_interpreter_program_counter(struct sieve_interpreter *interp)
86460
 
+{
86461
 
+       return interp->pc;
86462
 
+}
86463
 
+
86464
 
+int sieve_interpreter_program_jump
86465
 
+(struct sieve_interpreter *interp, bool jump)
86466
 
+{
86467
 
+       const struct sieve_runtime_env *renv = &interp->runenv;
86468
 
+       sieve_size_t pc = interp->pc;
86469
 
+       int offset;
86470
 
+       
86471
 
+       if ( !sieve_binary_read_offset(renv->sbin, &(interp->pc), &offset) )
86472
 
+       {
86473
 
+               sieve_runtime_trace_error(renv, "invalid jump offset"); 
86474
 
+               return SIEVE_EXEC_BIN_CORRUPT;
86475
 
+       }
86476
 
+
86477
 
+       if ( pc + offset <= sieve_binary_get_code_size(renv->sbin) && 
86478
 
+               pc + offset > 0 ) 
86479
 
+       {       
86480
 
+               if ( jump )
86481
 
+                       interp->pc = pc + offset;
86482
 
+               
86483
 
+               return SIEVE_EXEC_OK;
86484
 
+       }
86485
 
+       
86486
 
+       sieve_runtime_trace_error(renv, "jump offset out of range");
86487
 
+       return SIEVE_EXEC_BIN_CORRUPT;
86488
 
+}
86489
 
+
86490
 
+/*
86491
 
+ * Test results
86492
 
+ */
86493
 
+
86494
 
+void sieve_interpreter_set_test_result
86495
 
+(struct sieve_interpreter *interp, bool result)
86496
 
+{
86497
 
+       interp->test_result = result;
86498
 
+}
86499
 
+
86500
 
+bool sieve_interpreter_get_test_result
86501
 
+(struct sieve_interpreter *interp)
86502
 
+{
86503
 
+       return interp->test_result;
86504
 
+}
86505
 
+
86506
 
+/* 
86507
 
+ * Operations and operands 
86508
 
+ */
86509
 
+
86510
 
+int sieve_interpreter_handle_optional_operands
86511
 
+(const struct sieve_runtime_env *renv, sieve_size_t *address,
86512
 
+       struct sieve_side_effects_list **list)
86513
 
+{
86514
 
+       signed int opt_code = -1;
86515
 
+       
86516
 
+       if ( sieve_operand_optional_present(renv->sbin, address) ) {
86517
 
+               while ( opt_code != 0 ) {
86518
 
+                       if ( !sieve_operand_optional_read(renv->sbin, address, &opt_code) ) {
86519
 
+                               sieve_runtime_trace_error(renv, "invalid optional operand");
86520
 
+                               return SIEVE_EXEC_BIN_CORRUPT;
86521
 
+                       }
86522
 
+
86523
 
+                       if ( opt_code == SIEVE_OPT_SIDE_EFFECT ) {
86524
 
+                               void *context = NULL;
86525
 
+                       
86526
 
+                               if ( list != NULL && *list == NULL ) 
86527
 
+                                       *list = sieve_side_effects_list_create(renv->result);
86528
 
+                                       
86529
 
+                               const struct sieve_side_effect *seffect = 
86530
 
+                                       sieve_opr_side_effect_read(renv, address);
86531
 
+
86532
 
+                               if ( seffect == NULL ) {
86533
 
+                                       sieve_runtime_trace_error(renv, "invalid side effect operand");
86534
 
+                                       return SIEVE_EXEC_BIN_CORRUPT;
86535
 
+                               }
86536
 
+                       
86537
 
+                               if ( list != NULL ) {
86538
 
+                                       if ( seffect->read_context != NULL && !seffect->read_context
86539
 
+                                               (seffect, renv, address, &context) ) {
86540
 
+                                               sieve_runtime_trace_error(renv, "invalid side effect context");
86541
 
+                                               return SIEVE_EXEC_BIN_CORRUPT;
86542
 
+                                       }
86543
 
+                               
86544
 
+                                       sieve_side_effects_list_add(*list, seffect, context);
86545
 
+                               }
86546
 
+                       }
86547
 
+               }
86548
 
+       }
86549
 
+       return TRUE;
86550
 
+}
86551
 
86552
 
+/* 
86553
 
+ * Code execute 
86554
 
+ */
86555
 
+
86556
 
+static int sieve_interpreter_execute_operation
86557
 
+(struct sieve_interpreter *interp) 
86558
 
+{
86559
 
+       const struct sieve_operation *op;
86560
 
+
86561
 
+       interp->current_op_addr = interp->pc;
86562
 
+       interp->current_op = op =
86563
 
+               sieve_operation_read(interp->runenv.sbin, &(interp->pc));
86564
 
+
86565
 
+       if ( op != NULL ) {
86566
 
+               int result = SIEVE_EXEC_OK;
86567
 
+
86568
 
+               if ( op->execute != NULL ) { /* Noop ? */
86569
 
+                       T_BEGIN {
86570
 
+                               result = op->execute(op, &(interp->runenv), &(interp->pc));
86571
 
+                       } T_END;
86572
 
+               } else {
86573
 
+                       sieve_runtime_trace(&interp->runenv, "OP: %s (NOOP)", op->mnemonic);
86574
 
+               }
86575
 
+
86576
 
+               return result;
86577
 
+       }
86578
 
+       
86579
 
+       sieve_runtime_trace(&interp->runenv, "Encountered invalid operation");  
86580
 
+       return SIEVE_EXEC_BIN_CORRUPT;
86581
 
+}              
86582
 
+
86583
 
+int sieve_interpreter_continue
86584
 
+(struct sieve_interpreter *interp, bool *interrupted) 
86585
 
+{
86586
 
+       int ret = SIEVE_EXEC_OK;
86587
 
+       
86588
 
+       sieve_result_ref(interp->runenv.result);
86589
 
+       interp->interrupted = FALSE;
86590
 
+       
86591
 
+       if ( interrupted != NULL )
86592
 
+               *interrupted = FALSE;
86593
 
+       
86594
 
+       while ( ret == SIEVE_EXEC_OK && !interp->interrupted && 
86595
 
+               interp->pc < sieve_binary_get_code_size(interp->runenv.sbin) ) {
86596
 
+               
86597
 
+               ret = sieve_interpreter_execute_operation(interp);
86598
 
+
86599
 
+               if ( ret != SIEVE_EXEC_OK ) {
86600
 
+                       sieve_runtime_trace(&interp->runenv, "[[EXECUTION ABORTED]]");
86601
 
+               }
86602
 
+       }
86603
 
+       
86604
 
+       if ( interrupted != NULL )
86605
 
+               *interrupted = interp->interrupted;
86606
 
+                       
86607
 
+       sieve_result_unref(&interp->runenv.result);
86608
 
+       return ret;
86609
 
+}
86610
 
+
86611
 
+int sieve_interpreter_start
86612
 
+(struct sieve_interpreter *interp, const struct sieve_message_data *msgdata,
86613
 
+       const struct sieve_script_env *senv, struct sieve_result *result, bool *interrupted) 
86614
 
+{
86615
 
+       const struct sieve_interpreter_extension_reg *extrs;
86616
 
+       unsigned int ext_count, i;
86617
 
+       
86618
 
+       interp->runenv.msgdata = msgdata;
86619
 
+       interp->runenv.result = result;
86620
 
+       interp->runenv.msgctx = sieve_result_get_message_context(result);               
86621
 
+       interp->runenv.scriptenv = senv;
86622
 
+       interp->runenv.trace_stream = senv->trace_stream;
86623
 
+
86624
 
+       if ( senv->exec_status == NULL ) 
86625
 
+               interp->runenv.exec_status = p_new(interp->pool, struct sieve_exec_status, 1);
86626
 
+       else
86627
 
+               interp->runenv.exec_status = senv->exec_status;
86628
 
+       
86629
 
+       /* Signal registered extensions that the interpreter is being run */
86630
 
+       extrs = array_get(&interp->extensions, &ext_count);
86631
 
+       for ( i = 0; i < ext_count; i++ ) {
86632
 
+               if ( extrs[i].int_ext != NULL && extrs[i].int_ext->run != NULL )
86633
 
+                       extrs[i].int_ext->run(&interp->runenv, extrs[i].context);
86634
 
+       }
86635
 
+
86636
 
+       return sieve_interpreter_continue(interp, interrupted); 
86637
 
+}
86638
 
+
86639
 
+int sieve_interpreter_run
86640
 
+(struct sieve_interpreter *interp, const struct sieve_message_data *msgdata,
86641
 
+       const struct sieve_script_env *senv, struct sieve_result *result)
86642
 
+{
86643
 
+       int ret = 0;
86644
 
+       
86645
 
+       sieve_interpreter_reset(interp);
86646
 
+       sieve_result_ref(result);
86647
 
+       
86648
 
+       ret = sieve_interpreter_start(interp, msgdata, senv, result, NULL);
86649
 
+       
86650
 
+       sieve_result_unref(&result);
86651
 
+       
86652
 
+       return ret;
86653
 
+}
86654
 
+
86655
 
+
86656
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-interpreter.h dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-interpreter.h
86657
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-interpreter.h    1970-01-01 01:00:00.000000000 +0100
86658
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-interpreter.h     2009-07-21 01:47:05.000000000 +0200
86659
 
@@ -0,0 +1,174 @@
86660
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
86661
 
+ */
86662
 
+
86663
 
+#ifndef __SIEVE_INTERPRETER_H
86664
 
+#define __SIEVE_INTERPRETER_H
86665
 
+
86666
 
+#include "lib.h"
86667
 
+#include "array.h"
86668
 
+#include "buffer.h"
86669
 
+#include "mail-storage.h"
86670
 
+
86671
 
+#include "sieve-common.h"
86672
 
+
86673
 
+/*
86674
 
+ * Forward declarations
86675
 
+ */
86676
 
86677
 
+struct sieve_interpreter;
86678
 
+
86679
 
+/*
86680
 
+ * Runtime environment
86681
 
+ */
86682
 
+
86683
 
+struct sieve_runtime_env {
86684
 
+       struct sieve_interpreter *interp;
86685
 
+
86686
 
+       struct sieve_script *script;
86687
 
+       const struct sieve_script_env *scriptenv;
86688
 
+       
86689
 
+       const struct sieve_message_data *msgdata;
86690
 
+       struct sieve_message_context *msgctx;
86691
 
+
86692
 
+       struct sieve_binary *sbin;
86693
 
+       struct sieve_result *result;
86694
 
+       
86695
 
+       struct sieve_exec_status *exec_status;
86696
 
+       struct ostream *trace_stream;
86697
 
+};
86698
 
+
86699
 
+/* 
86700
 
+ * Interpreter 
86701
 
+ */
86702
 
+
86703
 
+struct sieve_interpreter *sieve_interpreter_create
86704
 
+       (struct sieve_binary *sbin, struct sieve_error_handler *ehandler);
86705
 
+void sieve_interpreter_free(struct sieve_interpreter **interp);
86706
 
+
86707
 
+/*
86708
 
+ * Accessors
86709
 
+ */
86710
 
+
86711
 
+pool_t sieve_interpreter_pool
86712
 
+       (struct sieve_interpreter *interp);
86713
 
+struct sieve_script *sieve_interpreter_script
86714
 
+       (struct sieve_interpreter *interp);
86715
 
+struct sieve_error_handler *sieve_interpreter_get_error_handler
86716
 
+       (struct sieve_interpreter *interp);
86717
 
+
86718
 
+/* Do not use this function for normal sieve extensions. This is intended for
86719
 
+ * the testsuite only.
86720
 
+ */
86721
 
+void sieve_interpreter_set_result
86722
 
+       (struct sieve_interpreter *interp, struct sieve_result *result);
86723
 
+
86724
 
+/*
86725
 
+ * Program flow
86726
 
+ */
86727
 
+
86728
 
+void sieve_interpreter_reset
86729
 
+       (struct sieve_interpreter *interp);
86730
 
+void sieve_interpreter_interrupt
86731
 
+       (struct sieve_interpreter *interp);
86732
 
+sieve_size_t sieve_interpreter_program_counter
86733
 
+       (struct sieve_interpreter *interp);
86734
 
+
86735
 
+int sieve_interpreter_program_jump
86736
 
+       (struct sieve_interpreter *interp, bool jump);
86737
 
+       
86738
 
+/*
86739
 
+ * Test results
86740
 
+ */    
86741
 
+       
86742
 
+void sieve_interpreter_set_test_result
86743
 
+       (struct sieve_interpreter *interp, bool result);
86744
 
+bool sieve_interpreter_get_test_result
86745
 
+       (struct sieve_interpreter *interp);
86746
 
+       
86747
 
+/* 
86748
 
+ * Error handling 
86749
 
+ */
86750
 
+
86751
 
+/* This is not particularly user-friendly, so avoid using this.. */
86752
 
+const char *sieve_runtime_location(const struct sieve_runtime_env *runenv);
86753
 
+
86754
 
+void sieve_runtime_error
86755
 
+       (const struct sieve_runtime_env *runenv, const char *location,
86756
 
+               const char *fmt, ...) ATTR_FORMAT(3, 4);
86757
 
+void sieve_runtime_warning
86758
 
+       (const struct sieve_runtime_env *runenv, const char *location,
86759
 
+               const char *fmt, ...) ATTR_FORMAT(3, 4);
86760
 
+void sieve_runtime_log
86761
 
+       (const struct sieve_runtime_env *runenv, const char *location, 
86762
 
+               const char *fmt, ...) ATTR_FORMAT(3, 4);
86763
 
+
86764
 
+/* 
86765
 
+ * Runtime Trace 
86766
 
+ */
86767
 
+
86768
 
+#ifdef SIEVE_RUNTIME_TRACE
86769
 
+               
86770
 
+void _sieve_runtime_trace
86771
 
+       (const struct sieve_runtime_env *runenv, const char *fmt, ...)
86772
 
+               ATTR_FORMAT(2, 3);
86773
 
+void _sieve_runtime_trace_error
86774
 
+       (const struct sieve_runtime_env *runenv, const char *fmt, ...)
86775
 
+               ATTR_FORMAT(2, 3);
86776
 
+               
86777
 
+# define sieve_runtime_trace(runenv, ...) STMT_START { \
86778
 
+               if ( (runenv)->trace_stream != NULL ) \
86779
 
+                       _sieve_runtime_trace((runenv), __VA_ARGS__); \
86780
 
+       } STMT_END
86781
 
+# define sieve_runtime_trace_error(runenv, ...) STMT_START { \
86782
 
+               if ( (runenv)->trace_stream != NULL ) \
86783
 
+                       _sieve_runtime_trace_error((runenv), __VA_ARGS__); \
86784
 
+               } STMT_END      
86785
 
+
86786
 
+#else
86787
 
+# define sieve_runtime_trace(runenv, ...)
86788
 
+# define sieve_runtime_trace_error(runenv, ...)
86789
 
+#endif
86790
 
+
86791
 
+/* 
86792
 
+ * Extension support 
86793
 
+ */
86794
 
+
86795
 
+struct sieve_interpreter_extension {
86796
 
+       const struct sieve_extension *ext;      
86797
 
+
86798
 
+       void (*run)(const struct sieve_runtime_env *renv, void *context);
86799
 
+       void (*free)(struct sieve_interpreter *interp, void *context);
86800
 
+};
86801
 
+
86802
 
+void sieve_interpreter_extension_register
86803
 
+       (struct sieve_interpreter *interp, 
86804
 
+               const struct sieve_interpreter_extension *int_ext, void *context);
86805
 
+void sieve_interpreter_extension_set_context
86806
 
+       (struct sieve_interpreter *interp, const struct sieve_extension *ext, 
86807
 
+               void *context);
86808
 
+void *sieve_interpreter_extension_get_context
86809
 
+       (struct sieve_interpreter *interp, const struct sieve_extension *ext); 
86810
 
+
86811
 
+/* 
86812
 
+ * Opcodes and operands 
86813
 
+ */
86814
 
+       
86815
 
+int sieve_interpreter_handle_optional_operands
86816
 
+       (const struct sieve_runtime_env *renv, sieve_size_t *address,
86817
 
+               struct sieve_side_effects_list **list);
86818
 
+
86819
 
+/* 
86820
 
+ * Code execute 
86821
 
+ */
86822
 
+
86823
 
+int sieve_interpreter_continue
86824
 
+       (struct sieve_interpreter *interp, bool *interrupted);
86825
 
+int sieve_interpreter_start
86826
 
+       (struct sieve_interpreter *interp, const struct sieve_message_data *msgdata,
86827
 
+               const struct sieve_script_env *senv, struct sieve_result *result, 
86828
 
+               bool *interrupted);
86829
 
+int sieve_interpreter_run
86830
 
+       (struct sieve_interpreter *interp, const struct sieve_message_data *msgdata,
86831
 
+               const struct sieve_script_env *senv, struct sieve_result *result);
86832
 
+
86833
 
+#endif /* __SIEVE_INTERPRETER_H */
86834
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-lexer.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-lexer.c
86835
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-lexer.c  1970-01-01 01:00:00.000000000 +0100
86836
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-lexer.c   2009-08-01 19:31:54.000000000 +0200
86837
 
@@ -0,0 +1,805 @@
86838
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file 
86839
 
+ */
86840
 
86841
 
+#include "lib.h"
86842
 
+#include "compat.h"
86843
 
+#include "str.h"
86844
 
+#include "str-sanitize.h"
86845
 
+#include "istream.h"
86846
 
+
86847
 
+#include "sieve-common.h"
86848
 
+#include "sieve-limits.h"
86849
 
+#include "sieve-error.h"
86850
 
+#include "sieve-script.h"
86851
 
+
86852
 
+#include "sieve-lexer.h"
86853
 
+
86854
 
+#include <stdio.h>
86855
 
+#include <sys/types.h>
86856
 
+#include <sys/stat.h>
86857
 
+#include <fcntl.h>
86858
 
+#include <stdlib.h>
86859
 
+#include <unistd.h>
86860
 
+#include <ctype.h>
86861
 
+
86862
 
+/* 
86863
 
+ * Useful macros
86864
 
+ */
86865
 
+
86866
 
+#define DIGIT_VAL(c) ( c - '0' )
86867
 
+
86868
 
+/*
86869
 
+ * Forward declarations
86870
 
+ */
86871
 
86872
 
+inline static void sieve_lexer_error
86873
 
+       (struct sieve_lexer *lexer, const char *fmt, ...) ATTR_FORMAT(2, 3);
86874
 
+inline static void sieve_lexer_warning
86875
 
+       (struct sieve_lexer *lexer, const char *fmt, ...) ATTR_FORMAT(2, 3);
86876
 
+
86877
 
+/*
86878
 
+ * Lexer object
86879
 
+ */
86880
 
+
86881
 
+struct sieve_lexer {
86882
 
+       pool_t pool;
86883
 
+
86884
 
+       struct sieve_script *script;
86885
 
+       struct istream *input;
86886
 
+               
86887
 
+       int current_line;
86888
 
+       
86889
 
+       enum sieve_token_type token_type;
86890
 
+       string_t *token_str_value;
86891
 
+       int token_int_value;
86892
 
+       
86893
 
+       struct sieve_error_handler *ehandler;
86894
 
+       
86895
 
+       /* Currently scanned data */
86896
 
+       const unsigned char *buffer;
86897
 
+       size_t buffer_size;
86898
 
+       size_t buffer_pos;
86899
 
+};
86900
 
+
86901
 
+struct sieve_lexer *sieve_lexer_create
86902
 
+(struct sieve_script *script, struct sieve_error_handler *ehandler) 
86903
 
+{
86904
 
+       pool_t pool;
86905
 
+       struct sieve_lexer *lexer;
86906
 
+       struct istream *stream;
86907
 
+       
86908
 
+       stream = sieve_script_open(script, NULL);
86909
 
+       if ( stream == NULL )
86910
 
+               return NULL;
86911
 
+       
86912
 
+       pool = pool_alloconly_create("sieve_lexer", 1024);      
86913
 
+       lexer = p_new(pool, struct sieve_lexer, 1);
86914
 
+       lexer->pool = pool;
86915
 
+       
86916
 
+       lexer->ehandler = ehandler;
86917
 
+       sieve_error_handler_ref(ehandler);
86918
 
+
86919
 
+       lexer->input = stream;
86920
 
+       i_stream_ref(lexer->input);
86921
 
+       
86922
 
+       lexer->script = script;
86923
 
+       sieve_script_ref(script);
86924
 
+       
86925
 
+       lexer->buffer = NULL;
86926
 
+       lexer->buffer_size = 0;
86927
 
+       lexer->buffer_pos = 0;
86928
 
+       
86929
 
+       lexer->current_line = 1;        
86930
 
+       lexer->token_type = STT_NONE;
86931
 
+       lexer->token_str_value = str_new(pool, 256);
86932
 
+       lexer->token_int_value = 0;
86933
 
+               
86934
 
+       return lexer;
86935
 
+}
86936
 
+
86937
 
+void sieve_lexer_free(struct sieve_lexer **lexer) 
86938
 
+{      
86939
 
+       i_stream_unref(&(*lexer)->input);
86940
 
+
86941
 
+       sieve_script_close((*lexer)->script);
86942
 
+       sieve_script_unref(&(*lexer)->script);
86943
 
+
86944
 
+       sieve_error_handler_unref(&(*lexer)->ehandler);
86945
 
+
86946
 
+       pool_unref(&(*lexer)->pool); 
86947
 
+
86948
 
+       *lexer = NULL;
86949
 
+}
86950
 
+
86951
 
+/*
86952
 
+ * Internal error handling
86953
 
+ */
86954
 
+
86955
 
+inline static void sieve_lexer_error
86956
 
+(struct sieve_lexer *lexer, const char *fmt, ...)
86957
 
+{
86958
 
+       va_list args;
86959
 
+       va_start(args, fmt);
86960
 
+
86961
 
+       T_BEGIN {
86962
 
+               sieve_verror(lexer->ehandler, 
86963
 
+                       sieve_error_script_location(lexer->script, lexer->current_line),
86964
 
+                       fmt, args);
86965
 
+       } T_END;
86966
 
+               
86967
 
+       va_end(args);
86968
 
+}
86969
 
+
86970
 
+inline static void sieve_lexer_warning
86971
 
+(struct sieve_lexer *lexer, const char *fmt, ...)
86972
 
+{
86973
 
+       va_list args;
86974
 
+       va_start(args, fmt);
86975
 
+
86976
 
+       T_BEGIN { 
86977
 
+               sieve_vwarning(lexer->ehandler, 
86978
 
+                       sieve_error_script_location(lexer->script, lexer->current_line),
86979
 
+                       fmt, args);
86980
 
+       } T_END;
86981
 
+               
86982
 
+       va_end(args);
86983
 
+}
86984
 
+
86985
 
+const char *sieve_lexer_token_string(struct sieve_lexer *lexer) 
86986
 
+{
86987
 
+       switch ( lexer->token_type ) {
86988
 
+               case STT_NONE: return "no token (bug)";                 
86989
 
+               case STT_WHITESPACE: return "whitespace (bug)";
86990
 
+               case STT_EOF: return "end of file";
86991
 
+  
86992
 
+               case STT_NUMBER: return "number"; 
86993
 
+               case STT_IDENTIFIER: return "identifier"; 
86994
 
+               case STT_TAG: return "tag";
86995
 
+               case STT_STRING: return "string"; 
86996
 
+  
86997
 
+               case STT_RBRACKET: return "')'"; 
86998
 
+               case STT_LBRACKET: return "'('";
86999
 
+               case STT_RCURLY: return "'}'"; 
87000
 
+               case STT_LCURLY: return "'{'"; 
87001
 
+               case STT_RSQUARE: return "']'"; 
87002
 
+               case STT_LSQUARE: return "'['"; 
87003
 
+               case STT_SEMICOLON: return "';'"; 
87004
 
+               case STT_COMMA: return "','"; 
87005
 
+       
87006
 
+               case STT_SLASH: return "'/'";  
87007
 
+               case STT_COLON: return "':'";   
87008
 
+  
87009
 
+               case STT_GARBAGE: return "unknown characters"; 
87010
 
+               case STT_ERROR: return "error token (bug)";
87011
 
+       }
87012
 
+   
87013
 
+       return "unknown token (bug)";
87014
 
+}
87015
 
+       
87016
 
+/* 
87017
 
+ * Debug 
87018
 
+ */
87019
 
87020
 
+void sieve_lexer_print_token(struct sieve_lexer *lexer) 
87021
 
+{
87022
 
+       switch ( lexer->token_type ) {
87023
 
+               case STT_NONE: printf("??NONE?? "); break;              
87024
 
+               case STT_WHITESPACE: printf("??WHITESPACE?? "); break;
87025
 
+               case STT_EOF: printf("EOF\n"); break;
87026
 
+  
87027
 
+               case STT_NUMBER: printf("NUMBER "); break;
87028
 
+               case STT_IDENTIFIER: printf("IDENTIFIER "); break;
87029
 
+               case STT_TAG: printf("TAG "); break;
87030
 
+               case STT_STRING: printf("STRING "); break;
87031
 
+  
87032
 
+               case STT_RBRACKET: printf(") "); break;
87033
 
+               case STT_LBRACKET: printf("( "); break;
87034
 
+               case STT_RCURLY: printf("}\n"); break;
87035
 
+               case STT_LCURLY: printf("{\n"); break;
87036
 
+               case STT_RSQUARE: printf("] "); break;
87037
 
+               case STT_LSQUARE: printf("[ "); break;
87038
 
+               case STT_SEMICOLON: printf(";\n"); break;
87039
 
+               case STT_COMMA: printf(", "); break;
87040
 
+  
87041
 
+               case STT_SLASH: printf("/ "); break; 
87042
 
+               case STT_COLON: printf(": "); break;  
87043
 
+       
87044
 
+               case STT_GARBAGE: printf(">>GARBAGE<<"); break;
87045
 
+               case STT_ERROR: printf(">>ERROR<<"); break;
87046
 
+       default: 
87047
 
+               printf("UNKNOWN ");
87048
 
+               break;
87049
 
+       }
87050
 
+}
87051
 
+
87052
 
+/*
87053
 
+ * Token access
87054
 
+ */ 
87055
 
+
87056
 
+enum sieve_token_type sieve_lexer_current_token(struct sieve_lexer *lexer) 
87057
 
+{
87058
 
+       return lexer->token_type;
87059
 
+}
87060
 
+
87061
 
+const string_t *sieve_lexer_token_str(struct sieve_lexer *lexer) 
87062
 
+{
87063
 
+       i_assert(       lexer->token_type == STT_STRING );
87064
 
+               
87065
 
+       return lexer->token_str_value;
87066
 
+}
87067
 
+
87068
 
+const char *sieve_lexer_token_ident(struct sieve_lexer *lexer) 
87069
 
+{
87070
 
+       i_assert(
87071
 
+               lexer->token_type == STT_TAG ||
87072
 
+               lexer->token_type == STT_IDENTIFIER);
87073
 
+               
87074
 
+       return str_c(lexer->token_str_value);
87075
 
+}
87076
 
+
87077
 
+int sieve_lexer_token_int(struct sieve_lexer *lexer) 
87078
 
+{
87079
 
+       i_assert(lexer->token_type == STT_NUMBER);
87080
 
+               
87081
 
+       return lexer->token_int_value;
87082
 
+}
87083
 
+
87084
 
+bool sieve_lexer_eof(struct sieve_lexer *lexer) 
87085
 
+{
87086
 
+       return lexer->token_type == STT_EOF;
87087
 
+}
87088
 
+
87089
 
+int sieve_lexer_current_line(struct sieve_lexer *lexer) 
87090
 
+{
87091
 
+       return lexer->current_line;
87092
 
+}
87093
 
+
87094
 
+/*
87095
 
+ * Lexical scanning 
87096
 
+ */
87097
 
+
87098
 
+static void sieve_lexer_shift(struct sieve_lexer *lexer) 
87099
 
+{
87100
 
+       if ( lexer->buffer != NULL && lexer->buffer[lexer->buffer_pos] == '\n' ) 
87101
 
+               lexer->current_line++;  
87102
 
+       
87103
 
+       if ( lexer->buffer != NULL && lexer->buffer_pos + 1 < lexer->buffer_size )
87104
 
+               lexer->buffer_pos++;
87105
 
+       else {
87106
 
+               if ( lexer->buffer != NULL )
87107
 
+                       i_stream_skip(lexer->input, lexer->buffer_size);
87108
 
+               
87109
 
+               lexer->buffer = i_stream_get_data(lexer->input, &lexer->buffer_size);
87110
 
+         
87111
 
+               if ( lexer->buffer == NULL && i_stream_read(lexer->input) > 0 )
87112
 
+                       lexer->buffer = i_stream_get_data(lexer->input, &lexer->buffer_size);
87113
 
+               
87114
 
+               lexer->buffer_pos = 0;
87115
 
+       }
87116
 
+}
87117
 
+
87118
 
+static inline int sieve_lexer_curchar(struct sieve_lexer *lexer) 
87119
 
+{      
87120
 
+       if ( lexer->buffer == NULL )
87121
 
+               return -1;
87122
 
+       
87123
 
+       return lexer->buffer[lexer->buffer_pos];
87124
 
+}
87125
 
+
87126
 
+static inline const char *_char_sanitize(int ch)
87127
 
+{
87128
 
+       if ( ch > 31 && ch < 127 )
87129
 
+               return t_strdup_printf("'%c'", ch);
87130
 
+       
87131
 
+       return t_strdup_printf("0x%02x", ch);
87132
 
+}
87133
 
+
87134
 
+/* sieve_lexer_scan_raw_token:
87135
 
+ *   Scans valid tokens and whitespace 
87136
 
+ */
87137
 
+static bool sieve_lexer_scan_raw_token(struct sieve_lexer *lexer) 
87138
 
+{
87139
 
+       sieve_number_t start_line;
87140
 
+       string_t *str;
87141
 
+
87142
 
+       /* Read first character */
87143
 
+       if ( lexer->token_type == STT_NONE ) {
87144
 
+               i_stream_read(lexer->input);
87145
 
+               sieve_lexer_shift(lexer);
87146
 
+       }
87147
 
+  
87148
 
+       switch ( sieve_lexer_curchar(lexer) ) {
87149
 
+       
87150
 
+       /* whitespace */
87151
 
+       
87152
 
+       // hash-comment = ( "#" *CHAR-NOT-CRLF CRLF )
87153
 
+       case '#': 
87154
 
+               sieve_lexer_shift(lexer);
87155
 
+               while ( sieve_lexer_curchar(lexer) != '\n' ) {
87156
 
+                       switch( sieve_lexer_curchar(lexer) ) {
87157
 
+                       case -1:
87158
 
+                               sieve_lexer_error(lexer, "end of file before end of hash comment");
87159
 
+                               lexer->token_type = STT_ERROR;
87160
 
+                               return FALSE;
87161
 
+                       case '\0':
87162
 
+                               sieve_lexer_error(lexer, "encountered NUL character in hash comment");
87163
 
+                               lexer->token_type = STT_ERROR;
87164
 
+                               return FALSE;                           
87165
 
+                       default:
87166
 
+                               break;
87167
 
+                       }
87168
 
+                                               
87169
 
+                       /* Stray CR is ignored */
87170
 
+                       
87171
 
+                       sieve_lexer_shift(lexer);
87172
 
+               } 
87173
 
+
87174
 
+               sieve_lexer_shift(lexer);
87175
 
+               
87176
 
+               lexer->token_type = STT_WHITESPACE;
87177
 
+               return TRUE;
87178
 
+               
87179
 
+       // bracket-comment = "/*" *(CHAR-NOT-STAR / ("*" CHAR-NOT-SLASH)) "*/"
87180
 
+       //        ;; No */ allowed inside a comment.
87181
 
+       //        ;; (No * is allowed unless it is the last character,
87182
 
+       //        ;; or unless it is followed by a character that isn't a
87183
 
+       //        ;; slash.)
87184
 
+       case '/': 
87185
 
+               start_line = lexer->current_line;
87186
 
+               sieve_lexer_shift(lexer);
87187
 
+               
87188
 
+               if ( sieve_lexer_curchar(lexer) == '*' ) { 
87189
 
+                       sieve_lexer_shift(lexer);
87190
 
+                       
87191
 
+                       while ( TRUE ) {
87192
 
+                               switch ( sieve_lexer_curchar(lexer) ) {
87193
 
+                               case -1:
87194
 
+                                       sieve_lexer_error(lexer, 
87195
 
+                                               "end of file before end of bracket comment ('/* ... */') "
87196
 
+                                               "started at line %d", start_line);
87197
 
+                                       lexer->token_type = STT_ERROR;
87198
 
+                                       return FALSE;
87199
 
+                               case '*':
87200
 
+                                       sieve_lexer_shift(lexer);
87201
 
+                                       
87202
 
+                                       if ( sieve_lexer_curchar(lexer) == '/' ) {
87203
 
+                                               sieve_lexer_shift(lexer);
87204
 
+                                               
87205
 
+                                               lexer->token_type = STT_WHITESPACE;
87206
 
+                                               return TRUE;
87207
 
+                                               
87208
 
+                                       } else if ( sieve_lexer_curchar(lexer) == -1 ) {
87209
 
+                                               sieve_lexer_error(lexer, 
87210
 
+                                                       "end of file before end of bracket comment ('/* ... */') "
87211
 
+                                                       "started at line %d", start_line);
87212
 
+                                               lexer->token_type = STT_ERROR;
87213
 
+                                               return FALSE;
87214
 
+                                       }
87215
 
+                                       break;
87216
 
+                               case '\0':
87217
 
+                                       sieve_lexer_error(lexer, 
87218
 
+                                               "encountered NUL character in bracket comment");
87219
 
+                                       lexer->token_type = STT_ERROR;
87220
 
+                                       return FALSE;                           
87221
 
+                               default:
87222
 
+                                       sieve_lexer_shift(lexer);
87223
 
+                               }
87224
 
+                       }
87225
 
+                       
87226
 
+                       i_unreached();
87227
 
+                       return FALSE;
87228
 
+               }
87229
 
+               
87230
 
+               lexer->token_type = STT_SLASH;
87231
 
+               return TRUE;
87232
 
+               
87233
 
+       // comment = bracket-comment / hash-comment
87234
 
+       // white-space = 1*(SP / CRLF / HTAB) / comment
87235
 
+       case '\t':
87236
 
+       case '\r':
87237
 
+       case '\n':
87238
 
+       case ' ':
87239
 
+               sieve_lexer_shift(lexer);
87240
 
+               
87241
 
+               while ( sieve_lexer_curchar(lexer) == '\t' ||
87242
 
+                       sieve_lexer_curchar(lexer) == '\r' ||
87243
 
+                       sieve_lexer_curchar(lexer) == '\n' ||
87244
 
+                       sieve_lexer_curchar(lexer) == ' ' ) {
87245
 
+                       
87246
 
+                       sieve_lexer_shift(lexer);
87247
 
+               }
87248
 
+               
87249
 
+               lexer->token_type = STT_WHITESPACE;
87250
 
+               return TRUE;
87251
 
+               
87252
 
+       /* quoted-string */
87253
 
+       case '"':
87254
 
+               start_line = lexer->current_line;
87255
 
+               sieve_lexer_shift(lexer);
87256
 
+               str_truncate(lexer->token_str_value, 0);
87257
 
+               str = lexer->token_str_value;
87258
 
+               
87259
 
+               while ( sieve_lexer_curchar(lexer) != '"' ) {
87260
 
+                       if ( sieve_lexer_curchar(lexer) == '\\' ) {
87261
 
+                               sieve_lexer_shift(lexer);
87262
 
+                       }
87263
 
+
87264
 
+                       switch ( sieve_lexer_curchar(lexer) ) {
87265
 
+               
87266
 
+                       /* End of file */                       
87267
 
+                       case -1:
87268
 
+                               sieve_lexer_error(lexer, 
87269
 
+                                       "end of file before end of quoted string "
87270
 
+                                       "started at line %d", start_line);
87271
 
+                               lexer->token_type = STT_ERROR;
87272
 
+                               return FALSE;
87273
 
+
87274
 
+                       /* NUL character */
87275
 
+                       case '\0':
87276
 
+                               sieve_lexer_error(lexer,
87277
 
+                                       "encountered NUL character in quoted string "
87278
 
+                                       "started at line %d", start_line);
87279
 
+                               lexer->token_type = STT_ERROR;
87280
 
+                               return FALSE;
87281
 
+
87282
 
+                       /* CR .. check for LF */
87283
 
+                       case '\r':
87284
 
+                               sieve_lexer_shift(lexer);
87285
 
+
87286
 
+                               if ( sieve_lexer_curchar(lexer) != '\n' ) {
87287
 
+                                       sieve_lexer_error(lexer, 
87288
 
+                                               "found stray carriage-return (CR) character "
87289
 
+                                               "in quoted string started at line %d", start_line);
87290
 
+                                       lexer->token_type = STT_ERROR;
87291
 
+                                       return FALSE;
87292
 
+                               }
87293
 
+
87294
 
+                               if ( str_len(str) <= SIEVE_MAX_STRING_LEN ) 
87295
 
+                                       str_append(str, "\r\n");
87296
 
+                               break;
87297
 
+
87298
 
+                       /* Loose LF is allowed (non-standard) and converted to CRLF */
87299
 
+                       case '\n':
87300
 
+                               if ( str_len(str) <= SIEVE_MAX_STRING_LEN ) 
87301
 
+                                       str_append(str, "\r\n");
87302
 
+                               break;
87303
 
+
87304
 
+                       /* Other characters */
87305
 
+                       default:
87306
 
+                               if ( str_len(str) <= SIEVE_MAX_STRING_LEN ) 
87307
 
+                                       str_append_c(str, sieve_lexer_curchar(lexer));
87308
 
+                       }
87309
 
+
87310
 
+                       sieve_lexer_shift(lexer);                                                       
87311
 
+               }
87312
 
+
87313
 
+               sieve_lexer_shift(lexer);
87314
 
+
87315
 
+               if ( str_len(str) > SIEVE_MAX_STRING_LEN ) {
87316
 
+                       sieve_lexer_error(lexer, 
87317
 
+                               "quoted string started at line %d is too long "
87318
 
+                               "(longer than %llu bytes)", start_line,
87319
 
+                               (long long) SIEVE_MAX_STRING_LEN);
87320
 
+                       lexer->token_type = STT_ERROR;
87321
 
+                       return FALSE;
87322
 
+               }
87323
 
+               
87324
 
+               lexer->token_type = STT_STRING;
87325
 
+               return TRUE;
87326
 
+               
87327
 
+       /* single character tokens */
87328
 
+       case ']':
87329
 
+               sieve_lexer_shift(lexer);
87330
 
+               lexer->token_type = STT_RSQUARE;
87331
 
+               return TRUE;
87332
 
+       case '[':
87333
 
+               sieve_lexer_shift(lexer);
87334
 
+               lexer->token_type = STT_LSQUARE;
87335
 
+               return TRUE;
87336
 
+       case '}':
87337
 
+               sieve_lexer_shift(lexer);
87338
 
+               lexer->token_type = STT_RCURLY;
87339
 
+               return TRUE;
87340
 
+       case '{':
87341
 
+               sieve_lexer_shift(lexer);
87342
 
+               lexer->token_type = STT_LCURLY;
87343
 
+               return TRUE;
87344
 
+       case ')':
87345
 
+               sieve_lexer_shift(lexer);
87346
 
+               lexer->token_type = STT_RBRACKET;
87347
 
+               return TRUE;
87348
 
+       case '(':
87349
 
+               sieve_lexer_shift(lexer);
87350
 
+               lexer->token_type = STT_LBRACKET;       
87351
 
+               return TRUE;
87352
 
+       case ';':
87353
 
+               sieve_lexer_shift(lexer);
87354
 
+               lexer->token_type = STT_SEMICOLON;
87355
 
+               return TRUE;
87356
 
+       case ',':
87357
 
+               sieve_lexer_shift(lexer);
87358
 
+               lexer->token_type = STT_COMMA;
87359
 
+               return TRUE;
87360
 
+               
87361
 
+       /* EOF */       
87362
 
+       case -1: 
87363
 
+         lexer->token_type = STT_EOF;
87364
 
+               return TRUE;
87365
 
+               
87366
 
+       default: 
87367
 
+               /* number */
87368
 
+               if ( i_isdigit(sieve_lexer_curchar(lexer)) ) {
87369
 
+                       sieve_number_t value = DIGIT_VAL(sieve_lexer_curchar(lexer));
87370
 
+                       bool overflow = FALSE;
87371
 
+
87372
 
+                       sieve_lexer_shift(lexer);
87373
 
+               
87374
 
+                       while ( i_isdigit(sieve_lexer_curchar(lexer)) ) {
87375
 
+                               sieve_number_t valnew = 
87376
 
+                                       value * 10 + DIGIT_VAL(sieve_lexer_curchar(lexer));
87377
 
+                       
87378
 
+                               /* Check for integer wrap */
87379
 
+                               if ( valnew < value )
87380
 
+                                       overflow = TRUE;
87381
 
+
87382
 
+                               value = valnew;
87383
 
+                               sieve_lexer_shift(lexer);
87384
 
+                       }
87385
 
+               
87386
 
+                       switch ( sieve_lexer_curchar(lexer) ) { 
87387
 
+                       case 'k':
87388
 
+                       case 'K': /* Kilo */
87389
 
+                               if ( value > (SIEVE_MAX_NUMBER >> 10) )
87390
 
+                                       overflow = TRUE;
87391
 
+                               else
87392
 
+                                       value = value << 10;
87393
 
+                               sieve_lexer_shift(lexer);
87394
 
+                               break;
87395
 
+                       case 'm': 
87396
 
+                       case 'M': /* Mega */
87397
 
+                               if ( value > (SIEVE_MAX_NUMBER >> 20) )
87398
 
+                                       overflow = TRUE;
87399
 
+                               else
87400
 
+                                       value = value << 20;
87401
 
+                               sieve_lexer_shift(lexer);
87402
 
+                               break;
87403
 
+                       case 'g':
87404
 
+                       case 'G': /* Giga */
87405
 
+                               if ( value > (SIEVE_MAX_NUMBER >> 30) )
87406
 
+                                       overflow = TRUE;
87407
 
+                               else
87408
 
+                                       value = value << 30;
87409
 
+                               sieve_lexer_shift(lexer);
87410
 
+                               break;
87411
 
+                       default:
87412
 
+                               /* Next token */
87413
 
+                               break;
87414
 
+                       }
87415
 
+
87416
 
+                       /* Check for integer wrap */
87417
 
+                       if ( overflow ) {
87418
 
+                               sieve_lexer_error(lexer,
87419
 
+                                       "number exceeds integer limits (max %llu)",
87420
 
+                                       (long long) SIEVE_MAX_NUMBER);
87421
 
+                               lexer->token_type = STT_ERROR;
87422
 
+                               return FALSE;
87423
 
+                       }
87424
 
+       
87425
 
+                       lexer->token_type = STT_NUMBER;
87426
 
+                       lexer->token_int_value = value;
87427
 
+                       return TRUE;    
87428
 
+               
87429
 
+               /* identifier / tag */  
87430
 
+               } else if ( i_isalpha(sieve_lexer_curchar(lexer)) ||
87431
 
+                       sieve_lexer_curchar(lexer) == '_' || 
87432
 
+                       sieve_lexer_curchar(lexer) == ':' ) {
87433
 
+               
87434
 
+                       enum sieve_token_type type = STT_IDENTIFIER;
87435
 
+                       str_truncate(lexer->token_str_value,0);
87436
 
+                       str = lexer->token_str_value;
87437
 
+               
87438
 
+                       /* If it starts with a ':' it is a tag and not an identifier */
87439
 
+                       if ( sieve_lexer_curchar(lexer) == ':' ) {
87440
 
+                               sieve_lexer_shift(lexer); // discard colon
87441
 
+                               type = STT_TAG;
87442
 
+                       
87443
 
+                               /* First character still can't be a DIGIT */
87444
 
+                               if ( i_isalpha(sieve_lexer_curchar(lexer)) ||
87445
 
+                                       sieve_lexer_curchar(lexer) == '_' ) { 
87446
 
+                                       str_append_c(str, sieve_lexer_curchar(lexer));
87447
 
+                                       sieve_lexer_shift(lexer);
87448
 
+                               } else {
87449
 
+                                       /* Hmm, otherwise it is just a spurious colon */
87450
 
+                                       lexer->token_type = STT_COLON;
87451
 
+                                       return TRUE;
87452
 
+                               }
87453
 
+                       } else {
87454
 
+                               str_append_c(str, sieve_lexer_curchar(lexer));
87455
 
+                               sieve_lexer_shift(lexer);
87456
 
+                       }
87457
 
+               
87458
 
+                       /* Scan the rest of the identifier */
87459
 
+                       while ( i_isalnum(sieve_lexer_curchar(lexer)) ||
87460
 
+                               sieve_lexer_curchar(lexer) == '_' ) {
87461
 
+
87462
 
+                               if ( str_len(str) <= SIEVE_MAX_IDENTIFIER_LEN ) {
87463
 
+                                       str_append_c(str, sieve_lexer_curchar(lexer));
87464
 
+                               }
87465
 
+                               sieve_lexer_shift(lexer);
87466
 
+                       }
87467
 
+
87468
 
+                       /* Is this in fact a multiline text string ? */
87469
 
+                       if ( sieve_lexer_curchar(lexer) == ':' &&
87470
 
+                               type == STT_IDENTIFIER && str_len(str) == 4 &&
87471
 
+                               strncasecmp(str_c(str), "text", 4) == 0 ) {
87472
 
+                               sieve_lexer_shift(lexer); // discard colon
87473
 
+
87474
 
+                               start_line = lexer->current_line;
87475
 
+                       
87476
 
+                               /* Discard SP and HTAB whitespace */
87477
 
+                               while ( sieve_lexer_curchar(lexer) == ' ' || 
87478
 
+                                       sieve_lexer_curchar(lexer) == '\t' )
87479
 
+                                       sieve_lexer_shift(lexer);
87480
 
+                               
87481
 
+                               /* Discard hash comment or handle single CRLF */
87482
 
+                               switch ( sieve_lexer_curchar(lexer) ) {
87483
 
+                               case '#':
87484
 
+                                       while ( sieve_lexer_curchar(lexer) != '\n' )
87485
 
+                                               sieve_lexer_shift(lexer);
87486
 
+                                       break;
87487
 
+                               case '\r':
87488
 
+                                       sieve_lexer_shift(lexer);
87489
 
+                                       break;
87490
 
+                               }
87491
 
+                       
87492
 
+                               /* Terminating LF required */
87493
 
+                               switch ( sieve_lexer_curchar(lexer) ) {
87494
 
+                               case '\n':
87495
 
+                                       sieve_lexer_shift(lexer);
87496
 
+                                       break;
87497
 
+                               case -1:
87498
 
+                                       sieve_lexer_error(lexer, 
87499
 
+                                               "end of file before end of multi-line string");
87500
 
+                                       lexer->token_type = STT_ERROR;
87501
 
+                                       return FALSE;
87502
 
+                               default: 
87503
 
+                                       sieve_lexer_error(lexer, 
87504
 
+                                               "invalid character %s after 'text:' in multiline string",
87505
 
+                                               _char_sanitize(sieve_lexer_curchar(lexer)));
87506
 
+                                       lexer->token_type = STT_ERROR;
87507
 
+                                       return FALSE;
87508
 
+                               }
87509
 
+                       
87510
 
+                               /* Start over */
87511
 
+                               str_truncate(str, 0); 
87512
 
+                       
87513
 
+                               /* Parse literal lines */
87514
 
+                               while ( TRUE ) {
87515
 
+                                       bool cr_shifted = FALSE;
87516
 
+
87517
 
+                                       /* Remove dot-stuffing or detect end of text */
87518
 
+                                       if ( sieve_lexer_curchar(lexer) == '.' ) {
87519
 
+                                               sieve_lexer_shift(lexer);
87520
 
+                                       
87521
 
+                                               /* Check for CR.. */
87522
 
+                                               if ( sieve_lexer_curchar(lexer) == '\r' ) {
87523
 
+                                                       sieve_lexer_shift(lexer);
87524
 
+                                                       cr_shifted = TRUE;
87525
 
+                                               }
87526
 
+                               
87527
 
+                                               /* ..LF */
87528
 
+                                               if ( sieve_lexer_curchar(lexer) == '\n' ) {
87529
 
+                                                       sieve_lexer_shift(lexer);
87530
 
+
87531
 
+                                                       /* End of multi-line string */
87532
 
+
87533
 
+                                                       /* Check whether length limit was violated */
87534
 
+                                                       if ( str_len(str) > SIEVE_MAX_STRING_LEN ) {
87535
 
+                                                               sieve_lexer_error(lexer, 
87536
 
+                                                                       "multi-line string started at line %d is too long "
87537
 
+                                                                       "(longer than %llu bytes)", start_line,
87538
 
+                                                                       (long long) SIEVE_MAX_STRING_LEN);
87539
 
+                                                                       lexer->token_type = STT_ERROR;
87540
 
+                                                                       return FALSE;
87541
 
+                                                       }
87542
 
+
87543
 
+                                                       lexer->token_type = STT_STRING;
87544
 
+                                                       return TRUE;
87545
 
+                                               } else if ( cr_shifted ) {
87546
 
+                                                       /* Seen CR, but no LF */
87547
 
+                                                       sieve_lexer_error(lexer, 
87548
 
+                                                               "found stray carriage-return (CR) character "
87549
 
+                                                               "in multi-line string started at line %d", start_line);
87550
 
+                                                       lexer->token_type = STT_ERROR;
87551
 
+                                                       return FALSE;
87552
 
+                                               }
87553
 
+
87554
 
+                                               /* Handle dot-stuffing */
87555
 
+                                               if ( str_len(str) <= SIEVE_MAX_STRING_LEN ) 
87556
 
+                                                       str_append_c(str, '.');
87557
 
+                                               if ( sieve_lexer_curchar(lexer) == '.' )
87558
 
+                                                       sieve_lexer_shift(lexer);
87559
 
+                                       }
87560
 
+                               
87561
 
+                                       /* Scan the rest of the line */
87562
 
+                                       while ( sieve_lexer_curchar(lexer) != '\n' &&
87563
 
+                                               sieve_lexer_curchar(lexer) != '\r' ) {
87564
 
+
87565
 
+                                               switch ( sieve_lexer_curchar(lexer) ) {
87566
 
+                                               case -1:
87567
 
+                                                       sieve_lexer_error(lexer, 
87568
 
+                                                               "end of file before end of multi-line string");
87569
 
+                                                       lexer->token_type = STT_ERROR;
87570
 
+                                                       return FALSE;
87571
 
+                                               case '\0':
87572
 
+                                                       sieve_lexer_error(lexer,
87573
 
+                                                               "encountered NUL character in quoted string "
87574
 
+                                                               "started at line %d", start_line);
87575
 
+                                                       lexer->token_type = STT_ERROR;
87576
 
+                                                       return FALSE;
87577
 
+                                               default:
87578
 
+                                                       if ( str_len(str) <= SIEVE_MAX_STRING_LEN ) 
87579
 
+                                                               str_append_c(str, sieve_lexer_curchar(lexer));
87580
 
+                                               }
87581
 
+
87582
 
+                                               sieve_lexer_shift(lexer);
87583
 
+                                       }
87584
 
+
87585
 
+                                       /* If exited loop due to CR, skip it */
87586
 
+                                       if ( sieve_lexer_curchar(lexer) == '\r' ) {
87587
 
+                                               sieve_lexer_shift(lexer);
87588
 
+                                       }
87589
 
+
87590
 
+                                       /* Now we must see an LF */
87591
 
+                                       if ( sieve_lexer_curchar(lexer) != '\n' ) {                                     
87592
 
+                                               sieve_lexer_error(lexer, 
87593
 
+                                                       "found stray carriage-return (CR) character "
87594
 
+                                                       "in multi-line string started at line %d", start_line);
87595
 
+                                               lexer->token_type = STT_ERROR;
87596
 
+                                               return FALSE;
87597
 
+                                       }
87598
 
+                                               
87599
 
+                                       if ( str_len(str) <= SIEVE_MAX_STRING_LEN ) 
87600
 
+                                               str_append(str, "\r\n");
87601
 
+
87602
 
+                                       sieve_lexer_shift(lexer);
87603
 
+                               }
87604
 
+                       
87605
 
+                               i_unreached();
87606
 
+                               lexer->token_type = STT_ERROR;
87607
 
+                               return FALSE;
87608
 
+                       }
87609
 
+
87610
 
+                       if ( str_len(str) > SIEVE_MAX_IDENTIFIER_LEN ) {
87611
 
+                               sieve_lexer_error(lexer, 
87612
 
+                                       "encountered impossibly long %s%s'",
87613
 
+                                       (type == STT_TAG ? "tag identifier ':" : "identifier '"), 
87614
 
+                                       str_sanitize(str_c(str), SIEVE_MAX_IDENTIFIER_LEN));
87615
 
+                               lexer->token_type = STT_ERROR;
87616
 
+                               return FALSE;
87617
 
+                       }
87618
 
+                       
87619
 
+                       lexer->token_type = type;
87620
 
+                       return TRUE;
87621
 
+               }
87622
 
+       
87623
 
+               /* Error (unknown character and EOF handled already) */
87624
 
+               if ( lexer->token_type != STT_GARBAGE ) 
87625
 
+                       sieve_lexer_error(lexer, "unexpected character(s) starting with %s", 
87626
 
+                               _char_sanitize(sieve_lexer_curchar(lexer)));
87627
 
+               sieve_lexer_shift(lexer);
87628
 
+               lexer->token_type = STT_GARBAGE;
87629
 
+               return FALSE;
87630
 
+       }
87631
 
+}
87632
 
+
87633
 
+bool sieve_lexer_skip_token(struct sieve_lexer *lexer) 
87634
 
+{
87635
 
+       /* Scan token while skipping whitespace */
87636
 
+       do { 
87637
 
+               if ( !sieve_lexer_scan_raw_token(lexer) ) return FALSE;
87638
 
+       } while ( lexer->token_type == STT_WHITESPACE );
87639
 
+       
87640
 
+       return TRUE;
87641
 
+}
87642
 
+
87643
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-lexer.h dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-lexer.h
87644
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-lexer.h  1970-01-01 01:00:00.000000000 +0100
87645
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-lexer.h   2009-01-06 00:15:52.000000000 +0100
87646
 
@@ -0,0 +1,62 @@
87647
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file 
87648
 
+ */
87649
 
+
87650
 
+#ifndef __SIEVE_LEXER_H
87651
 
+#define __SIEVE_LEXER_H
87652
 
+
87653
 
+#include "sieve-common.h"
87654
 
+
87655
 
+enum sieve_token_type {
87656
 
+       STT_NONE,
87657
 
+       STT_WHITESPACE,
87658
 
+       STT_EOF,
87659
 
+  
87660
 
+       STT_NUMBER,
87661
 
+       STT_IDENTIFIER,
87662
 
+       STT_TAG,
87663
 
+       STT_STRING,
87664
 
+  
87665
 
+       STT_RBRACKET,
87666
 
+       STT_LBRACKET,
87667
 
+       STT_RCURLY,
87668
 
+       STT_LCURLY,
87669
 
+       STT_RSQUARE,
87670
 
+       STT_LSQUARE,
87671
 
+       STT_SEMICOLON,
87672
 
+       STT_COMMA,
87673
 
+  
87674
 
+       /* These are currently not used in the lexical specification, but a token
87675
 
+        * is assigned to these to generate proper error messages (these are
87676
 
+        * technically not garbage and possibly part of mistyped but otherwise
87677
 
+        * valid tokens).
87678
 
+        */
87679
 
+       STT_SLASH, 
87680
 
+       STT_COLON, 
87681
 
+  
87682
 
+       /* Error tokens */
87683
 
+       STT_GARBAGE, /* Error reporting deferred to parser */ 
87684
 
+       STT_ERROR    /* Lexer is responsible for error, parser won't report additional 
87685
 
+                       errors */
87686
 
+};
87687
 
+
87688
 
+struct sieve_lexer;
87689
 
+
87690
 
+/* Lexer object */
87691
 
+struct sieve_lexer *sieve_lexer_create
87692
 
+       (struct sieve_script *script, struct sieve_error_handler *ehandler);
87693
 
+void sieve_lexer_free(struct sieve_lexer **lexer);
87694
 
+
87695
 
+/* Scanning */
87696
 
+bool sieve_lexer_skip_token(struct sieve_lexer *lexer);
87697
 
+const char *sieve_lexer_token_string(struct sieve_lexer *lexer);
87698
 
+void sieve_lexer_print_token(struct sieve_lexer *lexer);
87699
 
+
87700
 
+/* Token access */
87701
 
+enum sieve_token_type sieve_lexer_current_token(struct sieve_lexer *lexer);
87702
 
+const string_t *sieve_lexer_token_str(struct sieve_lexer *lexer);
87703
 
+const char *sieve_lexer_token_ident(struct sieve_lexer *lexer);
87704
 
+int sieve_lexer_token_int(struct sieve_lexer *lexer);
87705
 
+int sieve_lexer_current_line(struct sieve_lexer *lexer);
87706
 
+bool sieve_lexer_eof(struct sieve_lexer *lexer);
87707
 
+
87708
 
+#endif /* __SIEVE_LEXER_H */
87709
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-limits.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-limits.c
87710
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-limits.c 1970-01-01 01:00:00.000000000 +0100
87711
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-limits.c  2009-01-06 00:15:52.000000000 +0100
87712
 
@@ -0,0 +1,9 @@
87713
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
87714
 
+ */
87715
 
+
87716
 
+#include "sieve-common.h"
87717
 
+#include "sieve-limits.h"
87718
 
+
87719
 
+unsigned int sieve_max_actions = SIEVE_DEFAULT_MAX_ACTIONS;
87720
 
+unsigned int sieve_max_redirects = SIEVE_DEFAULT_MAX_REDIRECTS;
87721
 
+
87722
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-limits.h dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-limits.h
87723
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-limits.h 1970-01-01 01:00:00.000000000 +0100
87724
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-limits.h  2009-01-06 00:15:52.000000000 +0100
87725
 
@@ -0,0 +1,38 @@
87726
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
87727
 
+ */
87728
 
+
87729
 
+#ifndef __SIEVE_LIMITS_H
87730
 
+#define __SIEVE_LIMITS_H
87731
 
+
87732
 
+/*
87733
 
+ * Lexer
87734
 
+ */
87735
 
+
87736
 
+#define SIEVE_MAX_STRING_LEN        (1 << 20)
87737
 
+#define SIEVE_MAX_IDENTIFIER_LEN    32
87738
 
+
87739
 
+/*
87740
 
+ * AST
87741
 
+ */
87742
 
+
87743
 
+#define SIEVE_MAX_COMMAND_ARGUMENTS 32
87744
 
+#define SIEVE_MAX_BLOCK_NESTING     32
87745
 
+#define SIEVE_MAX_TEST_NESTING      32
87746
 
+
87747
 
+/*
87748
 
+ * Runtime
87749
 
+ */
87750
 
+
87751
 
+#define SIEVE_MAX_MATCH_VALUES      32
87752
 
+
87753
 
+/*
87754
 
+ * Actions
87755
 
+ */
87756
 
+
87757
 
+#define SIEVE_DEFAULT_MAX_ACTIONS   32
87758
 
+#define SIEVE_DEFAULT_MAX_REDIRECTS 4
87759
 
+
87760
 
+extern unsigned int sieve_max_actions;
87761
 
+extern unsigned int sieve_max_redirects;
87762
 
+
87763
 
+#endif /* __SIEVE_LIMITS_H */
87764
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-match.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-match.c
87765
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-match.c  1970-01-01 01:00:00.000000000 +0100
87766
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-match.c   2009-08-02 15:32:07.000000000 +0200
87767
 
@@ -0,0 +1,205 @@
87768
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
87769
 
+ */
87770
 
+
87771
 
+#include "lib.h"
87772
 
+#include "mempool.h"
87773
 
+#include "hash.h"
87774
 
+#include "array.h"
87775
 
+
87776
 
+#include "sieve-extensions.h"
87777
 
+#include "sieve-commands.h"
87778
 
+#include "sieve-code.h"
87779
 
+#include "sieve-binary.h"
87780
 
+#include "sieve-validator.h"
87781
 
+#include "sieve-generator.h"
87782
 
+#include "sieve-interpreter.h"
87783
 
+#include "sieve-dump.h"
87784
 
+#include "sieve-comparators.h"
87785
 
+#include "sieve-match-types.h"
87786
 
+
87787
 
+#include "sieve-match.h"
87788
 
+
87789
 
+/*
87790
 
+ * Matching implementation
87791
 
+ */
87792
 
+
87793
 
+struct sieve_match_context *sieve_match_begin
87794
 
+(struct sieve_interpreter *interp, const struct sieve_match_type *mtch, 
87795
 
+       const struct sieve_comparator *cmp, 
87796
 
+       const struct sieve_match_key_extractor *kextract,
87797
 
+       struct sieve_coded_stringlist *key_list)
87798
 
+{
87799
 
+       struct sieve_match_context *mctx;
87800
 
+       pool_t pool;
87801
 
+
87802
 
+       pool = pool_alloconly_create("sieve_match_context", 1024);
87803
 
+       mctx = p_new(pool, struct sieve_match_context, 1);  
87804
 
+
87805
 
+       mctx->pool = pool;
87806
 
+       mctx->interp = interp;
87807
 
+       mctx->match_type = mtch;
87808
 
+       mctx->comparator = cmp;
87809
 
+       mctx->kextract = kextract;
87810
 
+       mctx->key_list = key_list;
87811
 
+
87812
 
+       if ( mtch->match_init != NULL ) {
87813
 
+               mtch->match_init(mctx);
87814
 
+       }
87815
 
+
87816
 
+       return mctx;
87817
 
+}
87818
 
+
87819
 
+int sieve_match_value
87820
 
+       (struct sieve_match_context *mctx, const char *value, size_t val_size)
87821
 
+{
87822
 
+       const struct sieve_match_type *mtch = mctx->match_type;
87823
 
+       sieve_coded_stringlist_reset(mctx->key_list);
87824
 
+       bool ok = TRUE;
87825
 
+
87826
 
+       /* Reject unimplemented match-type */
87827
 
+       if ( mtch->match == NULL )
87828
 
+               return FALSE;
87829
 
+                               
87830
 
+       /* Match to all key values */
87831
 
+       if ( mtch->is_iterative ) {
87832
 
+               unsigned int key_index = 0;
87833
 
+               string_t *key_item = NULL;
87834
 
+               int ret = 0;
87835
 
+       
87836
 
+               while ( (ok=sieve_coded_stringlist_next_item(mctx->key_list, &key_item)) 
87837
 
+                       && key_item != NULL ) 
87838
 
+               {                               
87839
 
+                       T_BEGIN {
87840
 
+                               if ( mctx->kextract != NULL && mtch->allow_key_extract ) {
87841
 
+                                       const struct sieve_match_key_extractor *kext = mctx->kextract;
87842
 
+                                       void *kctx;
87843
 
+                               
87844
 
+                                       if ( (ret=kext->init(&kctx, key_item)) > 0 ) {
87845
 
+                                               const char *key;
87846
 
+                                               size_t key_size;
87847
 
+                                                               
87848
 
+                                               while ( (ret=kext->extract_key(kctx, &key, &key_size)) > 0 ) {                          
87849
 
+                                                       ret = mtch->match
87850
 
+                                                               (mctx, value, val_size, key, key_size, key_index);
87851
 
+                                               
87852
 
+                                                       if ( ret != 0 ) break;
87853
 
+                                               }
87854
 
+                                       }  
87855
 
+                               } else {
87856
 
+                                       ret = mtch->match(mctx, value, val_size, str_c(key_item), 
87857
 
+                                                       str_len(key_item), key_index);
87858
 
+                               }
87859
 
+                       } T_END;
87860
 
+                       
87861
 
+                       if ( ret != 0 )
87862
 
+                               break;
87863
 
+       
87864
 
+                       key_index++;
87865
 
+               }
87866
 
+
87867
 
+               if ( !ok ) 
87868
 
+                       return -1;
87869
 
+
87870
 
+               if ( ret < 0 ) 
87871
 
+                       return ret;
87872
 
+               if ( ret > 0 )
87873
 
+                       return TRUE;
87874
 
+
87875
 
+       } else {
87876
 
+               bool result;
87877
 
+
87878
 
+               T_BEGIN {
87879
 
+                       result = mtch->match(mctx, value, val_size, NULL, 0, -1);
87880
 
+               } T_END;
87881
 
+
87882
 
+               return result;
87883
 
+       }
87884
 
+
87885
 
+       return FALSE;
87886
 
+}
87887
 
+
87888
 
+int sieve_match_end(struct sieve_match_context **mctx)
87889
 
+{
87890
 
+       const struct sieve_match_type *mtch = (*mctx)->match_type;
87891
 
+       int ret = FALSE;
87892
 
+
87893
 
+       if ( mtch->match_deinit != NULL ) {
87894
 
+               ret = mtch->match_deinit(*mctx);
87895
 
+       }
87896
 
+
87897
 
+    pool_unref(&(*mctx)->pool);
87898
 
+    *mctx = NULL;
87899
 
+
87900
 
+       return ret;
87901
 
+}
87902
 
+
87903
 
+/*
87904
 
+ * Reading match operands
87905
 
+ */
87906
 
87907
 
+bool sieve_match_dump_optional_operands
87908
 
+(const struct sieve_dumptime_env *denv, sieve_size_t *address, int *opt_code)
87909
 
+{
87910
 
+       if ( *opt_code != SIEVE_MATCH_OPT_END || 
87911
 
+               sieve_operand_optional_present(denv->sbin, address) ) {
87912
 
+               do {
87913
 
+                       if ( !sieve_operand_optional_read(denv->sbin, address, opt_code) ) 
87914
 
+                               return FALSE;
87915
 
+
87916
 
+                       switch ( *opt_code ) {
87917
 
+                       case SIEVE_MATCH_OPT_END:
87918
 
+                               break;
87919
 
+                       case SIEVE_MATCH_OPT_COMPARATOR:
87920
 
+                               if ( !sieve_opr_comparator_dump(denv, address) )
87921
 
+                                       return FALSE;
87922
 
+                               break;
87923
 
+                       case SIEVE_MATCH_OPT_MATCH_TYPE:
87924
 
+                               if ( !sieve_opr_match_type_dump(denv, address) )
87925
 
+                                       return FALSE;
87926
 
+                               break;
87927
 
+                       default: 
87928
 
+                               return TRUE;
87929
 
+                       }
87930
 
+               } while ( *opt_code != SIEVE_MATCH_OPT_END );
87931
 
+       }
87932
 
+       
87933
 
+       return TRUE;
87934
 
+}
87935
 
+
87936
 
+int sieve_match_read_optional_operands
87937
 
+(const struct sieve_runtime_env *renv, sieve_size_t *address, int *opt_code,
87938
 
+       const struct sieve_comparator **cmp_r, const struct sieve_match_type **mtch_r)
87939
 
+{       
87940
 
+       /* Handle any optional arguments */
87941
 
+       if ( *opt_code != SIEVE_MATCH_OPT_END || 
87942
 
+               sieve_operand_optional_present(renv->sbin, address) ) {
87943
 
+               do {
87944
 
+                       if ( !sieve_operand_optional_read(renv->sbin, address, opt_code) ) {
87945
 
+                               sieve_runtime_trace_error(renv, "invalid optional operand");
87946
 
+                               return SIEVE_EXEC_BIN_CORRUPT;
87947
 
+                       }
87948
 
+
87949
 
+                       switch ( *opt_code ) {
87950
 
+                       case SIEVE_MATCH_OPT_END: 
87951
 
+                               break;
87952
 
+                       case SIEVE_MATCH_OPT_COMPARATOR:
87953
 
+                               if ( (*cmp_r = sieve_opr_comparator_read(renv, address)) == NULL ) {
87954
 
+                                       sieve_runtime_trace_error(renv, "invalid comparator operand");
87955
 
+                                       return SIEVE_EXEC_BIN_CORRUPT;
87956
 
+                               }
87957
 
+                               break;
87958
 
+                       case SIEVE_MATCH_OPT_MATCH_TYPE:
87959
 
+                               if ( (*mtch_r = sieve_opr_match_type_read(renv, address)) == NULL ) {
87960
 
+                                       sieve_runtime_trace_error(renv, "invalid match type operand");
87961
 
+                                       return SIEVE_EXEC_BIN_CORRUPT;
87962
 
+                               }
87963
 
+                               break;
87964
 
+                       default:
87965
 
+                               return SIEVE_EXEC_OK;
87966
 
+                       }
87967
 
+               } while ( *opt_code != SIEVE_MATCH_OPT_END );
87968
 
+       }
87969
 
+       
87970
 
+       return SIEVE_EXEC_OK;
87971
 
+}
87972
 
+
87973
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-match.h dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-match.h
87974
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-match.h  1970-01-01 01:00:00.000000000 +0100
87975
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-match.h   2009-07-30 00:34:54.000000000 +0200
87976
 
@@ -0,0 +1,64 @@
87977
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
87978
 
+ */
87979
 
87980
 
+#ifndef __SIEVE_MATCH_H
87981
 
+#define __SIEVE_MATCH_H
87982
 
+
87983
 
+#include "sieve-common.h"
87984
 
+
87985
 
+/*
87986
 
+ * Matching context
87987
 
+ */
87988
 
87989
 
+struct sieve_match_key_extractor {
87990
 
+       int (*init)(void **context, string_t *raw_key);
87991
 
+       int (*extract_key)(void *context, const char **key, size_t *size);
87992
 
+};
87993
 
+
87994
 
+struct sieve_match_context {
87995
 
+       pool_t pool;
87996
 
+
87997
 
+       struct sieve_interpreter *interp;
87998
 
+       const struct sieve_match_type *match_type;
87999
 
+       const struct sieve_comparator *comparator;
88000
 
+       const struct sieve_match_key_extractor *kextract;
88001
 
+
88002
 
+       struct sieve_coded_stringlist *key_list;
88003
 
+
88004
 
+
88005
 
+       void *data;
88006
 
+};
88007
 
+
88008
 
+/*
88009
 
+ * Matching implementation
88010
 
+ */
88011
 
+
88012
 
+struct sieve_match_context *sieve_match_begin
88013
 
+       (struct sieve_interpreter *interp, const struct sieve_match_type *mtch, 
88014
 
+               const struct sieve_comparator *cmp, 
88015
 
+               const struct sieve_match_key_extractor *kextract,
88016
 
+               struct sieve_coded_stringlist *key_list);
88017
 
+int sieve_match_value
88018
 
+       (struct sieve_match_context *mctx, const char *value, size_t val_size);
88019
 
+int sieve_match_end(struct sieve_match_context **mctx);
88020
 
+
88021
 
+/*
88022
 
+ * Read matching operands
88023
 
+ */
88024
 
88025
 
+enum sieve_match_opt_operand {
88026
 
+       SIEVE_MATCH_OPT_END,
88027
 
+       SIEVE_MATCH_OPT_COMPARATOR,
88028
 
+       SIEVE_MATCH_OPT_MATCH_TYPE,
88029
 
+       SIEVE_MATCH_OPT_LAST
88030
 
+};
88031
 
+
88032
 
+bool sieve_match_dump_optional_operands
88033
 
+       (const struct sieve_dumptime_env *denv, sieve_size_t *addres, int *opt_code);
88034
 
+
88035
 
+int sieve_match_read_optional_operands
88036
 
+       (const struct sieve_runtime_env *renv, sieve_size_t *address, int *opt_code,
88037
 
+               const struct sieve_comparator **cmp_r, 
88038
 
+               const struct sieve_match_type **mtch_r);
88039
 
+
88040
 
+#endif /* __SIEVE_MATCH_H */
88041
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-match-types.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-match-types.c
88042
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-match-types.c    1970-01-01 01:00:00.000000000 +0100
88043
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-match-types.c     2009-02-24 13:40:32.000000000 +0100
88044
 
@@ -0,0 +1,514 @@
88045
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
88046
 
+ */
88047
 
88048
 
+#include <stdio.h>
88049
 
+
88050
 
+#include "lib.h"
88051
 
+#include "compat.h"
88052
 
+#include "mempool.h"
88053
 
+#include "hash.h"
88054
 
+#include "array.h"
88055
 
+
88056
 
+#include "sieve-common.h"
88057
 
+#include "sieve-limits.h"
88058
 
+#include "sieve-extensions.h"
88059
 
+#include "sieve-commands.h"
88060
 
+#include "sieve-code.h"
88061
 
+#include "sieve-binary.h"
88062
 
+#include "sieve-comparators.h"
88063
 
+#include "sieve-validator.h"
88064
 
+#include "sieve-generator.h"
88065
 
+#include "sieve-interpreter.h"
88066
 
+#include "sieve-dump.h"
88067
 
+
88068
 
+#include "sieve-match-types.h"
88069
 
+
88070
 
+#include <string.h>
88071
 
+
88072
 
+/*
88073
 
+ * Types
88074
 
+ */
88075
 
88076
 
+struct sieve_match_values {
88077
 
+       pool_t pool;
88078
 
+       ARRAY_DEFINE(values, string_t *);
88079
 
+       unsigned count;
88080
 
+};
88081
 
+
88082
 
+/* 
88083
 
+ * Default match types
88084
 
+ */ 
88085
 
+
88086
 
+const struct sieve_match_type *sieve_core_match_types[] = {
88087
 
+       &is_match_type, &contains_match_type, &matches_match_type
88088
 
+};
88089
 
+
88090
 
+const unsigned int sieve_core_match_types_count = 
88091
 
+       N_ELEMENTS(sieve_core_match_types);
88092
 
+
88093
 
+/* 
88094
 
+ * Match-type 'extension' 
88095
 
+ */
88096
 
+
88097
 
+static bool mtch_validator_load(struct sieve_validator *validator);
88098
 
+
88099
 
+static int ext_my_id = -1;
88100
 
+
88101
 
+const struct sieve_extension match_type_extension = {
88102
 
+       "@match-types",
88103
 
+       &ext_my_id,
88104
 
+       NULL, NULL,
88105
 
+       mtch_validator_load,
88106
 
+       NULL, NULL, NULL, NULL, NULL,
88107
 
+       SIEVE_EXT_DEFINE_NO_OPERATIONS,
88108
 
+       SIEVE_EXT_DEFINE_NO_OPERANDS
88109
 
+};
88110
 
+
88111
 
+static const struct sieve_extension *ext_this = &match_type_extension;
88112
 
+       
88113
 
+/* 
88114
 
+ * Validator context:
88115
 
+ *   name-based match-type registry. 
88116
 
+ */
88117
 
88118
 
+void sieve_match_type_register
88119
 
+(struct sieve_validator *validator, const struct sieve_match_type *mtch) 
88120
 
+{
88121
 
+       struct sieve_validator_object_registry *regs = 
88122
 
+               sieve_validator_object_registry_get(validator, ext_this);
88123
 
+       
88124
 
+       sieve_validator_object_registry_add(regs, &mtch->object);
88125
 
+}
88126
 
+
88127
 
+const struct sieve_match_type *sieve_match_type_find
88128
 
+(struct sieve_validator *validator, const char *identifier) 
88129
 
+{
88130
 
+       struct sieve_validator_object_registry *regs = 
88131
 
+               sieve_validator_object_registry_get(validator, ext_this);
88132
 
+       const struct sieve_object *object = 
88133
 
+               sieve_validator_object_registry_find(regs, identifier);
88134
 
+
88135
 
+  return (const struct sieve_match_type *) object;
88136
 
+}
88137
 
+
88138
 
+bool mtch_validator_load(struct sieve_validator *validator)
88139
 
+{
88140
 
+       struct sieve_validator_object_registry *regs = 
88141
 
+               sieve_validator_object_registry_init(validator, ext_this);
88142
 
+       unsigned int i;
88143
 
+
88144
 
+       /* Register core match-types */
88145
 
+       for ( i = 0; i < sieve_core_match_types_count; i++ ) {
88146
 
+               sieve_validator_object_registry_add
88147
 
+                       (regs, &(sieve_core_match_types[i]->object));
88148
 
+       }
88149
 
+
88150
 
+       return TRUE;
88151
 
+}
88152
 
+
88153
 
+/* 
88154
 
+ * Interpreter context
88155
 
+ */
88156
 
+
88157
 
+struct mtch_interpreter_context {
88158
 
+       struct sieve_match_values *match_values;
88159
 
+       bool match_values_enabled;
88160
 
+};
88161
 
+
88162
 
+static void mtch_interpreter_free
88163
 
+(struct sieve_interpreter *interp ATTR_UNUSED, void *context)
88164
 
+{
88165
 
+       struct mtch_interpreter_context *mctx = 
88166
 
+               (struct mtch_interpreter_context *) context;
88167
 
+       
88168
 
+       if ( mctx->match_values != NULL ) {
88169
 
+               pool_unref(&mctx->match_values->pool);
88170
 
+       }
88171
 
+}
88172
 
+
88173
 
+struct sieve_interpreter_extension mtch_interpreter_extension = {
88174
 
+       &match_type_extension,
88175
 
+       NULL,
88176
 
+       mtch_interpreter_free
88177
 
+};
88178
 
+
88179
 
+static inline struct mtch_interpreter_context *
88180
 
+get_interpreter_context(struct sieve_interpreter *interp)
88181
 
+{
88182
 
+       return (struct mtch_interpreter_context *)
88183
 
+               sieve_interpreter_extension_get_context(interp, ext_this);
88184
 
+}
88185
 
+
88186
 
+static struct mtch_interpreter_context *
88187
 
+mtch_interpreter_context_init(struct sieve_interpreter *interp)
88188
 
+{              
88189
 
+       pool_t pool = sieve_interpreter_pool(interp);
88190
 
+       struct mtch_interpreter_context *ctx;
88191
 
+       
88192
 
+       ctx = p_new(pool, struct mtch_interpreter_context, 1);
88193
 
+
88194
 
+       sieve_interpreter_extension_register
88195
 
+               (interp, &mtch_interpreter_extension, (void *) ctx);
88196
 
+
88197
 
+       return ctx;
88198
 
+}
88199
 
+
88200
 
+/*
88201
 
+ * Match values
88202
 
+ */
88203
 
+
88204
 
+bool sieve_match_values_set_enabled
88205
 
+(struct sieve_interpreter *interp, bool enable)
88206
 
+{
88207
 
+       struct mtch_interpreter_context *ctx = get_interpreter_context(interp);
88208
 
+       
88209
 
+       if ( ctx == NULL && enable ) 
88210
 
+               ctx = mtch_interpreter_context_init(interp);
88211
 
+       
88212
 
+       if ( ctx != NULL ) {
88213
 
+               bool previous = ctx->match_values_enabled;
88214
 
+               
88215
 
+               ctx->match_values_enabled = enable;
88216
 
+               return previous;
88217
 
+       }
88218
 
+       
88219
 
+       return FALSE;
88220
 
+}
88221
 
+
88222
 
+bool sieve_match_values_are_enabled
88223
 
+(struct sieve_interpreter *interp)
88224
 
+{
88225
 
+       struct mtch_interpreter_context *ctx = get_interpreter_context(interp);
88226
 
+               
88227
 
+       return ( ctx == NULL ? FALSE : ctx->match_values_enabled );
88228
 
+}
88229
 
+
88230
 
+struct sieve_match_values *sieve_match_values_start
88231
 
+(struct sieve_interpreter *interp)
88232
 
+{
88233
 
+       struct mtch_interpreter_context *ctx = get_interpreter_context(interp);
88234
 
+       struct sieve_match_values *match_values;
88235
 
+       
88236
 
+       if ( ctx == NULL || !ctx->match_values_enabled )
88237
 
+               return NULL;
88238
 
+       
88239
 
+       pool_t pool = pool_alloconly_create("sieve_match_values", 1024);
88240
 
+               
88241
 
+       match_values = p_new(pool, struct sieve_match_values, 1);
88242
 
+       match_values->pool = pool;
88243
 
+       match_values->count = 0;
88244
 
+       
88245
 
+       p_array_init(&match_values->values, pool, 4);
88246
 
+
88247
 
+       return match_values;
88248
 
+}
88249
 
+
88250
 
+static string_t *sieve_match_values_add_entry
88251
 
+(struct sieve_match_values *mvalues) 
88252
 
+{
88253
 
+       string_t *entry;
88254
 
+       
88255
 
+       if ( mvalues == NULL ) return NULL;     
88256
 
+
88257
 
+       if ( mvalues->count >= SIEVE_MAX_MATCH_VALUES ) return NULL;
88258
 
+               
88259
 
+       if ( mvalues->count >= array_count(&mvalues->values) ) {
88260
 
+               entry = str_new(mvalues->pool, 64);
88261
 
+               array_append(&mvalues->values, &entry, 1);      } else {
88262
 
+               string_t * const *ep = array_idx(&mvalues->values, mvalues->count);
88263
 
+               entry = *ep;
88264
 
+               str_truncate(entry, 0);
88265
 
+       }
88266
 
+       
88267
 
+       mvalues->count++;
88268
 
+
88269
 
+       return entry;
88270
 
+}
88271
 
+
88272
 
+void sieve_match_values_set
88273
 
+(struct sieve_match_values *mvalues, unsigned int index, string_t *value)
88274
 
+{
88275
 
+       if ( mvalues != NULL && index < array_count(&mvalues->values) ) {
88276
 
+               string_t * const *ep = array_idx(&mvalues->values, index);
88277
 
+       string_t *entry = *ep;
88278
 
+
88279
 
+           if ( entry != NULL && value != NULL ) {
88280
 
+                       str_truncate(entry, 0);
88281
 
+               str_append_str(entry, value);
88282
 
+               }
88283
 
+       }
88284
 
+}
88285
 
+       
88286
 
+void sieve_match_values_add
88287
 
+(struct sieve_match_values *mvalues, string_t *value) 
88288
 
+{
88289
 
+       string_t *entry = sieve_match_values_add_entry(mvalues); 
88290
 
+
88291
 
+       if ( entry != NULL && value != NULL )
88292
 
+               str_append_str(entry, value);
88293
 
+}
88294
 
+
88295
 
+void sieve_match_values_add_char
88296
 
+(struct sieve_match_values *mvalues, char c) 
88297
 
+{
88298
 
+       string_t *entry = sieve_match_values_add_entry(mvalues); 
88299
 
+
88300
 
+       if ( entry != NULL )
88301
 
+               str_append_c(entry, c);
88302
 
+}
88303
 
+
88304
 
+void sieve_match_values_skip
88305
 
+(struct sieve_match_values *mvalues, int num) 
88306
 
+{
88307
 
+       int i;
88308
 
+       
88309
 
+       for ( i = 0; i < num; i++ )
88310
 
+               (void) sieve_match_values_add_entry(mvalues); 
88311
 
+}
88312
 
+
88313
 
+void sieve_match_values_commit
88314
 
+(struct sieve_interpreter *interp, struct sieve_match_values **mvalues)
88315
 
+{
88316
 
+       struct mtch_interpreter_context *ctx;
88317
 
+       
88318
 
+       if ( (*mvalues) == NULL ) return;
88319
 
+       
88320
 
+       ctx = get_interpreter_context(interp);
88321
 
+       if ( ctx == NULL || !ctx->match_values_enabled )
88322
 
+               return; 
88323
 
+               
88324
 
+       if ( ctx->match_values != NULL ) {
88325
 
+               pool_unref(&ctx->match_values->pool);
88326
 
+               ctx->match_values = NULL;
88327
 
+       }
88328
 
+
88329
 
+       ctx->match_values = *mvalues;
88330
 
+       *mvalues = NULL;
88331
 
+}
88332
 
+
88333
 
+void sieve_match_values_abort
88334
 
+(struct sieve_match_values **mvalues)
88335
 
+{              
88336
 
+       if ( (*mvalues) == NULL ) return;
88337
 
+       
88338
 
+       pool_unref(&(*mvalues)->pool);
88339
 
+       *mvalues = NULL;
88340
 
+}
88341
 
+
88342
 
+void sieve_match_values_get
88343
 
+(struct sieve_interpreter *interp, unsigned int index, string_t **value_r) 
88344
 
+{
88345
 
+       struct mtch_interpreter_context *ctx = get_interpreter_context(interp);
88346
 
+       struct sieve_match_values *mvalues;
88347
 
+
88348
 
+       if ( ctx == NULL || ctx->match_values == NULL ) {
88349
 
+               *value_r = NULL;
88350
 
+               return;
88351
 
+       }
88352
 
+       
88353
 
+       mvalues = ctx->match_values;
88354
 
+       if ( index < array_count(&mvalues->values) && index < mvalues->count ) {
88355
 
+               string_t * const *entry = array_idx(&mvalues->values, index);
88356
 
+               
88357
 
+               *value_r = *entry;
88358
 
+               return;
88359
 
+       }
88360
 
+
88361
 
+       *value_r = NULL;        
88362
 
+}
88363
 
+
88364
 
+/* 
88365
 
+ * Match-type tagged argument 
88366
 
+ */
88367
 
88368
 
+/* Forward declarations */
88369
 
+
88370
 
+static bool tag_match_type_is_instance_of
88371
 
+       (struct sieve_validator *validator, struct sieve_command_context *cmd, 
88372
 
+               struct sieve_ast_argument *arg);
88373
 
+static bool tag_match_type_validate
88374
 
+       (struct sieve_validator *validator, struct sieve_ast_argument **arg, 
88375
 
+               struct sieve_command_context *cmd);
88376
 
+static bool tag_match_type_generate
88377
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, 
88378
 
+               struct sieve_command_context *cmd);
88379
 
+
88380
 
+/* Argument object */
88381
 
88382
 
+const struct sieve_argument match_type_tag = { 
88383
 
+       "MATCH-TYPE",
88384
 
+       tag_match_type_is_instance_of,
88385
 
+       NULL, 
88386
 
+       tag_match_type_validate, 
88387
 
+       NULL,
88388
 
+       tag_match_type_generate 
88389
 
+};
88390
 
+
88391
 
+/* Argument implementation */
88392
 
+
88393
 
+static bool tag_match_type_is_instance_of
88394
 
+(struct sieve_validator *validator, struct sieve_command_context *cmd, 
88395
 
+       struct sieve_ast_argument *arg)
88396
 
+{
88397
 
+       struct sieve_match_type_context *mtctx;
88398
 
+       const struct sieve_match_type *mtch = 
88399
 
+               sieve_match_type_find(validator, sieve_ast_argument_tag(arg));
88400
 
+               
88401
 
+       if ( mtch == NULL ) return FALSE;       
88402
 
+               
88403
 
+       /* Create context */
88404
 
+       mtctx = p_new(sieve_command_pool(cmd), struct sieve_match_type_context, 1);
88405
 
+       mtctx->match_type = mtch;
88406
 
+       mtctx->match_type_arg = arg;
88407
 
+       mtctx->command_ctx = cmd;
88408
 
+       mtctx->comparator = NULL; /* Can be filled in later */
88409
 
+       
88410
 
+       arg->context = (void *) mtctx;
88411
 
+       
88412
 
+       return TRUE;
88413
 
+}
88414
 
88415
 
+static bool tag_match_type_validate
88416
 
+(struct sieve_validator *validator, struct sieve_ast_argument **arg, 
88417
 
+       struct sieve_command_context *cmd ATTR_UNUSED)
88418
 
+{
88419
 
+       struct sieve_match_type_context *mtctx = 
88420
 
+               (struct sieve_match_type_context *) (*arg)->context;
88421
 
+       const struct sieve_match_type *mtch = mtctx->match_type;
88422
 
+
88423
 
+       /* Syntax:   
88424
 
+        *   ":is" / ":contains" / ":matches" (subject to extension)
88425
 
+        */
88426
 
+               
88427
 
+       /* Skip tag */
88428
 
+       *arg = sieve_ast_argument_next(*arg);
88429
 
+       
88430
 
+       /* Check whether this match type requires additional validation. 
88431
 
+        * Additional validation can override the match type recorded in the context 
88432
 
+        * for later code generation. 
88433
 
+        */
88434
 
+       if ( mtch->validate != NULL ) {
88435
 
+               return mtch->validate(validator, arg, mtctx);
88436
 
+       }
88437
 
+       
88438
 
+       return TRUE;
88439
 
+}
88440
 
+
88441
 
+static bool tag_match_type_generate
88442
 
+(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, 
88443
 
+       struct sieve_command_context *cmd ATTR_UNUSED)
88444
 
+{
88445
 
+       struct sieve_match_type_context *mtctx =
88446
 
+               (struct sieve_match_type_context *) arg->context;
88447
 
+       
88448
 
+       (void) sieve_opr_match_type_emit(cgenv->sbin, mtctx->match_type);
88449
 
+                       
88450
 
+       return TRUE;
88451
 
+}
88452
 
+
88453
 
+void sieve_match_types_link_tags
88454
 
+       (struct sieve_validator *validator, 
88455
 
+               struct sieve_command_registration *cmd_reg, int id_code) 
88456
 
+{      
88457
 
+       sieve_validator_register_tag
88458
 
+               (validator, cmd_reg, &match_type_tag, id_code);         
88459
 
+}
88460
 
+
88461
 
+/*
88462
 
+ * Validation
88463
 
+ */
88464
 
+
88465
 
+bool sieve_match_type_validate
88466
 
+(struct sieve_validator *validator, struct sieve_command_context *cmd,
88467
 
+       struct sieve_ast_argument *key_arg, 
88468
 
+       const struct sieve_match_type *mcht_default, 
88469
 
+       const struct sieve_comparator *cmp_default)
88470
 
+{
88471
 
+       struct sieve_ast_argument *arg = sieve_command_first_argument(cmd);
88472
 
+       struct sieve_ast_argument *mt_arg = NULL;
88473
 
+       struct sieve_match_type_context *mtctx;
88474
 
+       const struct sieve_match_type *mcht = NULL;
88475
 
+       const struct sieve_comparator *cmp = NULL;
88476
 
+
88477
 
+       /* Find match type and comparator among the arguments */
88478
 
+       while ( arg != NULL && arg != cmd->first_positional ) {
88479
 
+               if ( sieve_argument_is_comparator(arg) ) {
88480
 
+                       cmp = sieve_comparator_tag_get(arg);
88481
 
+                       if ( mt_arg != NULL ) break;
88482
 
+               }
88483
 
+
88484
 
+               if ( sieve_argument_is_match_type(arg) ) {
88485
 
+                       mt_arg = arg;
88486
 
+                       if ( cmp != NULL ) break;
88487
 
+               }
88488
 
+               arg = sieve_ast_argument_next(arg);
88489
 
+       }
88490
 
+       
88491
 
+       /* Verify using the default comparator if none is specified explicitly */
88492
 
+       if ( cmp == NULL )
88493
 
+               cmp = cmp_default;
88494
 
+       
88495
 
+       /* Verify the default match type if none is specified explicitly */
88496
 
+       if ( mt_arg == NULL || mt_arg->context == NULL ) {
88497
 
+               mtctx = NULL;
88498
 
+               mcht = mcht_default;
88499
 
+       } else {
88500
 
+               mtctx = (struct sieve_match_type_context *) mt_arg->context;
88501
 
+               mcht = mtctx->match_type;
88502
 
+               mtctx->comparator = cmp;
88503
 
+       }
88504
 
+
88505
 
+       /* Check whether this match type requires additional validation. 
88506
 
+        * Additional validation can override the match type recorded in the context 
88507
 
+        * for later code generation. 
88508
 
+        */
88509
 
+       if ( mcht != NULL && mcht->validate_context != NULL ) {
88510
 
+               return mcht->validate_context(validator, mt_arg, mtctx, key_arg);
88511
 
+       }
88512
 
+       
88513
 
+       return TRUE;    
88514
 
+}
88515
 
+
88516
 
+/*
88517
 
+ * Match-type operand
88518
 
+ */
88519
 
88520
 
+const struct sieve_operand_class sieve_match_type_operand_class = 
88521
 
+       { "match type" };
88522
 
+       
88523
 
+static const struct sieve_extension_objects core_match_types =
88524
 
+       SIEVE_EXT_DEFINE_MATCH_TYPES(sieve_core_match_types);
88525
 
+
88526
 
+const struct sieve_operand match_type_operand = { 
88527
 
+       "match-type", 
88528
 
+       NULL,
88529
 
+       SIEVE_OPERAND_MATCH_TYPE,
88530
 
+       &sieve_match_type_operand_class,
88531
 
+       &core_match_types
88532
 
+};
88533
 
+
88534
 
+/*
88535
 
+ * Common validation implementation
88536
 
+ */
88537
 
+
88538
 
+bool sieve_match_substring_validate_context
88539
 
+(struct sieve_validator *validator, struct sieve_ast_argument *arg,
88540
 
+       struct sieve_match_type_context *ctx,
88541
 
+       struct sieve_ast_argument *key_arg ATTR_UNUSED)
88542
 
+{
88543
 
+       const struct sieve_comparator *cmp = ctx->comparator;
88544
 
+               
88545
 
+       if ( cmp == NULL )
88546
 
+               return TRUE;
88547
 
+                       
88548
 
+       if ( (cmp->flags & SIEVE_COMPARATOR_FLAG_SUBSTRING_MATCH) == 0 ) {
88549
 
+               sieve_argument_validate_error(validator, arg,
88550
 
+                       "the specified %s comparator does not support "
88551
 
+                       "sub-string matching as required by the :%s match type",
88552
 
+                       cmp->object.identifier, ctx->match_type->object.identifier );
88553
 
+
88554
 
+               return FALSE;
88555
 
+       }
88556
 
+       
88557
 
+       return TRUE;
88558
 
+} 
88559
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-match-types.h dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-match-types.h
88560
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-match-types.h    1970-01-01 01:00:00.000000000 +0100
88561
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-match-types.h     2009-02-24 13:40:12.000000000 +0100
88562
 
@@ -0,0 +1,201 @@
88563
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
88564
 
+ */
88565
 
88566
 
+#ifndef __SIEVE_MATCH_TYPES_H
88567
 
+#define __SIEVE_MATCH_TYPES_H
88568
 
+
88569
 
+#include "sieve-common.h"
88570
 
+#include "sieve-extensions.h"
88571
 
+#include "sieve-commands.h"
88572
 
+#include "sieve-code.h"
88573
 
+#include "sieve-objects.h"
88574
 
+
88575
 
+/*
88576
 
+ * Types
88577
 
+ */
88578
 
+
88579
 
+struct sieve_match_type_context;
88580
 
+
88581
 
+/*
88582
 
+ * Core match types 
88583
 
+ */
88584
 
88585
 
+enum sieve_match_type_code {
88586
 
+       SIEVE_MATCH_TYPE_IS,
88587
 
+       SIEVE_MATCH_TYPE_CONTAINS,
88588
 
+       SIEVE_MATCH_TYPE_MATCHES,
88589
 
+       SIEVE_MATCH_TYPE_CUSTOM
88590
 
+};
88591
 
+
88592
 
+extern const struct sieve_match_type is_match_type;
88593
 
+extern const struct sieve_match_type contains_match_type;
88594
 
+extern const struct sieve_match_type matches_match_type;
88595
 
+
88596
 
+/*
88597
 
+ * Match type object
88598
 
+ */
88599
 
88600
 
+struct sieve_match_type {
88601
 
+       struct sieve_object object;
88602
 
+
88603
 
+       /* Match function called for every key value or should it be called once
88604
 
+        * for every tested value? (TRUE = first alternative)
88605
 
+        */
88606
 
+       bool is_iterative;
88607
 
+       
88608
 
+       /* Is the key value allowed to contain formatting to extract multiple keys
88609
 
+        * out of the same string?
88610
 
+        */
88611
 
+       bool allow_key_extract;
88612
 
+               
88613
 
+       bool (*validate)
88614
 
+               (struct sieve_validator *validator, struct sieve_ast_argument **arg, 
88615
 
+                       struct sieve_match_type_context *ctx);
88616
 
+       bool (*validate_context)
88617
 
+               (struct sieve_validator *validator, struct sieve_ast_argument *arg, 
88618
 
+                       struct sieve_match_type_context *ctx, struct sieve_ast_argument *key_arg);
88619
 
+                       
88620
 
+       /*
88621
 
+        * Matching
88622
 
+        */
88623
 
+
88624
 
+       void (*match_init)(struct sieve_match_context *mctx);
88625
 
+
88626
 
+       /* WARNING: some tests may pass a val == NULL parameter indicating that the 
88627
 
+        * passed value has no significance. For string-type matches this should map 
88628
 
+        * to the empty string "", but for match types that consider the passed values 
88629
 
+        * as objects rather than strings (e.g. :count) this means that the passed 
88630
 
+        * value should be skipped. 
88631
 
+        */
88632
 
+       int (*match)
88633
 
+               (struct sieve_match_context *mctx, const char *val, size_t val_size, 
88634
 
+                       const char *key, size_t key_size, int key_index);
88635
 
+       int (*match_deinit)(struct sieve_match_context *mctx);
88636
 
+};
88637
 
+
88638
 
+struct sieve_match_type_context {
88639
 
+       struct sieve_command_context *command_ctx;
88640
 
+       struct sieve_ast_argument *match_type_arg;
88641
 
+
88642
 
+       const struct sieve_match_type *match_type;
88643
 
+       
88644
 
+       /* Only filled in when match_type->validate_context() is called */
88645
 
+       const struct sieve_comparator *comparator;
88646
 
+       
88647
 
+       /* Context data could be used in the future to pass data between validator and
88648
 
+        * generator in match types that use extra parameters. Currently not 
88649
 
+        * necessary, not even for the relational extension.
88650
 
+        */
88651
 
+       void *ctx_data;
88652
 
+};
88653
 
+
88654
 
+/*
88655
 
+ * Match type registration
88656
 
+ */
88657
 
+
88658
 
+void sieve_match_type_register
88659
 
+       (struct sieve_validator *validator, const struct sieve_match_type *mcht);
88660
 
+const struct sieve_match_type *sieve_match_type_find
88661
 
+       (struct sieve_validator *validator, const char *identifier);
88662
 
+
88663
 
+/* 
88664
 
+ * Match values 
88665
 
+ */
88666
 
+
88667
 
+struct sieve_match_values;
88668
 
+
88669
 
+bool sieve_match_values_set_enabled
88670
 
+       (struct sieve_interpreter *interp, bool enable);
88671
 
+bool sieve_match_values_are_enabled
88672
 
+       (struct sieve_interpreter *interp);     
88673
 
+       
88674
 
+struct sieve_match_values *sieve_match_values_start
88675
 
+       (struct sieve_interpreter *interp);
88676
 
+void sieve_match_values_set
88677
 
+       (struct sieve_match_values *mvalues, unsigned int index, string_t *value);
88678
 
+void sieve_match_values_add
88679
 
+       (struct sieve_match_values *mvalues, string_t *value);
88680
 
+void sieve_match_values_add_char
88681
 
+       (struct sieve_match_values *mvalues, char c);   
88682
 
+void sieve_match_values_skip
88683
 
+       (struct sieve_match_values *mvalues, int num);
88684
 
+       
88685
 
+void sieve_match_values_commit
88686
 
+       (struct sieve_interpreter *interp, struct sieve_match_values **mvalues);
88687
 
+void sieve_match_values_abort
88688
 
+       (struct sieve_match_values **mvalues);
88689
 
+       
88690
 
+void sieve_match_values_get
88691
 
+       (struct sieve_interpreter *interp, unsigned int index, string_t **value_r);
88692
 
+
88693
 
+/*
88694
 
+ * Match type tagged argument 
88695
 
+ */
88696
 
+
88697
 
+extern const struct sieve_argument match_type_tag;
88698
 
+
88699
 
+static inline bool sieve_argument_is_match_type
88700
 
+       (struct sieve_ast_argument *arg)
88701
 
+{
88702
 
+       return ( arg->argument == &match_type_tag );
88703
 
+}
88704
 
+
88705
 
+void sieve_match_types_link_tags
88706
 
+       (struct sieve_validator *validator, 
88707
 
+               struct sieve_command_registration *cmd_reg, int id_code);
88708
 
+
88709
 
+/*
88710
 
+ * Validation
88711
 
+ */
88712
 
+
88713
 
+bool sieve_match_type_validate
88714
 
+       (struct sieve_validator *validator, struct sieve_command_context *cmd,
88715
 
+               struct sieve_ast_argument *key_arg, 
88716
 
+               const struct sieve_match_type *mcht_default, 
88717
 
+               const struct sieve_comparator *cmp_default);
88718
 
+
88719
 
+/*
88720
 
+ * Match type operand
88721
 
+ */
88722
 
88723
 
+extern const struct sieve_operand match_type_operand;
88724
 
+extern const struct sieve_operand_class sieve_match_type_operand_class;
88725
 
+
88726
 
+#define SIEVE_EXT_DEFINE_MATCH_TYPE(OP) SIEVE_EXT_DEFINE_OBJECT(OP)
88727
 
+#define SIEVE_EXT_DEFINE_MATCH_TYPES(OPS) SIEVE_EXT_DEFINE_OBJECTS(OPS)
88728
 
+
88729
 
+static inline bool sieve_operand_is_match_type
88730
 
+(const struct sieve_operand *operand)
88731
 
+{
88732
 
+       return ( operand != NULL && 
88733
 
+               operand->class == &sieve_match_type_operand_class );
88734
 
+}
88735
 
+
88736
 
+static inline void sieve_opr_match_type_emit
88737
 
+(struct sieve_binary *sbin, const struct sieve_match_type *mtch)
88738
 
+{ 
88739
 
+       sieve_opr_object_emit(sbin, &mtch->object);
88740
 
+}
88741
 
+
88742
 
+static inline const struct sieve_match_type *sieve_opr_match_type_read
88743
 
+(const struct sieve_runtime_env *renv, sieve_size_t *address)
88744
 
+{
88745
 
+       return (const struct sieve_match_type *) sieve_opr_object_read
88746
 
+               (renv, &sieve_match_type_operand_class, address);
88747
 
+}
88748
 
+
88749
 
+static inline bool sieve_opr_match_type_dump
88750
 
+(const struct sieve_dumptime_env *denv, sieve_size_t *address)
88751
 
+{
88752
 
+       return sieve_opr_object_dump
88753
 
+               (denv, &sieve_match_type_operand_class, address, NULL);
88754
 
+}
88755
 
+
88756
 
+/* Common validation implementation */
88757
 
+
88758
 
+bool sieve_match_substring_validate_context
88759
 
+       (struct sieve_validator *validator, struct sieve_ast_argument *arg,
88760
 
+               struct sieve_match_type_context *ctx, 
88761
 
+               struct sieve_ast_argument *key_arg);
88762
 
+
88763
 
+#endif /* __SIEVE_MATCH_TYPES_H */
88764
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-message.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-message.c
88765
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-message.c        1970-01-01 01:00:00.000000000 +0100
88766
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-message.c 2009-07-21 02:51:39.000000000 +0200
88767
 
@@ -0,0 +1,190 @@
88768
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
88769
 
+ */
88770
 
+
88771
 
+#include "lib.h"
88772
 
+#include "ioloop.h"
88773
 
+#include "mempool.h"
88774
 
+#include "array.h"
88775
 
+
88776
 
+#include "sieve-common.h"
88777
 
+#include "sieve-error.h"
88778
 
+#include "sieve-extensions.h"
88779
 
+#include "sieve-address.h"
88780
 
+
88781
 
+#include "sieve-message.h"
88782
 
+
88783
 
+/*
88784
 
+ * Message transmission
88785
 
+ */
88786
 
88787
 
+const char *sieve_message_get_new_id
88788
 
+(const struct sieve_script_env *senv)
88789
 
+{
88790
 
+       static int count = 0;
88791
 
+       
88792
 
+       return t_strdup_printf("<dovecot-sieve-%s-%s-%d@%s>",
88793
 
+               dec2str(ioloop_timeval.tv_sec), dec2str(ioloop_timeval.tv_usec),
88794
 
+    count++, senv->hostname);
88795
 
+}
88796
 
+
88797
 
+/* 
88798
 
+ * Message context 
88799
 
+ */
88800
 
+
88801
 
+struct sieve_message_context {
88802
 
+       pool_t pool;
88803
 
+       int refcount;
88804
 
+
88805
 
+       const struct sieve_message_data *msgdata;
88806
 
+
88807
 
+       /* Normalized envelope addresses */
88808
 
+
88809
 
+       bool envelope_parsed;
88810
 
+
88811
 
+       const struct sieve_address *envelope_sender;
88812
 
+       const struct sieve_address *envelope_recipient;
88813
 
+       
88814
 
+       /* Context data for extensions */
88815
 
+       ARRAY_DEFINE(ext_contexts, void *); 
88816
 
+};
88817
 
+
88818
 
+struct sieve_message_context *sieve_message_context_create
88819
 
+(const struct sieve_message_data *msgdata)
88820
 
+{
88821
 
+       struct sieve_message_context *msgctx;
88822
 
+       
88823
 
+       msgctx = i_new(struct sieve_message_context, 1);
88824
 
+       msgctx->refcount = 1;
88825
 
+
88826
 
+       msgctx->msgdata = msgdata;
88827
 
+               
88828
 
+       sieve_message_context_flush(msgctx);
88829
 
+
88830
 
+       return msgctx;
88831
 
+}
88832
 
+
88833
 
+void sieve_message_context_ref(struct sieve_message_context *msgctx)
88834
 
+{
88835
 
+       msgctx->refcount++;
88836
 
+}
88837
 
+
88838
 
+void sieve_message_context_unref(struct sieve_message_context **msgctx)
88839
 
+{
88840
 
+       i_assert((*msgctx)->refcount > 0);
88841
 
+
88842
 
+       if (--(*msgctx)->refcount != 0)
88843
 
+               return;
88844
 
+       
88845
 
+       pool_unref(&((*msgctx)->pool));
88846
 
+               
88847
 
+       i_free(*msgctx);
88848
 
+       *msgctx = NULL;
88849
 
+}
88850
 
+
88851
 
+void sieve_message_context_flush(struct sieve_message_context *msgctx)
88852
 
+{
88853
 
+       pool_t pool;
88854
 
+
88855
 
+       if ( msgctx->pool != NULL ) {
88856
 
+               pool_unref(&msgctx->pool);
88857
 
+       }
88858
 
+
88859
 
+       pool = pool_alloconly_create("sieve_message_context", 1024);
88860
 
+       msgctx->pool = pool;
88861
 
+
88862
 
+       msgctx->envelope_recipient = NULL;
88863
 
+       msgctx->envelope_sender = NULL;
88864
 
+       msgctx->envelope_parsed = FALSE;
88865
 
+
88866
 
+       p_array_init(&msgctx->ext_contexts, pool, sieve_extensions_get_count());
88867
 
+}
88868
 
+
88869
 
+pool_t sieve_message_context_pool(struct sieve_message_context *msgctx)
88870
 
+{
88871
 
+       return msgctx->pool;
88872
 
+}
88873
 
+
88874
 
+/* Extension support */
88875
 
+
88876
 
+void sieve_message_context_extension_set
88877
 
+(struct sieve_message_context *msgctx, const struct sieve_extension *ext, 
88878
 
+       void *context)
88879
 
+{
88880
 
+       array_idx_set(&msgctx->ext_contexts, (unsigned int) SIEVE_EXT_ID(ext), &context);       
88881
 
+}
88882
 
+
88883
 
+const void *sieve_message_context_extension_get
88884
 
+(struct sieve_message_context *msgctx, const struct sieve_extension *ext) 
88885
 
+{
88886
 
+       int ext_id = SIEVE_EXT_ID(ext);
88887
 
+       void * const *ctx;
88888
 
+
88889
 
+       if  ( ext_id < 0 || ext_id >= (int) array_count(&msgctx->ext_contexts) )
88890
 
+               return NULL;
88891
 
+       
88892
 
+       ctx = array_idx(&msgctx->ext_contexts, (unsigned int) ext_id);          
88893
 
+
88894
 
+       return *ctx;
88895
 
+}
88896
 
+
88897
 
+/* Envelope */
88898
 
+
88899
 
+static void sieve_message_envelope_parse(struct sieve_message_context *msgctx)
88900
 
+{
88901
 
+       /* FIXME: log parse problems properly; logs only 'failure' now */
88902
 
+
88903
 
+       msgctx->envelope_recipient = sieve_address_parse_envelope_path
88904
 
+               (msgctx->pool, msgctx->msgdata->to_address);    
88905
 
+
88906
 
+       if ( msgctx->envelope_recipient == NULL )
88907
 
+               sieve_sys_error("envelope recipient address '%s' is unparseable", msgctx->msgdata->to_address); 
88908
 
+       else if ( msgctx->envelope_recipient->local_part == NULL )
88909
 
+               sieve_sys_error("envelope recipient address '%s' is a null path", msgctx->msgdata->to_address); 
88910
 
+
88911
 
+       msgctx->envelope_sender = sieve_address_parse_envelope_path
88912
 
+               (msgctx->pool, msgctx->msgdata->return_path);   
88913
 
+
88914
 
+       if ( msgctx->envelope_sender == NULL )
88915
 
+               sieve_sys_error("envelope sender address '%s' is unparseable", msgctx->msgdata->return_path); 
88916
 
+
88917
 
+       msgctx->envelope_parsed = TRUE;
88918
 
+}
88919
 
+
88920
 
+const struct sieve_address *sieve_message_get_recipient_address
88921
 
+(struct sieve_message_context *msgctx)
88922
 
+{
88923
 
+       if ( !msgctx->envelope_parsed ) 
88924
 
+               sieve_message_envelope_parse(msgctx);
88925
 
+
88926
 
+       return msgctx->envelope_recipient;
88927
 
+} 
88928
 
+
88929
 
+const struct sieve_address *sieve_message_get_sender_address
88930
 
+(struct sieve_message_context *msgctx)
88931
 
+{
88932
 
+       if ( !msgctx->envelope_parsed ) 
88933
 
+               sieve_message_envelope_parse(msgctx);
88934
 
+
88935
 
+       return msgctx->envelope_sender; 
88936
 
+} 
88937
 
+
88938
 
+const char *sieve_message_get_recipient
88939
 
+(struct sieve_message_context *msgctx)
88940
 
+{
88941
 
+       if ( !msgctx->envelope_parsed ) 
88942
 
+               sieve_message_envelope_parse(msgctx);
88943
 
+
88944
 
+       return sieve_address_to_string(msgctx->envelope_recipient);
88945
 
+}
88946
 
+
88947
 
+const char *sieve_message_get_sender
88948
 
+(struct sieve_message_context *msgctx)
88949
 
+{
88950
 
+       if ( !msgctx->envelope_parsed ) 
88951
 
+               sieve_message_envelope_parse(msgctx);
88952
 
+
88953
 
+       return sieve_address_to_string(msgctx->envelope_sender);
88954
 
+} 
88955
 
+
88956
 
+
88957
 
+
88958
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-message.h dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-message.h
88959
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-message.h        1970-01-01 01:00:00.000000000 +0100
88960
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-message.h 2009-07-21 02:50:36.000000000 +0200
88961
 
@@ -0,0 +1,52 @@
88962
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
88963
 
+ */
88964
 
+
88965
 
+#ifndef __SIEVE_MESSAGE_H
88966
 
+#define __SIEVE_MESSAGE_H
88967
 
+
88968
 
+/* 
88969
 
+ * Message transmission
88970
 
+ */
88971
 
+
88972
 
+const char *sieve_message_get_new_id
88973
 
+       (const struct sieve_script_env *senv);
88974
 
+
88975
 
+/* 
88976
 
+ * Message context 
88977
 
+ */
88978
 
+
88979
 
+struct sieve_message_context;
88980
 
+
88981
 
+struct sieve_message_context *sieve_message_context_create
88982
 
+       (const struct sieve_message_data *msgdata);
88983
 
+void sieve_message_context_ref(struct sieve_message_context *msgctx);
88984
 
+void sieve_message_context_unref(struct sieve_message_context **msgctx);
88985
 
+
88986
 
+void sieve_message_context_flush(struct sieve_message_context *msgctx);
88987
 
+
88988
 
+pool_t sieve_message_context_pool
88989
 
+       (struct sieve_message_context *msgctx);
88990
 
+
88991
 
+/* Extension support */
88992
 
+
88993
 
+void sieve_message_context_extension_set
88994
 
+       (struct sieve_message_context *msgctx, const struct sieve_extension *ext, 
88995
 
+               void *context);
88996
 
+const void *sieve_message_context_extension_get
88997
 
+       (struct sieve_message_context *msgctx, const struct sieve_extension *ext);
88998
 
+
88999
 
+/* Envelope */
89000
 
+
89001
 
+const struct sieve_address *sieve_message_get_recipient_address
89002
 
+       (struct sieve_message_context *msgctx);
89003
 
+
89004
 
+const struct sieve_address *sieve_message_get_sender_address
89005
 
+       (struct sieve_message_context *msgctx);
89006
 
+
89007
 
+const char *sieve_message_get_recipient
89008
 
+       (struct sieve_message_context *msgctx);
89009
 
+
89010
 
+const char *sieve_message_get_sender
89011
 
+       (struct sieve_message_context *msgctx);
89012
 
+       
89013
 
+#endif /* __SIEVE_MESSAGE_H */
89014
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-objects.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-objects.c
89015
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-objects.c        1970-01-01 01:00:00.000000000 +0100
89016
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-objects.c 2009-01-06 00:15:52.000000000 +0100
89017
 
@@ -0,0 +1,96 @@
89018
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
89019
 
+ */
89020
 
+
89021
 
+#include "sieve-common.h"
89022
 
+#include "sieve-extensions.h"
89023
 
+#include "sieve-code.h"
89024
 
+#include "sieve-binary.h"
89025
 
+#include "sieve-dump.h"
89026
 
+#include "sieve-interpreter.h"
89027
 
+
89028
 
+#include "sieve-objects.h"
89029
 
+
89030
 
+/*
89031
 
+ * Object coding
89032
 
+ */
89033
 
+
89034
 
+void sieve_opr_object_emit
89035
 
+(struct sieve_binary *sbin, const struct sieve_object *obj)
89036
 
+{
89037
 
+       struct sieve_extension_objects *objs = 
89038
 
+               (struct sieve_extension_objects *) obj->operand->interface;
89039
 
+                
89040
 
+       (void) sieve_operand_emit_code(sbin, obj->operand);
89041
 
+       
89042
 
+       if ( objs->count > 1 ) {        
89043
 
+               (void) sieve_binary_emit_byte(sbin, obj->code);
89044
 
+       } 
89045
 
+}
89046
 
+
89047
 
+const struct sieve_object *sieve_opr_object_read_data
89048
 
+(struct sieve_binary *sbin, const struct sieve_operand *operand,
89049
 
+       const struct sieve_operand_class *opclass, sieve_size_t *address)
89050
 
+{
89051
 
+       const struct sieve_extension_objects *objs;
89052
 
+       unsigned int obj_code; 
89053
 
+
89054
 
+       if ( operand == NULL || operand->class != opclass )
89055
 
+               return NULL;
89056
 
+       
89057
 
+       objs = (struct sieve_extension_objects *) operand->interface;
89058
 
+       if ( objs == NULL ) 
89059
 
+               return NULL;
89060
 
+                       
89061
 
+       if ( objs->count > 1 ) {
89062
 
+               if ( !sieve_binary_read_byte(sbin, address, &obj_code) ) 
89063
 
+                       return NULL;
89064
 
+
89065
 
+               if ( obj_code < objs->count ) {
89066
 
+                       const struct sieve_object *const *objects = 
89067
 
+                               (const struct sieve_object* const *) objs->objects;
89068
 
+                       return objects[obj_code]; 
89069
 
+               }
89070
 
+       }
89071
 
+       
89072
 
+       return (const struct sieve_object *) objs->objects; 
89073
 
+}
89074
 
+
89075
 
+const struct sieve_object *sieve_opr_object_read
89076
 
+(const struct sieve_runtime_env *renv, 
89077
 
+       const struct sieve_operand_class *opclass, sieve_size_t *address)
89078
 
+{
89079
 
+       const struct sieve_operand *operand = sieve_operand_read(renv->sbin, address);
89080
 
+       
89081
 
+       return sieve_opr_object_read_data(renv->sbin, operand, opclass, address);
89082
 
+}
89083
 
+
89084
 
+bool sieve_opr_object_dump
89085
 
+(const struct sieve_dumptime_env *denv, 
89086
 
+       const struct sieve_operand_class *opclass, sieve_size_t *address,
89087
 
+       const struct sieve_object **object_r)
89088
 
+{
89089
 
+       const struct sieve_operand *operand;
89090
 
+       const struct sieve_object *obj;
89091
 
+       const char *class;
89092
 
+       
89093
 
+       sieve_code_mark(denv);
89094
 
+       
89095
 
+       operand = sieve_operand_read(denv->sbin, address); 
89096
 
+       obj = sieve_opr_object_read_data(denv->sbin, operand, opclass, address);
89097
 
+       
89098
 
+       if ( obj == NULL )
89099
 
+               return FALSE;
89100
 
+               
89101
 
+       if ( operand->class == NULL )
89102
 
+               class = "OBJECT";
89103
 
+       else
89104
 
+               class = operand->class->name;
89105
 
+                       
89106
 
+       sieve_code_dumpf(denv, "%s: %s", class, obj->identifier);
89107
 
+       
89108
 
+       if ( object_r != NULL )
89109
 
+               *object_r = obj;
89110
 
+       
89111
 
+       return TRUE;
89112
 
+}
89113
 
+
89114
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-objects.h dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-objects.h
89115
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-objects.h        1970-01-01 01:00:00.000000000 +0100
89116
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-objects.h 2009-01-06 00:15:52.000000000 +0100
89117
 
@@ -0,0 +1,41 @@
89118
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
89119
 
+ */
89120
 
+
89121
 
+#ifndef __SIEVE_OBJECTS_H
89122
 
+#define __SIEVE_OBJECTS_H
89123
 
+
89124
 
+/*
89125
 
+ * Object
89126
 
+ */
89127
 
+
89128
 
+struct sieve_object {
89129
 
+       const char *identifier;
89130
 
+       const struct sieve_operand *operand;
89131
 
+       unsigned int code;
89132
 
+};
89133
 
+
89134
 
+#define SIEVE_OBJECT(identifier, operand, code) \
89135
 
+       { identifier, operand, code }
89136
 
+
89137
 
+/*
89138
 
+ * Object coding
89139
 
+ */
89140
 
89141
 
+void sieve_opr_object_emit
89142
 
+       (struct sieve_binary *sbin, const struct sieve_object *obj);
89143
 
+
89144
 
+const struct sieve_object *sieve_opr_object_read_data
89145
 
+       (struct sieve_binary *sbin, const struct sieve_operand *operand,
89146
 
+               const struct sieve_operand_class *opclass, sieve_size_t *address);
89147
 
+
89148
 
+const struct sieve_object *sieve_opr_object_read
89149
 
+       (const struct sieve_runtime_env *renv, 
89150
 
+               const struct sieve_operand_class *opclass, sieve_size_t *address);
89151
 
+
89152
 
+bool sieve_opr_object_dump
89153
 
+       (const struct sieve_dumptime_env *denv, 
89154
 
+               const struct sieve_operand_class *opclass, sieve_size_t *address,
89155
 
+               const struct sieve_object **object_r);
89156
 
+
89157
 
+
89158
 
+#endif /* __SIEVE_OBJECTS_H */
89159
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-parser.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-parser.c
89160
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-parser.c 1970-01-01 01:00:00.000000000 +0100
89161
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-parser.c  2009-01-06 00:15:52.000000000 +0100
89162
 
@@ -0,0 +1,655 @@
89163
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file 
89164
 
+ */
89165
 
89166
 
+#include <stdio.h>
89167
 
+
89168
 
+#include "lib.h"
89169
 
+#include "istream.h"
89170
 
+#include "failures.h"
89171
 
+
89172
 
+#include "sieve-common.h"
89173
 
+#include "sieve-limits.h"
89174
 
+#include "sieve-script.h"
89175
 
+#include "sieve-lexer.h"
89176
 
+#include "sieve-parser.h"
89177
 
+#include "sieve-error.h"
89178
 
+#include "sieve-ast.h"
89179
 
+
89180
 
+/*
89181
 
+ * Forward declarations
89182
 
+ */
89183
 
89184
 
+inline static void sieve_parser_error
89185
 
+       (struct sieve_parser *parser, const char *fmt, ...) ATTR_FORMAT(2, 3);
89186
 
+inline static void sieve_parser_warning
89187
 
+       (struct sieve_parser *parser, const char *fmt, ...) ATTR_FORMAT(2, 3); 
89188
 
89189
 
+static int sieve_parser_recover
89190
 
+       (struct sieve_parser *parser, enum sieve_token_type end_token);
89191
 
+
89192
 
+/*
89193
 
+ * Parser object
89194
 
+ */
89195
 
+
89196
 
+struct sieve_parser {
89197
 
+       pool_t pool;
89198
 
+       
89199
 
+       bool valid;
89200
 
+       
89201
 
+       struct sieve_script *script;
89202
 
+               
89203
 
+       struct sieve_error_handler *ehandler;
89204
 
+       
89205
 
+       struct sieve_lexer *lexer;
89206
 
+       struct sieve_ast *ast;
89207
 
+};
89208
 
+
89209
 
+struct sieve_parser *sieve_parser_create
89210
 
+(struct sieve_script *script, struct sieve_error_handler *ehandler)
89211
 
+{
89212
 
+       struct sieve_parser *parser;
89213
 
+       struct sieve_lexer *lexer;
89214
 
+       
89215
 
+       lexer = sieve_lexer_create(script, ehandler);
89216
 
+  
89217
 
+       if ( lexer != NULL ) {
89218
 
+               pool_t pool = pool_alloconly_create("sieve_parser", 4096);      
89219
 
+
89220
 
+               parser = p_new(pool, struct sieve_parser, 1);
89221
 
+               parser->pool = pool;
89222
 
+               parser->valid = TRUE;
89223
 
+               
89224
 
+               parser->ehandler = ehandler;
89225
 
+               sieve_error_handler_ref(ehandler);
89226
 
+
89227
 
+               parser->script = script;
89228
 
+               sieve_script_ref(script);
89229
 
+                               
89230
 
+               parser->lexer = lexer;
89231
 
+               parser->ast = NULL;
89232
 
+                               
89233
 
+               return parser;
89234
 
+       }
89235
 
+       
89236
 
+       return NULL;
89237
 
+}
89238
 
+
89239
 
+void sieve_parser_free(struct sieve_parser **parser)
89240
 
+{
89241
 
+       if ((*parser)->ast != NULL)       
89242
 
+               sieve_ast_unref(&(*parser)->ast);
89243
 
+
89244
 
+       sieve_lexer_free(&(*parser)->lexer);
89245
 
+       sieve_script_unref(&(*parser)->script);
89246
 
+
89247
 
+       sieve_error_handler_unref(&(*parser)->ehandler);
89248
 
+
89249
 
+       pool_unref(&(*parser)->pool);
89250
 
+       
89251
 
+       *parser = NULL;
89252
 
+}
89253
 
+
89254
 
+/*
89255
 
+ * Internal error handling
89256
 
+ */
89257
 
+
89258
 
+inline static void sieve_parser_error
89259
 
+(struct sieve_parser *parser, const char *fmt, ...)
89260
 
+{ 
89261
 
+       va_list args;
89262
 
+       va_start(args, fmt);
89263
 
+
89264
 
+       /* Don't report a parse error if the lexer complained already */ 
89265
 
+       if ( sieve_lexer_current_token(parser->lexer) != STT_ERROR )  
89266
 
+       {
89267
 
+               T_BEGIN {
89268
 
+                       sieve_verror(parser->ehandler,
89269
 
+                               sieve_error_script_location(parser->script, 
89270
 
+                                       sieve_lexer_current_line(parser->lexer)),
89271
 
+                               fmt, args);
89272
 
+               } T_END; 
89273
 
+       }
89274
 
+       
89275
 
+       parser->valid = FALSE;
89276
 
+       
89277
 
+       va_end(args);
89278
 
+}
89279
 
+
89280
 
+inline static void sieve_parser_warning
89281
 
+(struct sieve_parser *parser, const char *fmt, ...)
89282
 
+{
89283
 
+       va_list args;
89284
 
+       va_start(args, fmt);
89285
 
+
89286
 
+       T_BEGIN {
89287
 
+               sieve_vwarning(parser->ehandler, 
89288
 
+                       sieve_error_script_location(parser->script, 
89289
 
+                               sieve_lexer_current_line(parser->lexer)),
89290
 
+                       fmt, args);
89291
 
+       } T_END;
89292
 
+               
89293
 
+       va_end(args);
89294
 
+} 
89295
 
+
89296
 
+/*
89297
 
+ * Sieve grammar parsing
89298
 
+ */
89299
 
+
89300
 
+/* sieve_parse_arguments():
89301
 
+ *
89302
 
+ * Parses both command arguments and sub-tests:
89303
 
+ *   arguments = *argument [test / test-list]
89304
 
+ *   argument = string-list / number / tag
89305
 
+ *   string = quoted-string / multi-line   [[implicitly handled in lexer]]
89306
 
+ *   string-list = "[" string *("," string) "]" / string         ;; if
89307
 
+ *     there is only a single string, the brackets are optional
89308
 
+ *   test-list = "(" test *("," test) ")"
89309
 
+ *   test = identifier arguments
89310
 
+ */
89311
 
+static int sieve_parse_arguments
89312
 
+(struct sieve_parser *parser, struct sieve_ast_node *node, unsigned int depth) 
89313
 
+{      
89314
 
+       struct sieve_lexer *lexer = parser->lexer;
89315
 
+       struct sieve_ast_node *test = NULL;
89316
 
+       bool test_present = TRUE;
89317
 
+       bool arg_present = TRUE;
89318
 
+       int result = TRUE; /* Indicates whether the parser is in a defined, not 
89319
 
+                              necessarily error-free state */
89320
 
+
89321
 
+       /* Parse arguments */
89322
 
+       while ( arg_present && result > 0 && 
89323
 
+               (parser->valid || sieve_errors_more_allowed(parser->ehandler)) ) {
89324
 
+               struct sieve_ast_argument *arg;
89325
 
+               
89326
 
+               switch ( sieve_lexer_current_token(lexer) ) {
89327
 
+               
89328
 
+               /* String list */
89329
 
+               case STT_LSQUARE:
89330
 
+                       /* Create stinglist object */
89331
 
+                       arg = sieve_ast_argument_stringlist_create
89332
 
+                               (node, sieve_lexer_current_line(parser->lexer));
89333
 
+
89334
 
+                       if ( arg == NULL ) break;
89335
 
+                               
89336
 
+                       sieve_lexer_skip_token(lexer);                  
89337
 
+                       
89338
 
+                       if ( sieve_lexer_current_token(lexer) == STT_STRING ) {
89339
 
+                               bool add_failed = FALSE;
89340
 
+
89341
 
+                               /* Add the string to the list */
89342
 
+                               if ( !sieve_ast_stringlist_add
89343
 
+                                       (arg, sieve_lexer_token_str(lexer), 
89344
 
+                                               sieve_lexer_current_line(parser->lexer)) )
89345
 
+                                       add_failed = TRUE;
89346
 
+                               
89347
 
+                               sieve_lexer_skip_token(lexer);
89348
 
+                                
89349
 
+                               while ( !add_failed && sieve_lexer_current_token(lexer) == STT_COMMA &&
89350
 
+                                       (parser->valid || sieve_errors_more_allowed(parser->ehandler)) ) {
89351
 
+                       
89352
 
+                                       sieve_lexer_skip_token(lexer);
89353
 
+                               
89354
 
+                                       if ( sieve_lexer_current_token(lexer) == STT_STRING ) {
89355
 
+                                               /* Add the string to the list */
89356
 
+                                               if ( !sieve_ast_stringlist_add
89357
 
+                                                       (arg, sieve_lexer_token_str(lexer), 
89358
 
+                                                               sieve_lexer_current_line(parser->lexer)) )
89359
 
+                                                       add_failed = TRUE;
89360
 
+                                                       
89361
 
+                                               sieve_lexer_skip_token(lexer);
89362
 
+                                       } else {
89363
 
+                                               sieve_parser_error(parser, 
89364
 
+                                                       "expecting string after ',' in string list, but found %s",
89365
 
+                                                       sieve_lexer_token_string(lexer));
89366
 
+                                       
89367
 
+                                               result = sieve_parser_recover(parser, STT_RSQUARE);
89368
 
+                                               break;
89369
 
+                                       }
89370
 
+                               }
89371
 
+                               
89372
 
+                               if ( add_failed ) {
89373
 
+                                       sieve_parser_error(parser, 
89374
 
+                                               "failed to accept more items in string list");
89375
 
+                                       return -1;
89376
 
+                               }
89377
 
+                       } else {
89378
 
+                               sieve_parser_error(parser, 
89379
 
+                                       "expecting string after '[' in string list, but found %s",
89380
 
+                                       sieve_lexer_token_string(lexer));
89381
 
+                       
89382
 
+                               result = sieve_parser_recover(parser, STT_RSQUARE);
89383
 
+                       }
89384
 
+               
89385
 
+                       /* Finish the string list */
89386
 
+                       if ( sieve_lexer_current_token(lexer) == STT_RSQUARE ) {
89387
 
+                               sieve_lexer_skip_token(lexer);
89388
 
+                       } else {
89389
 
+                               sieve_parser_error(parser, 
89390
 
+                                       "expecting ',' or end of string list ']', but found %s",
89391
 
+                                       sieve_lexer_token_string(lexer));
89392
 
+                       
89393
 
+                               if ( (result=sieve_parser_recover(parser, STT_RSQUARE)) == TRUE ) 
89394
 
+                                       sieve_lexer_skip_token(lexer);
89395
 
+                       }
89396
 
+       
89397
 
+                       break;
89398
 
+                       
89399
 
+               /* Single string */
89400
 
+               case STT_STRING: 
89401
 
+                       arg = sieve_ast_argument_string_create
89402
 
+                               (node, sieve_lexer_token_str(lexer), 
89403
 
+                                       sieve_lexer_current_line(parser->lexer));
89404
 
+
89405
 
+                       sieve_lexer_skip_token(lexer);
89406
 
+                       break;
89407
 
+               
89408
 
+               /* Number */
89409
 
+               case STT_NUMBER:
89410
 
+                       arg = sieve_ast_argument_number_create
89411
 
+                               (node, sieve_lexer_token_int(lexer), 
89412
 
+                                       sieve_lexer_current_line(parser->lexer));
89413
 
+                       sieve_lexer_skip_token(lexer);
89414
 
+                       break;
89415
 
+                       
89416
 
+               /* Tag */
89417
 
+               case STT_TAG:
89418
 
+                       arg = sieve_ast_argument_tag_create
89419
 
+                               (node, sieve_lexer_token_ident(lexer), 
89420
 
+                                       sieve_lexer_current_line(parser->lexer));
89421
 
+                       sieve_lexer_skip_token(lexer);
89422
 
+                       break;
89423
 
+                       
89424
 
+               /* End of argument list, continue with tests */
89425
 
+               default:
89426
 
+                       arg_present = FALSE;
89427
 
+                       break;
89428
 
+               }
89429
 
+
89430
 
+               if ( arg_present && arg == NULL ) {
89431
 
+                       sieve_parser_error(parser, 
89432
 
+                               "failed to accept more arguments for command '%s'", node->identifier);
89433
 
+                       return -1;
89434
 
+               }
89435
 
+
89436
 
+               if ( sieve_ast_argument_count(node) > SIEVE_MAX_COMMAND_ARGUMENTS ) {
89437
 
+                       sieve_parser_error(parser, 
89438
 
+                               "too many arguments for command '%s'", node->identifier);
89439
 
+                       return FALSE;
89440
 
+               }
89441
 
+       }
89442
 
+       
89443
 
+       if ( result <= 0 ) return result; /* Defer recovery to caller */
89444
 
+       
89445
 
+       /* --> [ test / test-list ] 
89446
 
+        * test-list = "(" test *("," test) ")"
89447
 
+        * test = identifier arguments
89448
 
+        */
89449
 
+       switch ( sieve_lexer_current_token(lexer) ) {
89450
 
+
89451
 
+       /* Single test */
89452
 
+       case STT_IDENTIFIER:
89453
 
+               if ( depth+1 > SIEVE_MAX_TEST_NESTING ) {
89454
 
+                       sieve_parser_error(parser, 
89455
 
+                               "cannot nest tests deeper than %u levels",
89456
 
+                               SIEVE_MAX_TEST_NESTING);
89457
 
+                       return FALSE;
89458
 
+               }
89459
 
+
89460
 
+               test = sieve_ast_test_create
89461
 
+                       (node, sieve_lexer_token_ident(lexer), 
89462
 
+                               sieve_lexer_current_line(parser->lexer));
89463
 
+               sieve_lexer_skip_token(lexer);
89464
 
+               
89465
 
+               /* Theoretically, test can be NULL */
89466
 
+               if ( test == NULL ) break;
89467
 
+
89468
 
+               /* Parse test arguments, which may include more tests (recurse) */
89469
 
+               if ( !sieve_parse_arguments(parser, test, depth+1) ) {
89470
 
+                       return FALSE; /* Defer recovery to caller */
89471
 
+               }
89472
 
+               
89473
 
+               break;
89474
 
+               
89475
 
+       /* Test list */
89476
 
+       case STT_LBRACKET:      
89477
 
+               sieve_lexer_skip_token(lexer);
89478
 
+
89479
 
+               if ( depth+1 > SIEVE_MAX_TEST_NESTING ) {
89480
 
+                       sieve_parser_error(parser, 
89481
 
+                               "cannot nest tests deeper than %u levels",
89482
 
+                               SIEVE_MAX_TEST_NESTING);
89483
 
+                       result = sieve_parser_recover(parser, STT_RBRACKET);
89484
 
+
89485
 
+                       if ( result ) sieve_lexer_skip_token(lexer);
89486
 
+                       return result;
89487
 
+               }
89488
 
+
89489
 
+               node->test_list = TRUE;
89490
 
+               
89491
 
+               /* Test starts with identifier */
89492
 
+               if ( sieve_lexer_current_token(lexer) == STT_IDENTIFIER ) {
89493
 
+                       test = sieve_ast_test_create
89494
 
+                               (node, sieve_lexer_token_ident(lexer), 
89495
 
+                                       sieve_lexer_current_line(parser->lexer));
89496
 
+                       sieve_lexer_skip_token(lexer);
89497
 
+               
89498
 
+                       if ( test == NULL ) break;
89499
 
+
89500
 
+                       /* Parse test arguments, which may include more tests (recurse) */
89501
 
+                       if ( (result=sieve_parse_arguments(parser, test, depth+1)) > 0 ) {
89502
 
+                       
89503
 
+                               /* More tests ? */
89504
 
+                               while ( sieve_lexer_current_token(lexer) == STT_COMMA && 
89505
 
+                                       (parser->valid && sieve_errors_more_allowed(parser->ehandler)) ) {
89506
 
+                                       sieve_lexer_skip_token(lexer);
89507
 
+                                       
89508
 
+                                       /* Test starts with identifier */
89509
 
+                                       if ( sieve_lexer_current_token(lexer) == STT_IDENTIFIER ) {
89510
 
+                                               test = sieve_ast_test_create
89511
 
+                                                       (node, sieve_lexer_token_ident(lexer), 
89512
 
+                                                               sieve_lexer_current_line(parser->lexer));
89513
 
+                                               sieve_lexer_skip_token(lexer);
89514
 
+
89515
 
+                                               if ( test == NULL ) break;
89516
 
+                                               
89517
 
+                                               /* Parse test arguments, which may include more tests (recurse) */
89518
 
+                                               if ( (result=sieve_parse_arguments(parser, test, depth+1)) <= 0 ) {
89519
 
+                                                       if ( result < 0 ) return result;
89520
 
+
89521
 
+                                                       result = sieve_parser_recover(parser, STT_RBRACKET);
89522
 
+                                                       break;
89523
 
+                                               }
89524
 
+                                       } else {
89525
 
+                                               sieve_parser_error(parser, 
89526
 
+                                                       "expecting test identifier after ',' in test list, but found %s",
89527
 
+                                                       sieve_lexer_token_string(lexer));
89528
 
+                                                                               
89529
 
+                                               result = sieve_parser_recover(parser, STT_RBRACKET);
89530
 
+                                               break;
89531
 
+                                       }
89532
 
+                               }
89533
 
+
89534
 
+                               if ( test == NULL ) break;
89535
 
+                       } else { 
89536
 
+                               if ( result < 0 ) return result;
89537
 
+
89538
 
+                               result = sieve_parser_recover(parser, STT_RBRACKET);
89539
 
+                       }
89540
 
+               } else {
89541
 
+                       sieve_parser_error(parser, 
89542
 
+                               "expecting test identifier after '(' in test list, but found %s",
89543
 
+                               sieve_lexer_token_string(lexer));
89544
 
+                       
89545
 
+                       result = sieve_parser_recover(parser, STT_RBRACKET);
89546
 
+               }
89547
 
+               
89548
 
+               /* The next token should be a ')', indicating the end of the test list
89549
 
+                *   --> previous sieve_parser_recover calls try to restore this situation 
89550
 
+                *       after parse errors.  
89551
 
+                */
89552
 
+               if ( sieve_lexer_current_token(lexer) == STT_RBRACKET ) {
89553
 
+                       sieve_lexer_skip_token(lexer);
89554
 
+               } else {
89555
 
+                       sieve_parser_error(parser, 
89556
 
+                               "expecting ',' or end of test list ')', but found %s",
89557
 
+                               sieve_lexer_token_string(lexer));
89558
 
+                       
89559
 
+                       /* Recover function tries to make next token equal to ')'. If it succeeds 
89560
 
+                        * we need to skip it.
89561
 
+                        */
89562
 
+                       if ( (result=sieve_parser_recover(parser, STT_RBRACKET)) == TRUE ) 
89563
 
+                               sieve_lexer_skip_token(lexer);
89564
 
+               }
89565
 
+               break;
89566
 
+               
89567
 
+       default:
89568
 
+               /* Not an error: test / test-list is optional
89569
 
+                *   --> any errors are detected by the caller  
89570
 
+                */
89571
 
+               test_present = FALSE;
89572
 
+               break;
89573
 
+       }
89574
 
+
89575
 
+       if ( test_present && test == NULL ) {
89576
 
+               sieve_parser_error(parser, 
89577
 
+                       "failed to accept more tests for command '%s'", node->identifier);
89578
 
+               return -1;
89579
 
+       }                       
89580
 
+       
89581
 
+       return result;
89582
 
+}
89583
 
+
89584
 
+/* commands = *command
89585
 
+ * command = identifier arguments ( ";" / block )
89586
 
+ * block = "{" commands "}"
89587
 
+ */
89588
 
+static int sieve_parse_commands
89589
 
+(struct sieve_parser *parser, struct sieve_ast_node *block, unsigned int depth) 
89590
 
+{ 
89591
 
+       struct sieve_lexer *lexer = parser->lexer;
89592
 
+       int result = TRUE;
89593
 
+
89594
 
+       while ( result > 0 && 
89595
 
+               sieve_lexer_current_token(lexer) == STT_IDENTIFIER && 
89596
 
+               (parser->valid || sieve_errors_more_allowed(parser->ehandler)) ) {
89597
 
+               struct sieve_ast_node *command = 
89598
 
+                       sieve_ast_command_create
89599
 
+                               (block, sieve_lexer_token_ident(lexer), 
89600
 
+                                       sieve_lexer_current_line(parser->lexer));
89601
 
+       
89602
 
+               if ( command == NULL ) {
89603
 
+                       sieve_parser_error(parser, 
89604
 
+                               "failed to accept more commands inside the block of command '%s'", 
89605
 
+                               block->identifier);
89606
 
+                       return -1;
89607
 
+               }
89608
 
+
89609
 
+               /* Defined state */
89610
 
+               result = TRUE;          
89611
 
+               
89612
 
+               sieve_lexer_skip_token(lexer);
89613
 
+               
89614
 
+               result = sieve_parse_arguments(parser, command, 1);
89615
 
+
89616
 
+               /* Check whether the command is properly terminated 
89617
 
+                * (i.e. with ; or a new block) 
89618
 
+                */
89619
 
+               if ( result > 0 &&
89620
 
+                       sieve_lexer_current_token(lexer) != STT_SEMICOLON &&
89621
 
+                       sieve_lexer_current_token(lexer) != STT_LCURLY ) {
89622
 
+                       
89623
 
+                       sieve_parser_error(parser, 
89624
 
+                               "expected end of command ';' or the beginning of a compound block '{', "
89625
 
+                               "but found %s",
89626
 
+                               sieve_lexer_token_string(lexer));       
89627
 
+                       result = FALSE;
89628
 
+               }
89629
 
+               
89630
 
+               /* Try to recover from parse errors to reacquire a defined state */
89631
 
+               if ( result == 0 ) {
89632
 
+                       result = sieve_parser_recover(parser, STT_SEMICOLON);
89633
 
+               }
89634
 
+
89635
 
+               /* Don't bother to continue if we are not in a defined state */
89636
 
+               if ( result <= 0 ) return result;
89637
 
+                       
89638
 
+               switch ( sieve_lexer_current_token(lexer) ) {
89639
 
+               
89640
 
+               /* End of the command */
89641
 
+               case STT_SEMICOLON:
89642
 
+                       sieve_lexer_skip_token(lexer);
89643
 
+                       break;
89644
 
+
89645
 
+               /* Command has a block {...} */         
89646
 
+               case STT_LCURLY:
89647
 
+                       sieve_lexer_skip_token(lexer);
89648
 
+                       
89649
 
+                       /* Check current depth first */
89650
 
+                       if ( depth+1 > SIEVE_MAX_BLOCK_NESTING ) {
89651
 
+                               sieve_parser_error(parser, 
89652
 
+                                       "cannot nest command blocks deeper than %u levels",
89653
 
+                                       SIEVE_MAX_BLOCK_NESTING);
89654
 
+                               result = sieve_parser_recover(parser, STT_RCURLY);
89655
 
+
89656
 
+                               if ( result > 0 )
89657
 
+                                       sieve_lexer_skip_token(lexer);
89658
 
+                               break;
89659
 
+                       }
89660
 
+
89661
 
+                       command->block = TRUE;
89662
 
+                       
89663
 
+                       if ( (result=sieve_parse_commands(parser, command, depth+1)) > 0 ) {
89664
 
+                       
89665
 
+                               if ( sieve_lexer_current_token(lexer) != STT_RCURLY ) {
89666
 
+                                       sieve_parser_error(parser, 
89667
 
+                                               "expected end of compound block '}', but found %s",
89668
 
+                                               sieve_lexer_token_string(lexer));
89669
 
+                                       result = sieve_parser_recover(parser, STT_RCURLY);                              
89670
 
+                               } else 
89671
 
+                                       sieve_lexer_skip_token(lexer);
89672
 
+                       } else {
89673
 
+                               if ( result < 0 ) return result;
89674
 
+
89675
 
+                               if ( (result=sieve_parser_recover(parser, STT_RCURLY)) == 0 ) 
89676
 
+                                       sieve_lexer_skip_token(lexer);
89677
 
+                       }
89678
 
+
89679
 
+                       break;
89680
 
+                       
89681
 
+               default:
89682
 
+                       /* Recovered previously, so this cannot happen */
89683
 
+                       i_unreached();
89684
 
+               }
89685
 
+       }
89686
 
+
89687
 
+       return result;
89688
 
+}
89689
 
+
89690
 
+bool sieve_parser_run
89691
 
+(struct sieve_parser *parser, struct sieve_ast **ast) 
89692
 
+{
89693
 
+       if ( parser->ast != NULL )
89694
 
+               sieve_ast_unref(&parser->ast);
89695
 
+       
89696
 
+       /* Create AST object if none is provided */
89697
 
+       if ( *ast == NULL )
89698
 
+               *ast = sieve_ast_create(parser->script);
89699
 
+       else 
89700
 
+               sieve_ast_ref(*ast);
89701
 
+               
89702
 
+       parser->ast = *ast;
89703
 
+
89704
 
+       /* Scan first token */
89705
 
+       sieve_lexer_skip_token(parser->lexer);
89706
 
+
89707
 
+       /* Parse */
89708
 
+       if ( sieve_parse_commands(parser, sieve_ast_root(parser->ast), 1) > 0 && 
89709
 
+               parser->valid ) {
89710
 
+                
89711
 
+               /* Parsed right to EOF ? */
89712
 
+               if ( sieve_lexer_current_token(parser->lexer) != STT_EOF ) { 
89713
 
+                       sieve_parser_error(parser, 
89714
 
+                               "unexpected %s found at (the presumed) end of file",
89715
 
+                               sieve_lexer_token_string(parser->lexer));
89716
 
+                       parser->valid = FALSE;
89717
 
+               }
89718
 
+       } else parser->valid = FALSE;
89719
 
+       
89720
 
+       /* Clean up AST if parse failed */
89721
 
+       if ( !parser->valid ) {
89722
 
+               parser->ast = NULL;
89723
 
+               sieve_ast_unref(ast);
89724
 
+       }
89725
 
+       
89726
 
+       return parser->valid;
89727
 
+}      
89728
 
+
89729
 
+/* Error recovery:
89730
 
+ *   To continue parsing after an error it is important to find the next 
89731
 
+ *   parsible item in the stream. The recover function skips over the remaining 
89732
 
+ *   garbage after an error. It tries  to find the end of the failed syntax 
89733
 
+ *   structure and takes nesting of structures into account. 
89734
 
+ */
89735
 
+
89736
 
+/* Assign useful names to priorities for readability */ 
89737
 
+enum sieve_grammatical_prio {
89738
 
+       SGP_BLOCK = 3,
89739
 
+       SGP_COMMAND = 2,
89740
 
+       SGP_TEST_LIST = 1,
89741
 
+       SGP_STRING_LIST = 0,
89742
 
+  
89743
 
+       SGP_OTHER = -1
89744
 
+};
89745
 
+
89746
 
+static inline enum sieve_grammatical_prio __get_token_priority
89747
 
+(enum sieve_token_type token) 
89748
 
+{
89749
 
+       switch ( token ) {
89750
 
+       case STT_LCURLY:
89751
 
+       case STT_RCURLY: 
89752
 
+               return SGP_BLOCK;
89753
 
+       case STT_SEMICOLON: 
89754
 
+               return SGP_COMMAND;
89755
 
+       case STT_LBRACKET:
89756
 
+       case STT_RBRACKET: 
89757
 
+               return SGP_TEST_LIST;
89758
 
+       case STT_LSQUARE:
89759
 
+       case STT_RSQUARE: 
89760
 
+               return SGP_STRING_LIST;
89761
 
+       default:
89762
 
+               break;
89763
 
+       }
89764
 
+       
89765
 
+       return SGP_OTHER;
89766
 
+}
89767
 
+
89768
 
+static int sieve_parser_recover
89769
 
+(struct sieve_parser *parser, enum sieve_token_type end_token) 
89770
 
+{
89771
 
+       /* The tokens that begin/end a specific block/command/list in order 
89772
 
+        * of ascending grammatical priority.
89773
 
+        */ 
89774
 
+       static const enum sieve_token_type begin_tokens[4] = 
89775
 
+               { STT_LSQUARE, STT_LBRACKET, STT_NONE, STT_LCURLY };
89776
 
+       static const enum sieve_token_type end_tokens[4] = 
89777
 
+               { STT_RSQUARE, STT_RBRACKET, STT_SEMICOLON, STT_RCURLY};
89778
 
+
89779
 
+       struct sieve_lexer *lexer = parser->lexer;
89780
 
+       int nesting = 1;
89781
 
+       enum sieve_grammatical_prio end_priority = __get_token_priority(end_token);
89782
 
+                       
89783
 
+       i_assert( end_priority != SGP_OTHER );
89784
 
+                       
89785
 
+       while ( sieve_lexer_current_token(lexer) != STT_EOF && 
89786
 
+               __get_token_priority(sieve_lexer_current_token(lexer)) <= end_priority ) {
89787
 
+                       
89788
 
+               if ( sieve_lexer_current_token(lexer) == begin_tokens[end_priority] ) {
89789
 
+                       nesting++;
89790
 
+                       sieve_lexer_skip_token(lexer);
89791
 
+                       continue;
89792
 
+               }
89793
 
+               
89794
 
+               if ( sieve_lexer_current_token(lexer) == end_tokens[end_priority] ) {
89795
 
+                       nesting--;
89796
 
+
89797
 
+                       if ( nesting == 0 ) {
89798
 
+                               /* Next character is the end */
89799
 
+                               return TRUE; 
89800
 
+                       }
89801
 
+               }
89802
 
+               
89803
 
+               sieve_lexer_skip_token(lexer);
89804
 
+       }
89805
 
+       
89806
 
+       /* Special case: COMMAND */
89807
 
+       if (end_token == STT_SEMICOLON && 
89808
 
+               sieve_lexer_current_token(lexer) == STT_LCURLY)
89809
 
+               return TRUE;
89810
 
+       
89811
 
+       /* End not found before eof or end of surrounding grammatical structure 
89812
 
+        */
89813
 
+       return FALSE; 
89814
 
+}
89815
 
+
89816
 
+
89817
 
+
89818
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-parser.h dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-parser.h
89819
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-parser.h 1970-01-01 01:00:00.000000000 +0100
89820
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-parser.h  2009-01-06 00:15:52.000000000 +0100
89821
 
@@ -0,0 +1,18 @@
89822
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file 
89823
 
+ */
89824
 
89825
 
+#ifndef __SIEVE_PARSER_H
89826
 
+#define __SIEVE_PARSER_H
89827
 
+
89828
 
+#include "lib.h"
89829
 
+
89830
 
+#include "sieve-common.h"
89831
 
+
89832
 
+struct sieve_parser;
89833
 
+
89834
 
+struct sieve_parser *sieve_parser_create
89835
 
+       (struct sieve_script *script, struct sieve_error_handler *ehandler);
89836
 
+void sieve_parser_free(struct sieve_parser **parser);
89837
 
+bool sieve_parser_run(struct sieve_parser *parser, struct sieve_ast **ast);
89838
 
+
89839
 
+#endif /* __SIEVE_PARSER_H */
89840
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-result.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-result.c
89841
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-result.c 1970-01-01 01:00:00.000000000 +0100
89842
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-result.c  2009-08-02 10:21:02.000000000 +0200
89843
 
@@ -0,0 +1,1199 @@
89844
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
89845
 
+ */
89846
 
89847
 
+#include "lib.h"
89848
 
+#include "mempool.h"
89849
 
+#include "ostream.h"
89850
 
+#include "hash.h"
89851
 
+#include "str.h"
89852
 
+#include "strfuncs.h"
89853
 
+#include "str-sanitize.h"
89854
 
+
89855
 
+#include "sieve-common.h"
89856
 
+#include "sieve-limits.h"
89857
 
+#include "sieve-script.h"
89858
 
+#include "sieve-error.h"
89859
 
+#include "sieve-interpreter.h"
89860
 
+#include "sieve-actions.h"
89861
 
+#include "sieve-message.h"
89862
 
+
89863
 
+#include "sieve-result.h"
89864
 
+
89865
 
+#include <stdio.h>
89866
 
+
89867
 
+/*
89868
 
+ * Types
89869
 
+ */
89870
 
89871
 
+struct sieve_result_action {
89872
 
+       struct sieve_result *result;
89873
 
+       struct sieve_action_data data;
89874
 
+       
89875
 
+       void *tr_context;
89876
 
+       bool success;
89877
 
+       
89878
 
+       bool keep;
89879
 
+
89880
 
+       struct sieve_side_effects_list *seffects;
89881
 
+       
89882
 
+       struct sieve_result_action *prev, *next; 
89883
 
+};
89884
 
+
89885
 
+struct sieve_side_effects_list {
89886
 
+       struct sieve_result *result;
89887
 
+
89888
 
+       struct sieve_result_side_effect *first_effect;
89889
 
+       struct sieve_result_side_effect *last_effect;
89890
 
+};
89891
 
+
89892
 
+struct sieve_result_side_effect {
89893
 
+       const struct sieve_side_effect *seffect;
89894
 
+       void *context;
89895
 
+       struct sieve_result_side_effect *prev, *next; 
89896
 
+};
89897
 
+
89898
 
+struct sieve_result_action_context {
89899
 
+       const struct sieve_action *action;
89900
 
+       struct sieve_side_effects_list *seffects;
89901
 
+};
89902
 
+
89903
 
+/*
89904
 
+ * Result object
89905
 
+ */
89906
 
+
89907
 
+struct sieve_result {
89908
 
+       pool_t pool;
89909
 
+       int refcount;
89910
 
+
89911
 
+       /* Context data for extensions */
89912
 
+       ARRAY_DEFINE(ext_contexts, void *); 
89913
 
+
89914
 
+       struct sieve_error_handler *ehandler;
89915
 
+               
89916
 
+       struct sieve_action_exec_env action_env;
89917
 
+       
89918
 
+       const struct sieve_action *keep_action;
89919
 
+       const struct sieve_action *failure_action;
89920
 
+
89921
 
+       unsigned int action_count;
89922
 
+       struct sieve_result_action *first_action;
89923
 
+       struct sieve_result_action *last_action;
89924
 
+       
89925
 
+       struct sieve_result_action *last_attempted_action;
89926
 
+       
89927
 
+       struct hash_table *action_contexts;
89928
 
+};
89929
 
+
89930
 
+struct sieve_result *sieve_result_create
89931
 
+(const struct sieve_message_data *msgdata, const struct sieve_script_env *senv,
89932
 
+       struct sieve_error_handler *ehandler)
89933
 
+{
89934
 
+       pool_t pool;
89935
 
+       struct sieve_result *result;
89936
 
+        
89937
 
+       pool = pool_alloconly_create("sieve_result", 4096);     
89938
 
+       result = p_new(pool, struct sieve_result, 1);
89939
 
+       result->refcount = 1;
89940
 
+       result->pool = pool;
89941
 
+       
89942
 
+       p_array_init(&result->ext_contexts, pool, 4);
89943
 
+
89944
 
+       if ( ehandler != NULL )
89945
 
+               sieve_error_handler_ref(ehandler);      
89946
 
+       result->ehandler = ehandler;
89947
 
+
89948
 
+       result->action_env.result = result;
89949
 
+       result->action_env.scriptenv = senv;
89950
 
+       result->action_env.msgdata = msgdata;
89951
 
+       result->action_env.msgctx = sieve_message_context_create(msgdata); 
89952
 
+               
89953
 
+       result->keep_action = &act_store;
89954
 
+       result->failure_action = &act_store;
89955
 
+       
89956
 
+       result->action_count = 0;
89957
 
+       result->first_action = NULL;
89958
 
+       result->last_action = NULL;
89959
 
+
89960
 
+       result->action_contexts = NULL;
89961
 
+       return result;
89962
 
+}
89963
 
+
89964
 
+void sieve_result_ref(struct sieve_result *result) 
89965
 
+{
89966
 
+       result->refcount++;
89967
 
+}
89968
 
+
89969
 
+void sieve_result_unref(struct sieve_result **result) 
89970
 
+{
89971
 
+       i_assert((*result)->refcount > 0);
89972
 
+
89973
 
+       if (--(*result)->refcount != 0)
89974
 
+               return;
89975
 
+
89976
 
+       sieve_message_context_unref(&(*result)->action_env.msgctx);
89977
 
+
89978
 
+       if ( (*result)->action_contexts != NULL )
89979
 
+        hash_table_destroy(&(*result)->action_contexts);
89980
 
+
89981
 
+       if ( (*result)->ehandler != NULL )
89982
 
+               sieve_error_handler_unref(&(*result)->ehandler);
89983
 
+
89984
 
+       pool_unref(&(*result)->pool);
89985
 
+
89986
 
+       *result = NULL;
89987
 
+}
89988
 
+
89989
 
+pool_t sieve_result_pool(struct sieve_result *result)
89990
 
+{
89991
 
+       return result->pool;
89992
 
+}
89993
 
+
89994
 
+/*
89995
 
+ * Getters/Setters
89996
 
+ */
89997
 
+
89998
 
+struct sieve_error_handler *sieve_result_get_error_handler
89999
 
+(struct sieve_result *result)
90000
 
+{
90001
 
+       return result->ehandler;
90002
 
+}
90003
 
+const struct sieve_script_env *sieve_result_get_script_env
90004
 
+(struct sieve_result *result)
90005
 
+{
90006
 
+    return result->action_env.scriptenv;
90007
 
+}
90008
 
+
90009
 
+const struct sieve_message_data *sieve_result_get_message_data
90010
 
+(struct sieve_result *result)
90011
 
+{
90012
 
+       return result->action_env.msgdata;
90013
 
+}
90014
 
+
90015
 
+struct sieve_message_context *sieve_result_get_message_context
90016
 
+(struct sieve_result *result)
90017
 
+{
90018
 
+       return result->action_env.msgctx;
90019
 
+}
90020
 
+
90021
 
+void sieve_result_set_error_handler
90022
 
+(struct sieve_result *result, struct sieve_error_handler *ehandler)
90023
 
+{
90024
 
+       if ( result->ehandler != ehandler ) {
90025
 
+               sieve_error_handler_ref(ehandler);
90026
 
+               sieve_error_handler_unref(&result->ehandler);
90027
 
+               result->ehandler = ehandler;
90028
 
+       }
90029
 
+}
90030
 
+
90031
 
+/*
90032
 
+ * Extension support
90033
 
+ */
90034
 
+
90035
 
+void sieve_result_extension_set_context
90036
 
+(struct sieve_result *result, const struct sieve_extension *ext, void *context)
90037
 
+{
90038
 
+       array_idx_set(&result->ext_contexts, (unsigned int) SIEVE_EXT_ID(ext), 
90039
 
+               &context);      
90040
 
+}
90041
 
+
90042
 
+const void *sieve_result_extension_get_context
90043
 
+(struct sieve_result *result, const struct sieve_extension *ext) 
90044
 
+{
90045
 
+       int ext_id = SIEVE_EXT_ID(ext);
90046
 
+       void * const *ctx;
90047
 
+
90048
 
+       if  ( ext_id < 0 || ext_id >= (int) array_count(&result->ext_contexts) )
90049
 
+               return NULL;
90050
 
+       
90051
 
+       ctx = array_idx(&result->ext_contexts, (unsigned int) ext_id);          
90052
 
+
90053
 
+       return *ctx;
90054
 
+}
90055
 
+
90056
 
+/* 
90057
 
+ * Error handling 
90058
 
+ */
90059
 
+
90060
 
+void sieve_result_error
90061
 
+       (const struct sieve_action_exec_env *aenv, const char *fmt, ...)
90062
 
+{
90063
 
+       va_list args;
90064
 
+       
90065
 
+       if ( aenv->result->ehandler == NULL ) return;
90066
 
+
90067
 
+       va_start(args, fmt);    
90068
 
+       sieve_verror(aenv->result->ehandler, sieve_action_get_location(aenv), fmt, 
90069
 
+               args); 
90070
 
+       va_end(args);
90071
 
+}
90072
 
+
90073
 
+void sieve_result_warning
90074
 
+       (const struct sieve_action_exec_env *aenv, const char *fmt, ...)
90075
 
+{
90076
 
+       va_list args;
90077
 
+
90078
 
+       if ( aenv->result->ehandler == NULL ) return;
90079
 
+       
90080
 
+       va_start(args, fmt);    
90081
 
+       sieve_vwarning(aenv->result->ehandler, sieve_action_get_location(aenv), fmt, 
90082
 
+               args); 
90083
 
+       va_end(args);
90084
 
+}
90085
 
+
90086
 
+void sieve_result_log
90087
 
+       (const struct sieve_action_exec_env *aenv, const char *fmt, ...)
90088
 
+{
90089
 
+       va_list args;
90090
 
+       
90091
 
+       if ( aenv->result->ehandler == NULL ) return;
90092
 
+
90093
 
+       va_start(args, fmt);    
90094
 
+       sieve_vinfo(aenv->result->ehandler, sieve_action_get_location(aenv), fmt, 
90095
 
+               args); 
90096
 
+       va_end(args);
90097
 
+}
90098
 
+
90099
 
+/* 
90100
 
+ * Result composition 
90101
 
+ */
90102
 
+
90103
 
+void sieve_result_add_implicit_side_effect
90104
 
+(struct sieve_result *result, const struct sieve_action *to_action, 
90105
 
+       const struct sieve_side_effect *seffect, void *context)
90106
 
+{
90107
 
+       struct sieve_result_action_context *actctx = NULL;
90108
 
+       
90109
 
+       if ( result->action_contexts == NULL ) {
90110
 
+               result->action_contexts = hash_table_create
90111
 
+                       (default_pool, result->pool, 0, NULL, NULL);
90112
 
+       } else {
90113
 
+               actctx = (struct sieve_result_action_context *) 
90114
 
+                       hash_table_lookup(result->action_contexts, to_action);
90115
 
+       }
90116
 
+
90117
 
+       if ( actctx == NULL ) {
90118
 
+               actctx = p_new
90119
 
+                       (result->pool, struct sieve_result_action_context, 1);
90120
 
+               actctx->action = to_action;
90121
 
+               actctx->seffects = sieve_side_effects_list_create(result);
90122
 
+               
90123
 
+               hash_table_insert(result->action_contexts, (void *) to_action, 
90124
 
+                       (void *) actctx);
90125
 
+       }       
90126
 
+       
90127
 
+       sieve_side_effects_list_add(actctx->seffects, seffect, context);
90128
 
+}
90129
 
+
90130
 
+static int sieve_result_side_effects_merge
90131
 
+(const struct sieve_runtime_env *renv, const struct sieve_action *action, 
90132
 
+       struct sieve_side_effects_list *old_seffects,
90133
 
+       struct sieve_side_effects_list *new_seffects)
90134
 
+{
90135
 
+       int ret;
90136
 
+       struct sieve_result_side_effect *rsef, *nrsef;
90137
 
+
90138
 
+       /* Allow side-effects to merge with existing copy */
90139
 
+               
90140
 
+       /* Merge existing side effects */
90141
 
+       rsef = old_seffects != NULL ? old_seffects->first_effect : NULL;
90142
 
+       while ( rsef != NULL ) {
90143
 
+               const struct sieve_side_effect *seffect = rsef->seffect;
90144
 
+               bool found = FALSE;
90145
 
+               
90146
 
+               if ( seffect->merge != NULL ) {
90147
 
+
90148
 
+                       /* Try to find it among the new */
90149
 
+                       nrsef = new_seffects != NULL ? new_seffects->first_effect : NULL;
90150
 
+                       while ( nrsef != NULL ) {
90151
 
+                               if ( nrsef->seffect == seffect ) {
90152
 
+                                       if ( seffect->merge
90153
 
+                                               (renv, action, seffect, &rsef->context, nrsef->context) < 0 )
90154
 
+                                               return -1;
90155
 
+                       
90156
 
+                                       found = TRUE;
90157
 
+                                       break;
90158
 
+                               }
90159
 
+               
90160
 
+                               nrsef = nrsef->next;
90161
 
+                       }
90162
 
+       
90163
 
+                       /* Not found? */
90164
 
+                       if ( !found && seffect->merge
90165
 
+                               (renv, action, seffect, &rsef->context, NULL) < 0 )
90166
 
+                               return -1;
90167
 
+               }
90168
 
+       
90169
 
+               rsef = rsef->next;
90170
 
+       }
90171
 
+
90172
 
+       /* Merge new Side effects */
90173
 
+       nrsef = new_seffects != NULL ? new_seffects->first_effect : NULL;
90174
 
+       while ( nrsef != NULL ) {
90175
 
+               const struct sieve_side_effect *seffect = nrsef->seffect;
90176
 
+               bool found = FALSE;
90177
 
+               
90178
 
+               if ( seffect->merge != NULL ) {
90179
 
+               
90180
 
+                       /* Try to find it among the exising */
90181
 
+                       rsef = old_seffects != NULL ? old_seffects->first_effect : NULL;
90182
 
+                       while ( rsef != NULL ) {
90183
 
+                               if ( rsef->seffect == seffect ) {
90184
 
+                                       found = TRUE;
90185
 
+                                       break;
90186
 
+                               }
90187
 
+                               rsef = rsef->next;
90188
 
+                       }
90189
 
+       
90190
 
+                       /* Not found? */
90191
 
+                       if ( !found ) {
90192
 
+                               void *new_context = NULL; 
90193
 
+               
90194
 
+                               if ( (ret=seffect->merge
90195
 
+                                       (renv, action, seffect, &new_context, nrsef->context)) < 0 ) 
90196
 
+                                       return -1;
90197
 
+                                       
90198
 
+                               if ( ret != 0 ) {
90199
 
+                                       /* Add side effect */
90200
 
+                                       sieve_side_effects_list_add(old_seffects, seffect, new_context);
90201
 
+                               }
90202
 
+                       }
90203
 
+               }
90204
 
+       
90205
 
+               nrsef = nrsef->next;
90206
 
+       }
90207
 
+       
90208
 
+       return 1;
90209
 
+}
90210
 
+
90211
 
+static void sieve_result_action_detach(struct sieve_result_action *raction)
90212
 
+{
90213
 
+       struct sieve_result *result = raction->result;
90214
 
+       
90215
 
+       if ( result->first_action == raction ) 
90216
 
+               result->first_action = raction->next;
90217
 
+               
90218
 
+       if ( result->last_action == raction ) 
90219
 
+               result->last_action = raction->prev;
90220
 
+               
90221
 
+       if ( raction->next != NULL ) raction->next->prev = raction->prev;
90222
 
+       if ( raction->prev != NULL ) raction->prev->next = raction->next;
90223
 
+       
90224
 
+       raction->next = NULL;
90225
 
+       raction->prev = NULL;
90226
 
+       
90227
 
+       if ( result->action_count > 0 )
90228
 
+               result->action_count--;
90229
 
+}
90230
 
+
90231
 
+static int _sieve_result_add_action
90232
 
+(const struct sieve_runtime_env *renv,
90233
 
+       const struct sieve_action *action, struct sieve_side_effects_list *seffects,
90234
 
+       unsigned int source_line, void *context, unsigned int instance_limit, 
90235
 
+       bool keep)              
90236
 
+{
90237
 
+       int ret = 0;
90238
 
+       unsigned int instance_count = 0;
90239
 
+       struct sieve_result *result = renv->result;
90240
 
+       struct sieve_result_action *raction = NULL, *kaction = NULL;
90241
 
+       struct sieve_action_data act_data;
90242
 
+                       
90243
 
+       act_data.action = action;
90244
 
+       act_data.location = sieve_error_script_location(renv->script, source_line);
90245
 
+       act_data.context = context;
90246
 
+       act_data.executed = FALSE;
90247
 
+               
90248
 
+       /* First, check for duplicates or conflicts */
90249
 
+       raction = result->first_action;
90250
 
+       while ( raction != NULL ) {
90251
 
+               const struct sieve_action *oact = raction->data.action;
90252
 
+               
90253
 
+               if ( keep && raction->keep ) {
90254
 
+               
90255
 
+                       /* Duplicate keep */
90256
 
+                       if ( raction->data.executed ) {
90257
 
+                               /* Keep action from preceeding execution */
90258
 
+                       
90259
 
+                               /* Detach existing keep action */
90260
 
+                               sieve_result_action_detach(raction);
90261
 
+
90262
 
+                               /* Merge existing side-effects with new keep action */
90263
 
+                               if ( kaction == NULL )
90264
 
+                                       kaction = raction;
90265
 
+                       
90266
 
+                               if ( (ret=sieve_result_side_effects_merge
90267
 
+                                       (renv, action, kaction->seffects, seffects)) <= 0 )      
90268
 
+                                       return ret;                             
90269
 
+                       } else {
90270
 
+                               /* True duplicate */
90271
 
+                               
90272
 
+                               return sieve_result_side_effects_merge
90273
 
+                                       (renv, action, raction->seffects, seffects);
90274
 
+                       }
90275
 
+                       
90276
 
+               } if ( raction->data.action == action ) {
90277
 
+                       instance_count++;
90278
 
+
90279
 
+                       /* Possible duplicate */
90280
 
+                       if ( action->check_duplicate != NULL ) {
90281
 
+                               if ( (ret=action->check_duplicate(renv, &act_data, &raction->data)) 
90282
 
+                                       < 0 )
90283
 
+                                       return ret;
90284
 
+                               
90285
 
+                               /* Duplicate */ 
90286
 
+                               if ( ret == 1 ) {
90287
 
+                                       if ( keep && !raction->keep ) {
90288
 
+                                               /* New keep has higher precedence than existing duplicate non-keep 
90289
 
+                                                * action. So, take over the result action object and transform it
90290
 
+                                                * into a keep.
90291
 
+                                                */
90292
 
+                                                
90293
 
+                                               if ( (ret=sieve_result_side_effects_merge
90294
 
+                                                       (renv, action, raction->seffects, seffects)) < 0 ) 
90295
 
+                                                       return ret;
90296
 
+                                                
90297
 
+                                               if ( kaction == NULL ) {                                                                
90298
 
+                                                       raction->data.context = NULL;
90299
 
+                                                       raction->data.location = p_strdup(result->pool, act_data.location);
90300
 
+                                                       
90301
 
+                                                       /* Note that existing execution status is retained, making sure 
90302
 
+                                                        * that keep is not executed multiple times.
90303
 
+                                                        */
90304
 
+                                                       
90305
 
+                                                       kaction = raction;
90306
 
+                                                                                               
90307
 
+                                               } else {
90308
 
+                                                       sieve_result_action_detach(raction);
90309
 
+
90310
 
+                                                       if ( (ret=sieve_result_side_effects_merge
90311
 
+                                                               (renv, action, kaction->seffects, raction->seffects)) < 0 ) 
90312
 
+                                                               return ret;
90313
 
+                                               }
90314
 
+                                       } else {
90315
 
+                                               /* Merge side-effects, but don't add new action */
90316
 
+                                               return sieve_result_side_effects_merge
90317
 
+                                                       (renv, action, raction->seffects, seffects);
90318
 
+                                       }
90319
 
+                               }
90320
 
+                       }
90321
 
+               } else {
90322
 
+                       if ( action != NULL && oact != NULL ) {
90323
 
+                               /* Check conflict */
90324
 
+                               if ( action->check_conflict != NULL &&
90325
 
+                                       (ret=action->check_conflict(renv, &act_data, &raction->data)) != 0 ) 
90326
 
+                                       return ret;
90327
 
+                       
90328
 
+                               if ( !raction->data.executed && oact->check_conflict != NULL &&
90329
 
+                                       (ret=oact->check_conflict(renv, &raction->data, &act_data)) != 0 )
90330
 
+                                       return ret;
90331
 
+                       }
90332
 
+               }
90333
 
+               raction = raction->next;
90334
 
+       }
90335
 
+
90336
 
+       /* Check policy limit on total number of actions */
90337
 
+       if ( sieve_max_actions > 0 && result->action_count >= sieve_max_actions ) {
90338
 
+               sieve_runtime_error(renv, act_data.location, 
90339
 
+                       "total number of actions exceeds policy limit");
90340
 
+               return -1;
90341
 
+       }
90342
 
+
90343
 
+       /* Check policy limit on number of this class of actions */
90344
 
+       if ( instance_limit > 0 && instance_count >= instance_limit ) {
90345
 
+               sieve_runtime_error(renv, act_data.location, 
90346
 
+                       "number of %s actions exceeds policy limit", action->name);
90347
 
+               return -1;
90348
 
+       }       
90349
 
+               
90350
 
+       if ( kaction != NULL )
90351
 
+               /* Use existing keep action to define new one */
90352
 
+               raction = kaction;
90353
 
+       else {
90354
 
+               /* Create new action object */
90355
 
+               raction = p_new(result->pool, struct sieve_result_action, 1);
90356
 
+               raction->data.executed = FALSE;
90357
 
+               raction->result = result;
90358
 
+               raction->seffects = seffects;
90359
 
+               raction->tr_context = NULL;
90360
 
+               raction->success = FALSE;
90361
 
+       }
90362
 
+       
90363
 
+       raction->data.context = context;
90364
 
+       raction->data.action = action;
90365
 
+       raction->data.location = p_strdup(result->pool, act_data.location);
90366
 
+       raction->keep = keep;
90367
 
+
90368
 
+       if ( raction->prev == NULL ) {
90369
 
+               /* Add */
90370
 
+               if ( result->first_action == NULL ) {
90371
 
+                       result->first_action = raction;
90372
 
+                       result->last_action = raction;
90373
 
+                       raction->prev = NULL;
90374
 
+                       raction->next = NULL;
90375
 
+               } else {
90376
 
+                       result->last_action->next = raction;
90377
 
+                       raction->prev = result->last_action;
90378
 
+                       result->last_action = raction;
90379
 
+                       raction->next = NULL;
90380
 
+               }
90381
 
+               result->action_count++;
90382
 
+       
90383
 
+               /* Apply any implicit side effects */
90384
 
+               if ( result->action_contexts != NULL ) {
90385
 
+                       struct sieve_result_action_context *actctx;
90386
 
+               
90387
 
+                       /* Check for implicit side effects to this particular action */
90388
 
+                       actctx = (struct sieve_result_action_context *) 
90389
 
+                                       hash_table_lookup(result->action_contexts, action);
90390
 
+               
90391
 
+                       if ( actctx != NULL ) {
90392
 
+                               struct sieve_result_side_effect *iseff;
90393
 
+                       
90394
 
+                               /* Iterate through all implicit side effects and add those that are 
90395
 
+                                * missing.
90396
 
+                                */
90397
 
+                               iseff = actctx->seffects->first_effect;
90398
 
+                               while ( iseff != NULL ) {
90399
 
+                                       struct sieve_result_side_effect *seff;
90400
 
+                                       bool exists = FALSE;
90401
 
+                               
90402
 
+                                       /* Scan for presence */
90403
 
+                                       if ( seffects != NULL ) {
90404
 
+                                               seff = seffects->first_effect;
90405
 
+                                               while ( seff != NULL ) {
90406
 
+                                                       if ( seff->seffect == iseff->seffect ) {
90407
 
+                                                               exists = TRUE;
90408
 
+                                                               break;
90409
 
+                                                       }
90410
 
+                                       
90411
 
+                                                       seff = seff->next;
90412
 
+                                               }
90413
 
+                                       } else {
90414
 
+                                               raction->seffects = seffects = 
90415
 
+                                                       sieve_side_effects_list_create(result);
90416
 
+                                       }
90417
 
+                               
90418
 
+                                       /* If not present, add it */
90419
 
+                                       if ( !exists ) {
90420
 
+                                               sieve_side_effects_list_add
90421
 
+                                                       (seffects, iseff->seffect, iseff->context);
90422
 
+                                       }
90423
 
+                               
90424
 
+                                       iseff = iseff->next;
90425
 
+                               }
90426
 
+                       }
90427
 
+               }
90428
 
+       }
90429
 
+       
90430
 
+       return 0;
90431
 
+}
90432
 
+
90433
 
+int sieve_result_add_action
90434
 
+(const struct sieve_runtime_env *renv,
90435
 
+       const struct sieve_action *action, struct sieve_side_effects_list *seffects,
90436
 
+       unsigned int source_line, void *context, unsigned int instance_limit)
90437
 
+{
90438
 
+       return _sieve_result_add_action
90439
 
+               (renv, action, seffects, source_line, context, instance_limit, FALSE);
90440
 
+}
90441
 
+
90442
 
+int sieve_result_add_keep
90443
 
+(const struct sieve_runtime_env *renv, struct sieve_side_effects_list *seffects,
90444
 
+       unsigned int source_line)
90445
 
+{
90446
 
+       return _sieve_result_add_action
90447
 
+               (renv, renv->result->keep_action, seffects, source_line, NULL, 0, TRUE);
90448
 
+}
90449
 
+
90450
 
+void sieve_result_set_keep_action
90451
 
+(struct sieve_result *result, const struct sieve_action *action)
90452
 
+{
90453
 
+       result->keep_action = action;
90454
 
+}
90455
 
+
90456
 
+void sieve_result_set_failure_action
90457
 
+(struct sieve_result *result, const struct sieve_action *action)
90458
 
+{
90459
 
+       result->failure_action = action;
90460
 
+}
90461
 
+
90462
 
+/*
90463
 
+ * Result printing
90464
 
+ */
90465
 
+
90466
 
+void sieve_result_vprintf
90467
 
+(const struct sieve_result_print_env *penv, const char *fmt, va_list args)
90468
 
+{      
90469
 
+       string_t *outbuf = t_str_new(128);
90470
 
+
90471
 
+       str_vprintfa(outbuf, fmt, args);
90472
 
+       
90473
 
+       o_stream_send(penv->stream, str_data(outbuf), str_len(outbuf));
90474
 
+}
90475
 
+
90476
 
+void sieve_result_printf
90477
 
+(const struct sieve_result_print_env *penv, const char *fmt, ...)
90478
 
+{      
90479
 
+       va_list args;
90480
 
+       
90481
 
+       va_start(args, fmt);    
90482
 
+       sieve_result_vprintf(penv, fmt, args);
90483
 
+       va_end(args);   
90484
 
+}
90485
 
+
90486
 
+void sieve_result_action_printf
90487
 
+(const struct sieve_result_print_env *penv, const char *fmt, ...)
90488
 
+{      
90489
 
+       string_t *outbuf = t_str_new(128);
90490
 
+       va_list args;
90491
 
+       
90492
 
+       va_start(args, fmt);    
90493
 
+       str_append(outbuf, " * ");
90494
 
+       str_vprintfa(outbuf, fmt, args);
90495
 
+       str_append_c(outbuf, '\n');
90496
 
+       va_end(args);
90497
 
+       
90498
 
+       o_stream_send(penv->stream, str_data(outbuf), str_len(outbuf));
90499
 
+}
90500
 
+
90501
 
+void sieve_result_seffect_printf
90502
 
+(const struct sieve_result_print_env *penv, const char *fmt, ...)
90503
 
+{      
90504
 
+       string_t *outbuf = t_str_new(128);
90505
 
+       va_list args;
90506
 
+       
90507
 
+       va_start(args, fmt);    
90508
 
+       str_append(outbuf, "        + ");
90509
 
+       str_vprintfa(outbuf, fmt, args);
90510
 
+       str_append_c(outbuf, '\n');
90511
 
+       va_end(args);
90512
 
+       
90513
 
+       o_stream_send(penv->stream, str_data(outbuf), str_len(outbuf));
90514
 
+}
90515
 
+
90516
 
+static void sieve_result_print_side_effect
90517
 
+(struct sieve_result_print_env *rpenv, const struct sieve_action *action,
90518
 
+       struct sieve_side_effects_list *slist, bool *implicit_keep)
90519
 
+{
90520
 
+       struct sieve_result_side_effect *rsef;
90521
 
+       const struct sieve_side_effect *sef;
90522
 
+       
90523
 
+       /* Print side effects */
90524
 
+       rsef = slist != NULL ? slist->first_effect : NULL;
90525
 
+       while ( rsef != NULL ) {
90526
 
+               sef = rsef->seffect;
90527
 
+               if ( sef->print != NULL ) 
90528
 
+                       sef->print(sef, action, rpenv, rsef->context, implicit_keep);
90529
 
+               rsef = rsef->next;
90530
 
+       }
90531
 
+}
90532
 
+
90533
 
+bool sieve_result_print
90534
 
+(struct sieve_result *result, const struct sieve_script_env *senv, 
90535
 
+       struct ostream *stream, bool *keep)
90536
 
+{
90537
 
+       const struct sieve_action *act_keep = result->keep_action;
90538
 
+       struct sieve_result_print_env penv;
90539
 
+       bool implicit_keep = TRUE;
90540
 
+       struct sieve_result_action *rac, *first_action;
90541
 
+       
90542
 
+       first_action = ( result->last_attempted_action == NULL ?
90543
 
+               result->first_action : result->last_attempted_action->next );
90544
 
+       
90545
 
+       if ( keep != NULL ) *keep = FALSE;
90546
 
+       
90547
 
+       /* Prepare environment */
90548
 
+       
90549
 
+       penv.result = result;
90550
 
+       penv.stream = stream;
90551
 
+       penv.scriptenv = senv;
90552
 
+       
90553
 
+       sieve_result_printf(&penv, "\nPerformed actions:\n\n");
90554
 
+       
90555
 
+       if ( first_action == NULL ) {
90556
 
+               sieve_result_printf(&penv, "  (none)\n");
90557
 
+       } else {                
90558
 
+               rac = first_action;
90559
 
+               while ( rac != NULL ) {         
90560
 
+                       bool impl_keep = TRUE;
90561
 
+                       const struct sieve_action *act = rac->data.action;
90562
 
+
90563
 
+                       if ( rac->keep && keep != NULL ) *keep = TRUE;
90564
 
+
90565
 
+                       if ( act != NULL ) {
90566
 
+                               if ( act->print != NULL )
90567
 
+                                       act->print(act, &penv, rac->data.context, &impl_keep);
90568
 
+                               else
90569
 
+                                       sieve_result_action_printf(&penv, "%s", act->name); 
90570
 
+                       } else {
90571
 
+                               if ( rac->keep ) {
90572
 
+                                       sieve_result_action_printf(&penv, "keep");
90573
 
+                                       impl_keep = FALSE;
90574
 
+                               } else {
90575
 
+                                       sieve_result_action_printf(&penv, "[NULL]");
90576
 
+                               }
90577
 
+                       }
90578
 
+       
90579
 
+                       /* Print side effects */
90580
 
+                       sieve_result_print_side_effect
90581
 
+                               (&penv, rac->data.action, rac->seffects, &impl_keep);
90582
 
+                       
90583
 
+                       implicit_keep = implicit_keep && impl_keep;             
90584
 
+               
90585
 
+                       rac = rac->next;        
90586
 
+               }
90587
 
+       }
90588
 
+       
90589
 
+       if ( implicit_keep && keep != NULL ) *keep = TRUE;
90590
 
+               
90591
 
+       sieve_result_printf(&penv, "\nImplicit keep:\n\n");
90592
 
+               
90593
 
+       if ( implicit_keep ) {
90594
 
+               bool dummy = TRUE;
90595
 
+                       
90596
 
+               if ( act_keep == NULL ) 
90597
 
+                       sieve_result_action_printf(&penv, "keep");
90598
 
+               else {
90599
 
+                       /* Scan for execution of keep-equal actions */  
90600
 
+                       rac = result->first_action;
90601
 
+                       while ( act_keep != NULL && rac != NULL ) {
90602
 
+                               if ( rac->data.action == act_keep && act_keep->equals != NULL && 
90603
 
+                                       act_keep->equals(senv, NULL, rac->data.context) 
90604
 
+                                               && rac->data.executed ) {
90605
 
+                                       act_keep = NULL;
90606
 
+                               }
90607
 
+                       
90608
 
+                               rac = rac->next;        
90609
 
+                       }
90610
 
+                       
90611
 
+                       if ( act_keep == NULL ) {
90612
 
+                               sieve_result_printf(&penv, 
90613
 
+                                       "  (none; keep or equivalent action executed earlier)\n");
90614
 
+                       } else {
90615
 
+                               act_keep->print(act_keep, &penv, NULL, &dummy);
90616
 
+                       
90617
 
+                               /* Apply any implicit side effects if applicable */
90618
 
+                               if ( result->action_contexts != NULL ) {
90619
 
+                                       struct sieve_result_action_context *actctx;
90620
 
+               
90621
 
+                                       /* Check for implicit side effects to keep action */
90622
 
+                                       actctx = (struct sieve_result_action_context *) 
90623
 
+                                                       hash_table_lookup(result->action_contexts, act_keep);
90624
 
+               
90625
 
+                                       if ( actctx != NULL && actctx->seffects != NULL ) 
90626
 
+                                               sieve_result_print_side_effect
90627
 
+                                                       (&penv, act_keep, actctx->seffects, &dummy);
90628
 
+                               }
90629
 
+                       }
90630
 
+               }
90631
 
+       } else 
90632
 
+               sieve_result_printf(&penv, "  (none)\n");
90633
 
+       
90634
 
+       sieve_result_printf(&penv, "\n");
90635
 
+       
90636
 
+       return TRUE;
90637
 
+}
90638
 
+
90639
 
+/*
90640
 
+ * Result execution
90641
 
+ */
90642
 
+
90643
 
+static bool _sieve_result_implicit_keep
90644
 
+       (struct sieve_result *result, bool rollback)
90645
 
+{      
90646
 
+       struct sieve_result_action *rac;
90647
 
+       bool success = TRUE;
90648
 
+       bool dummy = TRUE;
90649
 
+       struct sieve_result_side_effect *rsef, *rsef_first = NULL;
90650
 
+       void *tr_context = NULL;
90651
 
+       const struct sieve_action *act_keep;
90652
 
+       
90653
 
+       if ( rollback )
90654
 
+               act_keep = result->failure_action;
90655
 
+       else 
90656
 
+               act_keep = result->keep_action;
90657
 
+       
90658
 
+       /* If keep is a non-action, return right away */
90659
 
+       if ( act_keep == NULL ) return TRUE; 
90660
 
+
90661
 
+       /* Scan for execution of keep-equal actions */  
90662
 
+       rac = result->first_action;
90663
 
+       while ( rac != NULL ) {
90664
 
+               if ( rac->data.action == act_keep && act_keep->equals != NULL && 
90665
 
+                       act_keep->equals(result->action_env.scriptenv, NULL, rac->data.context) &&
90666
 
+                       rac->data.executed )
90667
 
+                       return TRUE;
90668
 
+               
90669
 
+               rac = rac->next;        
90670
 
+       }
90671
 
+       
90672
 
+       /* Apply any implicit side effects if applicable */
90673
 
+       if ( !rollback && result->action_contexts != NULL ) {
90674
 
+               struct sieve_result_action_context *actctx;
90675
 
+               
90676
 
+               /* Check for implicit side effects to keep action */
90677
 
+               actctx = (struct sieve_result_action_context *) 
90678
 
+                               hash_table_lookup(result->action_contexts, act_keep);
90679
 
+               
90680
 
+               if ( actctx != NULL && actctx->seffects != NULL ) 
90681
 
+                       rsef_first = actctx->seffects->first_effect;
90682
 
+       }
90683
 
+       
90684
 
+       /* Start keep action */
90685
 
+       if ( act_keep->start != NULL ) 
90686
 
+               success = act_keep->start
90687
 
+                       (act_keep, &result->action_env, NULL, &tr_context);
90688
 
+
90689
 
+       /* Execute keep action */
90690
 
+       if ( success ) {
90691
 
+               rsef = rsef_first;
90692
 
+               while ( success && rsef != NULL ) {
90693
 
+                       const struct sieve_side_effect *sef = rsef->seffect;
90694
 
+                       if ( sef->pre_execute != NULL ) 
90695
 
+                               success = success && sef->pre_execute
90696
 
+                                       (sef, act_keep, &result->action_env, &rsef->context, tr_context);
90697
 
+                       rsef = rsef->next;
90698
 
+               }
90699
 
+
90700
 
+               if ( act_keep->execute != NULL )
90701
 
+                       success = success && act_keep->execute
90702
 
+                               (act_keep, &result->action_env, tr_context);
90703
 
+
90704
 
+               rsef = rsef_first;
90705
 
+               while ( success && rsef != NULL ) {
90706
 
+                       const struct sieve_side_effect *sef = rsef->seffect;
90707
 
+                       if ( sef->post_execute != NULL ) 
90708
 
+                               success = success && sef->post_execute
90709
 
+                                       (sef, act_keep, &result->action_env, rsef->context, tr_context);
90710
 
+                       rsef = rsef->next;
90711
 
+               }
90712
 
+       }
90713
 
+       
90714
 
+       /* Finish keep action */
90715
 
+       if ( success ) {
90716
 
+               if ( act_keep->commit != NULL ) 
90717
 
+                       success = act_keep->commit
90718
 
+                               (act_keep, &result->action_env, tr_context, &dummy);
90719
 
+
90720
 
+               rsef = rsef_first;
90721
 
+               while ( rsef != NULL ) {
90722
 
+                       const struct sieve_side_effect *sef = rsef->seffect;
90723
 
+                       bool keep = TRUE;
90724
 
+                       
90725
 
+                       if ( sef->post_commit != NULL ) 
90726
 
+                               sef->post_commit
90727
 
+                                       (sef, act_keep, &result->action_env, rsef->context, tr_context, 
90728
 
+                                               &keep);
90729
 
+                       rsef = rsef->next;
90730
 
+               }
90731
 
+                       
90732
 
+               return success; 
90733
 
+       }
90734
 
+       
90735
 
+       /* Failed, rollback */
90736
 
+       if ( act_keep->rollback != NULL )
90737
 
+               act_keep->rollback(act_keep, &result->action_env, tr_context, success);
90738
 
+
90739
 
+       return FALSE;
90740
 
+}
90741
 
+
90742
 
+bool sieve_result_implicit_keep
90743
 
+(struct sieve_result *result)
90744
 
+{
90745
 
+       const struct sieve_script_env *senv = result->action_env.scriptenv;
90746
 
+       struct sieve_exec_status dummy_status;
90747
 
+
90748
 
+       result->action_env.exec_status = 
90749
 
+               ( senv->exec_status == NULL ? &dummy_status : senv->exec_status );
90750
 
+
90751
 
+       return _sieve_result_implicit_keep(result, TRUE);       
90752
 
+}
90753
 
+
90754
 
+void sieve_result_mark_executed(struct sieve_result *result)
90755
 
+{
90756
 
+       struct sieve_result_action *first_action, *rac;
90757
 
+       
90758
 
+       first_action = ( result->last_attempted_action == NULL ?
90759
 
+               result->first_action : result->last_attempted_action->next );
90760
 
+       result->last_attempted_action = result->last_action;
90761
 
+
90762
 
+       rac = first_action;
90763
 
+       while ( rac != NULL ) {
90764
 
+               if ( rac->data.action != NULL )
90765
 
+                       rac->data.executed = TRUE;
90766
 
+               
90767
 
+               rac = rac->next;        
90768
 
+       }
90769
 
+}
90770
 
+
90771
 
+int sieve_result_execute
90772
 
+(struct sieve_result *result, bool *keep)
90773
 
+{
90774
 
+       const struct sieve_script_env *senv = result->action_env.scriptenv;
90775
 
+       struct sieve_exec_status dummy_status;
90776
 
+       bool implicit_keep = TRUE;
90777
 
+       bool success = TRUE, commit_ok;
90778
 
+       struct sieve_result_action *rac, *first_action;
90779
 
+       struct sieve_result_action *last_attempted;
90780
 
+
90781
 
+       if ( keep != NULL ) *keep = FALSE;
90782
 
+
90783
 
+       /* Prepare environment */
90784
 
+
90785
 
+       result->action_env.exec_status = 
90786
 
+               ( senv->exec_status == NULL ? &dummy_status : senv->exec_status );
90787
 
+       
90788
 
+       /* Make notice of this attempt */
90789
 
+       
90790
 
+       first_action = ( result->last_attempted_action == NULL ?
90791
 
+               result->first_action : result->last_attempted_action->next );
90792
 
+       result->last_attempted_action = result->last_action;
90793
 
+               
90794
 
+       /* 
90795
 
+        * Transaction start 
90796
 
+        */
90797
 
+       
90798
 
+       rac = first_action;
90799
 
+       while ( success && rac != NULL ) {
90800
 
+               const struct sieve_action *act = rac->data.action;
90801
 
+       
90802
 
+               /* Skip non-actions (inactive keep) and executed ones */
90803
 
+               if ( act == NULL || rac->data.executed ) {
90804
 
+                       rac = rac->next;        
90805
 
+                       continue;
90806
 
+               }
90807
 
+       
90808
 
+               if ( act->start != NULL ) {
90809
 
+                       rac->success = act->start(act, &result->action_env, rac->data.context, 
90810
 
+                               &rac->tr_context);
90811
 
+                       success = success && rac->success;
90812
 
+               } else {
90813
 
+                       rac->tr_context = rac->data.context;
90814
 
+               }
90815
 
90816
 
+               rac = rac->next;        
90817
 
+       }
90818
 
+       
90819
 
+       /* 
90820
 
+        * Transaction execute 
90821
 
+        */
90822
 
+       
90823
 
+       last_attempted = rac;
90824
 
+       rac = first_action;
90825
 
+       while ( success && rac != NULL ) {
90826
 
+               const struct sieve_action *act = rac->data.action;
90827
 
+               struct sieve_result_side_effect *rsef;
90828
 
+               const struct sieve_side_effect *sef;
90829
 
+               
90830
 
+               /* Skip non-actions (inactive keep) and executed ones */
90831
 
+               if ( act == NULL || rac->data.executed ) {
90832
 
+                       rac = rac->next;        
90833
 
+                       continue;
90834
 
+               }
90835
 
+                               
90836
 
+               /* Execute pre-execute event of side effects */
90837
 
+               rsef = rac->seffects != NULL ? rac->seffects->first_effect : NULL;
90838
 
+               while ( success && rsef != NULL ) {
90839
 
+                       sef = rsef->seffect;
90840
 
+                       if ( sef->pre_execute != NULL ) 
90841
 
+                               success = success & sef->pre_execute
90842
 
+                                       (sef, act, &result->action_env, &rsef->context, rac->tr_context);
90843
 
+                       rsef = rsef->next;
90844
 
+               }
90845
 
+       
90846
 
+               /* Execute the action itself */
90847
 
+               if ( success && act->execute != NULL ) {
90848
 
+                       rac->success = act->execute(act, &result->action_env, rac->tr_context);
90849
 
+                       success = success && rac->success;
90850
 
+               }
90851
 
+               
90852
 
+               /* Execute post-execute event of side effects */
90853
 
+               rsef = rac->seffects != NULL ? rac->seffects->first_effect : NULL;
90854
 
+               while ( success && rsef != NULL ) {
90855
 
+                       sef = rsef->seffect;
90856
 
+                       if ( sef->post_execute != NULL ) 
90857
 
+                               success = success && sef->post_execute
90858
 
+                                       (sef, act, &result->action_env, rsef->context, rac->tr_context);
90859
 
+                       rsef = rsef->next;
90860
 
+               }
90861
 
+                
90862
 
+               rac = rac->next;        
90863
 
+       }
90864
 
+       
90865
 
+       /* 
90866
 
+        * Transaction commit/rollback 
90867
 
+        */
90868
 
+
90869
 
+       commit_ok = success;
90870
 
+       rac = first_action;
90871
 
+       while ( rac != NULL && rac != last_attempted ) {
90872
 
+               const struct sieve_action *act = rac->data.action;
90873
 
+               struct sieve_result_side_effect *rsef;
90874
 
+               const struct sieve_side_effect *sef;
90875
 
+               
90876
 
+               if ( success ) {
90877
 
+                       bool impl_keep = TRUE;
90878
 
+                       
90879
 
+                       if ( rac->keep && keep != NULL ) *keep = TRUE;
90880
 
+
90881
 
+                       /* Skip non-actions (inactive keep) and executed ones */
90882
 
+                       if ( act == NULL || rac->data.executed ) {
90883
 
+                               rac = rac->next;        
90884
 
+                               continue;
90885
 
+                       }
90886
 
+                       
90887
 
+                       if ( act->commit != NULL ) { 
90888
 
+                               rac->data.executed = act->commit
90889
 
+                                       (act, &result->action_env, rac->tr_context, &impl_keep);
90890
 
+                               commit_ok = rac->data.executed && commit_ok;
90891
 
+                       }
90892
 
+       
90893
 
+                       /* Execute post_commit event of side effects */
90894
 
+                       rsef = rac->seffects != NULL ? rac->seffects->first_effect : NULL;
90895
 
+                       while ( rsef != NULL ) {
90896
 
+                               sef = rsef->seffect;
90897
 
+                               if ( sef->post_commit != NULL ) 
90898
 
+                                       sef->post_commit
90899
 
+                                               (sef, act, &result->action_env, rsef->context, rac->tr_context, 
90900
 
+                                                       &impl_keep);
90901
 
+                               rsef = rsef->next;
90902
 
+                       }
90903
 
+                       
90904
 
+                       implicit_keep = implicit_keep && impl_keep;
90905
 
+               } else {
90906
 
+                       /* Skip non-actions (inactive keep) and executed ones */
90907
 
+                       if ( act == NULL || rac->data.executed ) {
90908
 
+                               rac = rac->next;        
90909
 
+                               continue;
90910
 
+                       }
90911
 
+               
90912
 
+                       if ( act->rollback != NULL ) 
90913
 
+                               act->rollback(act, &result->action_env, rac->tr_context, rac->success);
90914
 
+                               
90915
 
+                       /* Rollback side effects */
90916
 
+                       rsef = rac->seffects != NULL ? rac->seffects->first_effect : NULL;
90917
 
+                       while ( rsef != NULL ) {
90918
 
+                               sef = rsef->seffect;
90919
 
+                               if ( sef->rollback != NULL ) 
90920
 
+                                       sef->rollback
90921
 
+                                               (sef, act, &result->action_env, rsef->context, rac->tr_context, 
90922
 
+                                               rac->success);
90923
 
+                               rsef = rsef->next;
90924
 
+                       }
90925
 
+               }
90926
 
+               
90927
 
+               rac = rac->next;        
90928
 
+       }
90929
 
+       
90930
 
+       if ( implicit_keep && keep != NULL ) *keep = TRUE;
90931
 
+       
90932
 
+       /* Return value indicates whether the caller should attempt an implicit keep 
90933
 
+        * of its own. So, if the above transaction fails, but the implicit keep below
90934
 
+        * succeeds, the return value is still true. An error is/should be logged 
90935
 
+        * though.
90936
 
+        */
90937
 
+       
90938
 
+       /* Execute implicit keep if the transaction failed or when the implicit keep
90939
 
+        * was not canceled during transaction. 
90940
 
+        */
90941
 
+       if ( !commit_ok || implicit_keep ) {            
90942
 
+               if ( !_sieve_result_implicit_keep(result, !commit_ok) ) 
90943
 
+                       return SIEVE_EXEC_KEEP_FAILED;
90944
 
+                       
90945
 
+               return ( commit_ok ? 
90946
 
+                       SIEVE_EXEC_OK            /* Success */ :
90947
 
+                       SIEVE_EXEC_FAILURE       /* Implicit keep executed */ );
90948
 
+       }
90949
 
+       
90950
 
+       /* Unconditional success */
90951
 
+       return SIEVE_EXEC_OK;
90952
 
+}
90953
 
+
90954
 
+/*
90955
 
+ * Result evaluation
90956
 
+ */
90957
 
+
90958
 
+struct sieve_result_iterate_context {
90959
 
+       struct sieve_result *result;
90960
 
+       struct sieve_result_action *action;
90961
 
+};
90962
 
+
90963
 
+struct sieve_result_iterate_context *sieve_result_iterate_init
90964
 
+(struct sieve_result *result)
90965
 
+{
90966
 
+       struct sieve_result_iterate_context *rictx = 
90967
 
+               t_new(struct sieve_result_iterate_context, 1);
90968
 
+       
90969
 
+       rictx->result = result;
90970
 
+       rictx->action = result->first_action;
90971
 
+
90972
 
+       return rictx;
90973
 
+}
90974
 
+
90975
 
+const struct sieve_action *sieve_result_iterate_next
90976
 
+       (struct sieve_result_iterate_context *rictx, bool *keep, void **context)
90977
 
+{
90978
 
+       struct sieve_result_action *rac;
90979
 
+
90980
 
+       if ( rictx == NULL )
90981
 
+               return  NULL;
90982
 
+
90983
 
+       rac = rictx->action;
90984
 
+       if ( rac != NULL ) {
90985
 
+               rictx->action = rac->next;
90986
 
+               
90987
 
+               if ( keep != NULL )
90988
 
+                       *keep = rac->keep;
90989
 
+
90990
 
+               if ( context != NULL )
90991
 
+                       *context = rac->data.context;
90992
 
+       
90993
 
+               return rac->data.action;
90994
 
+       }
90995
 
+
90996
 
+       return NULL;
90997
 
+}
90998
 
+
90999
 
+/*
91000
 
+ * Side effects list
91001
 
+ */
91002
 
91003
 
+struct sieve_side_effects_list *sieve_side_effects_list_create
91004
 
+       (struct sieve_result *result)
91005
 
+{
91006
 
+       struct sieve_side_effects_list *list = 
91007
 
+               p_new(result->pool, struct sieve_side_effects_list, 1);
91008
 
+       
91009
 
+       list->result = result;
91010
 
+       list->first_effect = NULL;
91011
 
+       list->last_effect = NULL;
91012
 
+       
91013
 
+       return list;
91014
 
+};
91015
 
+
91016
 
+void sieve_side_effects_list_add
91017
 
+(struct sieve_side_effects_list *list, const struct sieve_side_effect *seffect, 
91018
 
+       void *context)          
91019
 
+{
91020
 
+       struct sieve_result_side_effect *reffect;
91021
 
+       
91022
 
+       /* Create new side effect object */
91023
 
+       reffect = p_new(list->result->pool, struct sieve_result_side_effect, 1);
91024
 
+       reffect->seffect = seffect;
91025
 
+       reffect->context = context;
91026
 
+       
91027
 
+       /* Add */
91028
 
+       if ( list->first_effect == NULL ) {
91029
 
+               list->first_effect = reffect;
91030
 
+               list->last_effect = reffect;
91031
 
+               reffect->prev = NULL;
91032
 
+               reffect->next = NULL;
91033
 
+       } else {
91034
 
+               list->last_effect->next = reffect;
91035
 
+               reffect->prev = list->last_effect;
91036
 
+               list->last_effect = reffect;
91037
 
+               reffect->next = NULL;
91038
 
+       }       
91039
 
+}      
91040
 
+
91041
 
+
91042
 
+
91043
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-result.h dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-result.h
91044
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-result.h 1970-01-01 01:00:00.000000000 +0100
91045
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-result.h  2009-08-02 10:20:22.000000000 +0200
91046
 
@@ -0,0 +1,149 @@
91047
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
91048
 
+ */
91049
 
+
91050
 
+#ifndef __SIEVE_RESULT_H
91051
 
+#define __SIEVE_RESULT_H
91052
 
+
91053
 
+#include "sieve-common.h"
91054
 
+
91055
 
+/*
91056
 
+ * Types
91057
 
+ */
91058
 
91059
 
+struct sieve_side_effects_list;
91060
 
+
91061
 
+/*
91062
 
+ * Result object
91063
 
+ */
91064
 
+
91065
 
+struct sieve_result;
91066
 
+
91067
 
+struct sieve_result *sieve_result_create
91068
 
+       (const struct sieve_message_data *msgdata, const struct sieve_script_env *senv,
91069
 
+               struct sieve_error_handler *ehandler);
91070
 
+
91071
 
+void sieve_result_ref(struct sieve_result *result); 
91072
 
+
91073
 
+void sieve_result_unref(struct sieve_result **result); 
91074
 
+
91075
 
+pool_t sieve_result_pool(struct sieve_result *result);
91076
 
+
91077
 
+/*
91078
 
+ * Getters/Setters
91079
 
+ */
91080
 
+
91081
 
+struct sieve_error_handler *sieve_result_get_error_handler
91082
 
+       (struct sieve_result *result);
91083
 
+void sieve_result_set_error_handler
91084
 
+       (struct sieve_result *result, struct sieve_error_handler *ehandler);
91085
 
+
91086
 
+const struct sieve_script_env *sieve_result_get_script_env
91087
 
+       (struct sieve_result *result);
91088
 
+const struct sieve_message_data *sieve_result_get_message_data
91089
 
+       (struct sieve_result *result);
91090
 
+struct sieve_message_context *sieve_result_get_message_context
91091
 
+       (struct sieve_result *result);
91092
 
+
91093
 
+/*
91094
 
+ * Extension support
91095
 
+ */
91096
 
+
91097
 
+void sieve_result_extension_set_context
91098
 
+       (struct sieve_result *result, const struct sieve_extension *ext,
91099
 
+               void *context);
91100
 
+const void *sieve_result_extension_get_context
91101
 
+       (struct sieve_result *result, const struct sieve_extension *ext); 
91102
 
+
91103
 
+/* 
91104
 
+ * Result printing 
91105
 
+ */
91106
 
+
91107
 
+struct sieve_result_print_env {
91108
 
+       struct sieve_result *result;
91109
 
+       const struct sieve_script_env *scriptenv;
91110
 
+       struct ostream *stream;
91111
 
+};
91112
 
+
91113
 
+void sieve_result_vprintf
91114
 
+       (const struct sieve_result_print_env *penv, const char *fmt, va_list args);
91115
 
+void sieve_result_printf
91116
 
+       (const struct sieve_result_print_env *penv, const char *fmt, ...)
91117
 
+               ATTR_FORMAT(2, 3);
91118
 
+void sieve_result_action_printf
91119
 
+       (const struct sieve_result_print_env *penv, const char *fmt, ...)
91120
 
+               ATTR_FORMAT(2, 3);
91121
 
+void sieve_result_seffect_printf
91122
 
+       (const struct sieve_result_print_env *penv, const char *fmt, ...)
91123
 
+               ATTR_FORMAT(2, 3);
91124
 
+
91125
 
+bool sieve_result_print
91126
 
+       (struct sieve_result *result, const struct sieve_script_env *senv, 
91127
 
+               struct ostream *stream, bool *keep);
91128
 
+
91129
 
+/* 
91130
 
+ * Error handling 
91131
 
+ */
91132
 
+
91133
 
+void sieve_result_log
91134
 
+       (const struct sieve_action_exec_env *aenv, const char *fmt, ...)
91135
 
+               ATTR_FORMAT(2, 3);
91136
 
+void sieve_result_warning
91137
 
+       (const struct sieve_action_exec_env *aenv, const char *fmt, ...)
91138
 
+               ATTR_FORMAT(2, 3);
91139
 
+void sieve_result_error
91140
 
+       (const struct sieve_action_exec_env *aenv, const char *fmt, ...)
91141
 
+               ATTR_FORMAT(2, 3);
91142
 
+
91143
 
+/*
91144
 
+ * Result composition
91145
 
+ */
91146
 
91147
 
+void sieve_result_add_implicit_side_effect
91148
 
+(struct sieve_result *result, const struct sieve_action *to_action, 
91149
 
+       const struct sieve_side_effect *seffect, void *context);
91150
 
+       
91151
 
+int sieve_result_add_action
91152
 
+       (const struct sieve_runtime_env *renv, const struct sieve_action *action, 
91153
 
+               struct sieve_side_effects_list *seffects, unsigned int source_line, 
91154
 
+               void *context, unsigned int instance_limit);
91155
 
+int sieve_result_add_keep
91156
 
+       (const struct sieve_runtime_env *renv, 
91157
 
+               struct sieve_side_effects_list *seffects, unsigned int source_line);
91158
 
+
91159
 
+void sieve_result_set_keep_action
91160
 
+       (struct sieve_result *result, const struct sieve_action *action);
91161
 
+void sieve_result_set_failure_action
91162
 
+       (struct sieve_result *result, const struct sieve_action *action);
91163
 
+
91164
 
+/*
91165
 
+ * Result execution
91166
 
+ */
91167
 
91168
 
+bool sieve_result_implicit_keep(struct sieve_result *result);
91169
 
+
91170
 
+void sieve_result_mark_executed(struct sieve_result *result);
91171
 
+
91172
 
+int sieve_result_execute(struct sieve_result *result, bool *keep);
91173
 
+
91174
 
+/*
91175
 
+ * Result evaluation
91176
 
+ */
91177
 
+
91178
 
+struct sieve_result_iterate_context;
91179
 
+
91180
 
+struct sieve_result_iterate_context *sieve_result_iterate_init
91181
 
+       (struct sieve_result *result);
91182
 
+const struct sieve_action *sieve_result_iterate_next
91183
 
+       (struct sieve_result_iterate_context *rictx, bool *keep, void **context);
91184
 
+       
91185
 
+/*
91186
 
+ * Side effects list
91187
 
+ */
91188
 
91189
 
+struct sieve_side_effects_list *sieve_side_effects_list_create
91190
 
+       (struct sieve_result *result);
91191
 
+void sieve_side_effects_list_add
91192
 
+(struct sieve_side_effects_list *list, const struct sieve_side_effect *seffect, 
91193
 
+       void *context);
91194
 
+
91195
 
+#endif
91196
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-script.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-script.c
91197
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-script.c 1970-01-01 01:00:00.000000000 +0100
91198
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-script.c  2009-08-21 00:52:15.000000000 +0200
91199
 
@@ -0,0 +1,353 @@
91200
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
91201
 
+ */
91202
 
+
91203
 
+#include "lib.h"
91204
 
+#include "compat.h"
91205
 
+#include "istream.h"
91206
 
+#include "eacces-error.h"
91207
 
+
91208
 
+#include "sieve-common.h"
91209
 
+#include "sieve-error.h"
91210
 
+
91211
 
+#include "sieve-script-private.h"
91212
 
+
91213
 
+#include <unistd.h>
91214
 
+#include <sys/stat.h>
91215
 
+#include <fcntl.h>
91216
 
+
91217
 
+/*
91218
 
+ * Configuration
91219
 
+ */
91220
 
91221
 
+#define SIEVE_READ_BLOCK_SIZE (1024*8)
91222
 
+
91223
 
+/*
91224
 
+ * Filename to name/name to filename
91225
 
+ */
91226
 
+
91227
 
+static inline const char *_sieve_scriptfile_get_basename(const char *filename)
91228
 
+{
91229
 
+       const char *ext;
91230
 
+
91231
 
+       /* Extract the script name */
91232
 
+       ext = strrchr(filename, '.');
91233
 
+       if ( ext == NULL || ext == filename || strncmp(ext,".sieve",6) != 0 )
91234
 
+               return filename;
91235
 
+       
91236
 
+       return t_strdup_until(filename, ext);   
91237
 
+}
91238
 
+
91239
 
+bool sieve_script_file_has_extension(const char *filename)
91240
 
+{
91241
 
+       const char *ext;
91242
 
+
91243
 
+       /* See if it ends in .sieve already */
91244
 
+       ext = strrchr(filename, '.');
91245
 
+       if ( ext == NULL || ext == filename || strncmp(ext,".sieve",6) != 0 )
91246
 
+               return FALSE;
91247
 
+
91248
 
+       return TRUE;
91249
 
+}
91250
 
+
91251
 
+static inline const char *_sieve_scriptfile_from_name(const char *name)
91252
 
+{
91253
 
+       if ( !sieve_script_file_has_extension(name) )
91254
 
+               return t_strconcat(name, ".sieve", NULL);
91255
 
+
91256
 
+       return name;
91257
 
+}
91258
 
+
91259
 
+
91260
 
+/* 
91261
 
+ * Script object 
91262
 
+ */
91263
 
91264
 
+struct sieve_script *sieve_script_init
91265
 
+(struct sieve_script *script, const char *path, const char *name, 
91266
 
+       struct sieve_error_handler *ehandler, bool *exists_r)
91267
 
+{
91268
 
+       int ret;
91269
 
+       pool_t pool;
91270
 
+       struct stat st;
91271
 
+       struct stat lnk_st;
91272
 
+       const char *filename, *dirpath, *basename, *binpath;
91273
 
+
91274
 
+       if ( exists_r != NULL )
91275
 
+               *exists_r = TRUE;
91276
 
+
91277
 
+       T_BEGIN {
91278
 
+
91279
 
+               /* Extract filename from path */
91280
 
+
91281
 
+               filename = strrchr(path, '/');
91282
 
+               if ( filename == NULL ) {
91283
 
+                       dirpath = "";
91284
 
+                       filename = path;
91285
 
+               } else {
91286
 
+                       dirpath = t_strdup_until(path, filename);
91287
 
+                       filename++;
91288
 
+               }
91289
 
+
91290
 
+               basename = _sieve_scriptfile_get_basename(filename);
91291
 
+
91292
 
+               if ( *dirpath == '\0' )
91293
 
+                       binpath = t_strconcat(basename, ".svbin", NULL);
91294
 
+               else
91295
 
+                       binpath = t_strconcat(dirpath, "/", basename, ".svbin", NULL);
91296
 
+                               
91297
 
+               if ( name == NULL ) {
91298
 
+                       name = basename; 
91299
 
+               } else if ( *name == '\0' ) {
91300
 
+                       name = NULL;
91301
 
+               } else {
91302
 
+                       basename = name;
91303
 
+               }
91304
 
+                       
91305
 
+               /* First obtain stat data from the system */
91306
 
+               
91307
 
+               if ( (ret=lstat(path, &st)) < 0 ) {
91308
 
+                       if ( errno == ENOENT ) {
91309
 
+                               if ( exists_r == NULL ) 
91310
 
+                                       sieve_error(ehandler, basename, "sieve script does not exist");
91311
 
+                               else
91312
 
+                                       *exists_r = FALSE;
91313
 
+                       } else
91314
 
+                               sieve_critical(ehandler, basename, 
91315
 
+                                       "failed to stat sieve script: lstat(%s) failed: %m", path);
91316
 
+
91317
 
+                       script = NULL;
91318
 
+                       ret = 1;
91319
 
+
91320
 
+               } else {
91321
 
+                       /* Record stat information from the symlink */
91322
 
+                       lnk_st = st;
91323
 
+
91324
 
+                       /* Only create/init the object if it stat()s without problems */
91325
 
+                       if (S_ISLNK(st.st_mode)) {
91326
 
+                               if ( (ret=stat(path, &st)) < 0 ) { 
91327
 
+                                       if ( errno == ENOENT ) {
91328
 
+                                               if ( exists_r == NULL )
91329
 
+                                                       sieve_error(ehandler, basename, "sieve script does not exist");
91330
 
+                                               else
91331
 
+                                                       *exists_r = FALSE;
91332
 
+                                       } else
91333
 
+                                               sieve_critical(ehandler, basename, 
91334
 
+                                                       "failed to stat sieve script: stat(%s) failed: %m", path);
91335
 
+
91336
 
+                                       script = NULL;  
91337
 
+                                       ret = 1;
91338
 
+                               }
91339
 
+                       }
91340
 
+
91341
 
+                       if ( ret == 0 && !S_ISREG(st.st_mode) ) {
91342
 
+                               sieve_critical(ehandler, basename, 
91343
 
+                                       "sieve script file '%s' is not a regular file.", path);
91344
 
+                               script = NULL;
91345
 
+                               ret = 1;
91346
 
+                       } 
91347
 
+               }
91348
 
+
91349
 
+               if ( ret <= 0 ) {
91350
 
+                       if ( script == NULL ) {
91351
 
+                               pool = pool_alloconly_create("sieve_script", 1024);
91352
 
+                               script = p_new(pool, struct sieve_script, 1);
91353
 
+                               script->pool = pool;
91354
 
+                       } else 
91355
 
+                               pool = script->pool;
91356
 
+               
91357
 
+                       script->refcount = 1;
91358
 
+                       script->ehandler = ehandler;
91359
 
+                       sieve_error_handler_ref(ehandler);
91360
 
+               
91361
 
+                       script->st = st;
91362
 
+                       script->lnk_st = lnk_st;
91363
 
+                       script->path = p_strdup(pool, path);
91364
 
+                       script->filename = p_strdup(pool, filename);
91365
 
+                       script->dirpath = p_strdup(pool, dirpath);
91366
 
+                       script->binpath = p_strdup(pool, binpath);
91367
 
+                       script->basename = p_strdup(pool, basename);
91368
 
+
91369
 
+                       if ( name != NULL )
91370
 
+                               script->name = p_strdup(pool, name);
91371
 
+                       else
91372
 
+                               script->name = NULL;
91373
 
+               }
91374
 
+       } T_END;        
91375
 
+
91376
 
+       return script;
91377
 
+}
91378
 
+
91379
 
+struct sieve_script *sieve_script_create
91380
 
+(const char *path, const char *name, 
91381
 
+       struct sieve_error_handler *ehandler, bool *exists_r)
91382
 
+{
91383
 
+       return sieve_script_init(NULL, path, name, ehandler, exists_r);
91384
 
+}
91385
 
+
91386
 
+struct sieve_script *sieve_script_create_in_directory
91387
 
+(const char *dirpath, const char *name,
91388
 
+    struct sieve_error_handler *ehandler, bool *exists_r)
91389
 
+{
91390
 
+       const char *path;
91391
 
+
91392
 
+       if ( dirpath[strlen(dirpath)-1] == '/' )
91393
 
+               path = t_strconcat(dirpath, 
91394
 
+                       _sieve_scriptfile_from_name(name), NULL);
91395
 
+       else
91396
 
+               path = t_strconcat(dirpath, "/",
91397
 
+                       _sieve_scriptfile_from_name(name), NULL);
91398
 
+
91399
 
+       return sieve_script_init(NULL, path, name, ehandler, exists_r);
91400
 
+}
91401
 
+
91402
 
+void sieve_script_ref(struct sieve_script *script)
91403
 
+{
91404
 
+       script->refcount++;
91405
 
+}
91406
 
+
91407
 
+void sieve_script_unref(struct sieve_script **script)
91408
 
+{
91409
 
+       i_assert((*script)->refcount > 0);
91410
 
+
91411
 
+       if (--(*script)->refcount != 0)
91412
 
+               return;
91413
 
+
91414
 
+       if ( (*script)->stream != NULL )
91415
 
+               i_stream_destroy(&(*script)->stream);
91416
 
+
91417
 
+       sieve_error_handler_unref(&(*script)->ehandler);
91418
 
+
91419
 
+       pool_unref(&(*script)->pool);
91420
 
+
91421
 
+       *script = NULL;
91422
 
+}
91423
 
+
91424
 
+/* 
91425
 
+ * Accessors 
91426
 
+ */
91427
 
+
91428
 
+const char *sieve_script_name(const struct sieve_script *script)
91429
 
+{
91430
 
+       return script->name;
91431
 
+}
91432
 
+
91433
 
+const char *sieve_script_filename(const struct sieve_script *script)
91434
 
+{
91435
 
+       return script->filename;
91436
 
+}
91437
 
+
91438
 
+const char *sieve_script_path(const struct sieve_script *script)
91439
 
+{
91440
 
+       return script->path;
91441
 
+}
91442
 
+
91443
 
+const char *sieve_script_dirpath(const struct sieve_script *script)
91444
 
+{
91445
 
+       return script->dirpath;
91446
 
+}
91447
 
+
91448
 
+const char *sieve_script_binpath(const struct sieve_script *script)
91449
 
+{
91450
 
+       return script->binpath;
91451
 
+}
91452
 
+
91453
 
+mode_t sieve_script_permissions(const struct sieve_script *script)
91454
 
+{
91455
 
+       return script->st.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO);
91456
 
+}
91457
 
+
91458
 
+/* 
91459
 
+ * Stream manageement 
91460
 
+ */
91461
 
+
91462
 
+struct istream *sieve_script_open
91463
 
+(struct sieve_script *script, bool *deleted_r)
91464
 
+{
91465
 
+       int fd;
91466
 
+       struct stat st;
91467
 
+       struct istream *result;
91468
 
+
91469
 
+       if ( deleted_r != NULL )
91470
 
+               *deleted_r = FALSE;
91471
 
+
91472
 
+       if ( (fd=open(script->path, O_RDONLY)) < 0 ) {
91473
 
+               if ( errno == ENOENT ) {
91474
 
+                       if ( deleted_r == NULL ) 
91475
 
+                               /* Not supposed to occur, create() does stat already */
91476
 
+                               sieve_error(script->ehandler, script->basename, 
91477
 
+                                       "sieve script does not exist");
91478
 
+                       else 
91479
 
+                               *deleted_r = TRUE;
91480
 
+               } else if ( errno == EACCES ) {
91481
 
+                       sieve_critical(script->ehandler, script->path,
91482
 
+                               "failed to open sieve script: %s",
91483
 
+                               eacces_error_get("open", script->path));
91484
 
+               } else {
91485
 
+                       sieve_critical(script->ehandler, script->path, 
91486
 
+                               "failed to open sieve script: open(%s) failed: %m", script->path);
91487
 
+               }
91488
 
+               return NULL;
91489
 
+       }       
91490
 
+       
91491
 
+       if ( fstat(fd, &st) != 0 ) {
91492
 
+               sieve_critical(script->ehandler, script->path, 
91493
 
+                       "failed to open sieve script: fstat(fd=%s) failed: %m", script->path);
91494
 
+               result = NULL;
91495
 
+       } else {
91496
 
+               /* Re-check the file type just to be sure */
91497
 
+               if ( !S_ISREG(st.st_mode) ) {
91498
 
+                       sieve_critical(script->ehandler, script->path,
91499
 
+                               "sieve script file '%s' is not a regular file", script->path);
91500
 
+                       result = NULL;
91501
 
+               } else {
91502
 
+                       result = script->stream = 
91503
 
+                               i_stream_create_fd(fd, SIEVE_READ_BLOCK_SIZE, TRUE);
91504
 
+                       script->st = script->lnk_st = st;
91505
 
+               }
91506
 
+       }
91507
 
+
91508
 
+       if ( result == NULL ) {
91509
 
+               /* Something went wrong, close the fd */
91510
 
+               if ( close(fd) != 0 ) {
91511
 
+                       sieve_sys_error(
91512
 
+                               "failed to close sieve script: close(fd=%s) failed: %m", 
91513
 
+                               script->path);
91514
 
+               }
91515
 
+       }
91516
 
+       
91517
 
+       return result;
91518
 
+}
91519
 
+
91520
 
+void sieve_script_close(struct sieve_script *script)
91521
 
+{
91522
 
+       i_stream_destroy(&script->stream);
91523
 
+}
91524
 
+
91525
 
+uoff_t sieve_script_get_size(const struct sieve_script *script)
91526
 
+{
91527
 
+       return script->st.st_size;
91528
 
+}
91529
 
+
91530
 
+/* 
91531
 
+ * Comparison 
91532
 
+ */
91533
 
+
91534
 
+int sieve_script_cmp
91535
 
+(const struct sieve_script *script1, const struct sieve_script *script2)
91536
 
+{
91537
 
+       if ( script1 == NULL || script2 == NULL ) 
91538
 
+               return -1;      
91539
 
+
91540
 
+       return ( script1->st.st_ino == script2->st.st_ino ) ? 0 : -1;
91541
 
+}
91542
 
+
91543
 
+unsigned int sieve_script_hash(const struct sieve_script *script)
91544
 
+{      
91545
 
+       return (unsigned int) script->st.st_ino;
91546
 
+}
91547
 
+
91548
 
+bool sieve_script_older
91549
 
+(const struct sieve_script *script, time_t time)
91550
 
+{
91551
 
+       return ( script->st.st_mtime < time && script->lnk_st.st_mtime < time );
91552
 
+}
91553
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-script.h dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-script.h
91554
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-script.h 1970-01-01 01:00:00.000000000 +0100
91555
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-script.h  2009-02-12 21:01:37.000000000 +0100
91556
 
@@ -0,0 +1,70 @@
91557
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
91558
 
+ */
91559
 
+
91560
 
+#ifndef __SIEVE_SCRIPT_H
91561
 
+#define __SIEVE_SCRIPT_H
91562
 
+
91563
 
+#include "sieve-common.h"
91564
 
+
91565
 
+#include <sys/types.h>
91566
 
+
91567
 
+/*
91568
 
+ * Sieve script object
91569
 
+ */
91570
 
+
91571
 
+struct sieve_script;
91572
 
+
91573
 
+struct sieve_script *sieve_script_create
91574
 
+       (const char *path, const char *name, 
91575
 
+               struct sieve_error_handler *ehandler, bool *exists_r);
91576
 
+
91577
 
+struct sieve_script *sieve_script_create_in_directory
91578
 
+       (const char *dirpath, const char *name,
91579
 
+       struct sieve_error_handler *ehandler, bool *exists_r);
91580
 
+
91581
 
+void sieve_script_ref(struct sieve_script *script);
91582
 
+void sieve_script_unref(struct sieve_script **script);
91583
 
+
91584
 
+/*
91585
 
+ * Filename filter
91586
 
+ */
91587
 
91588
 
+bool sieve_script_file_has_extension(const char *filename);
91589
 
+
91590
 
+/*
91591
 
+ * Accessors
91592
 
+ */
91593
 
91594
 
+const char *sieve_script_name(const struct sieve_script *script);
91595
 
+const char *sieve_script_filename(const struct sieve_script *script);
91596
 
+const char *sieve_script_path(const struct sieve_script *script);
91597
 
+const char *sieve_script_binpath(const struct sieve_script *script);
91598
 
+const char *sieve_script_dirpath(const struct sieve_script *script);
91599
 
+
91600
 
+mode_t sieve_script_permissions(const struct sieve_script *script);
91601
 
+
91602
 
+/* 
91603
 
+ * Stream management 
91604
 
+ */
91605
 
+
91606
 
+struct istream *sieve_script_open(struct sieve_script *script, bool *deleted_r);
91607
 
+void sieve_script_close(struct sieve_script *script);
91608
 
+
91609
 
+uoff_t sieve_script_get_size(const struct sieve_script *script);
91610
 
+
91611
 
+/*
91612
 
+ * Comparison
91613
 
+ */
91614
 
91615
 
+int sieve_script_cmp
91616
 
+       (const struct sieve_script *script1, const struct sieve_script *script2);
91617
 
+unsigned int sieve_script_hash(const struct sieve_script *script);
91618
 
+bool sieve_script_older(const struct sieve_script *script, time_t time);
91619
 
+
91620
 
+static inline bool sieve_script_equals
91621
 
+       (const struct sieve_script *script1, const struct sieve_script *script2)
91622
 
+{
91623
 
+       return ( sieve_script_cmp(script1, script2) == 0 );
91624
 
+}
91625
 
+
91626
 
+#endif /* __SIEVE_SCRIPT_H */
91627
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-script-private.h dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-script-private.h
91628
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-script-private.h 1970-01-01 01:00:00.000000000 +0100
91629
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-script-private.h  2009-01-10 20:32:19.000000000 +0100
91630
 
@@ -0,0 +1,40 @@
91631
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
91632
 
+ */
91633
 
+
91634
 
+#ifndef __SIEVE_SCRIPT_PRIVATE_H
91635
 
+#define __SIEVE_SCRIPT_PRIVATE_H
91636
 
+
91637
 
+#include "sieve-script.h"
91638
 
+
91639
 
+/*
91640
 
+ * Script object
91641
 
+ */
91642
 
+
91643
 
+struct sieve_script {
91644
 
+       pool_t pool;
91645
 
+       unsigned int refcount;
91646
 
+
91647
 
+       struct stat st;
91648
 
+       struct stat lnk_st;
91649
 
+       time_t mtime;
91650
 
+
91651
 
+       struct sieve_error_handler *ehandler;
91652
 
+
91653
 
+       /* Parameters */
91654
 
+       const char *name;
91655
 
+       const char *basename;
91656
 
+       const char *filename;
91657
 
+       const char *path;
91658
 
+       const char *dirpath;
91659
 
+       const char *binpath;
91660
 
+
91661
 
+       /* Stream */
91662
 
+       int fd; /* FIXME: we could use the stream's autoclose facility */
91663
 
+       struct istream *stream;
91664
 
+};
91665
 
+
91666
 
+struct sieve_script *sieve_script_init
91667
 
+(struct sieve_script *script, const char *path, const char *name,
91668
 
+    struct sieve_error_handler *ehandler, bool *exists_r);
91669
 
+
91670
 
+#endif /* __SIEVE_SCRIPT_PRIVATE_H */
91671
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-types.h dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-types.h
91672
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-types.h  1970-01-01 01:00:00.000000000 +0100
91673
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-types.h   2009-07-27 13:30:18.000000000 +0200
91674
 
@@ -0,0 +1,103 @@
91675
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file 
91676
 
+ */
91677
 
+
91678
 
+#ifndef __SIEVE_TYPES_H
91679
 
+#define __SIEVE_TYPES_H
91680
 
+
91681
 
+#include "lib.h"
91682
 
+
91683
 
+#include <stdio.h>
91684
 
+
91685
 
+/* Enable runtime trace functionality */
91686
 
+#define SIEVE_RUNTIME_TRACE
91687
 
+
91688
 
+/*
91689
 
+ * Forward declarations
91690
 
+ */
91691
 
+
91692
 
+struct sieve_script;
91693
 
+struct sieve_binary;
91694
 
+
91695
 
+struct sieve_message_data;
91696
 
+struct sieve_script_env;
91697
 
+struct sieve_exec_status;
91698
 
+
91699
 
+/* 
91700
 
+ * Message data
91701
 
+ *
91702
 
+ * - The mail message + envelope data 
91703
 
+ */
91704
 
+
91705
 
+struct sieve_message_data {
91706
 
+       struct mail *mail;
91707
 
+       const char *return_path;
91708
 
+       const char *to_address;
91709
 
+       const char *auth_user;
91710
 
+       const char *id;
91711
 
+};
91712
 
+
91713
 
+/* 
91714
 
+ * Script environment
91715
 
+ *
91716
 
+ * - Environment for currently executing script 
91717
 
+ */
91718
 
+
91719
 
+struct sieve_script_env {
91720
 
+       /* Mail-related */
91721
 
+       struct mail_namespace *namespaces;
91722
 
+       const char *default_mailbox;
91723
 
+       bool mailbox_autocreate;
91724
 
+       bool mailbox_autosubscribe;
91725
 
+       
91726
 
+       /* System-related */
91727
 
+       const char *username;
91728
 
+       const char *hostname;
91729
 
+       const char *postmaster_address;
91730
 
+               
91731
 
+       /* Callbacks */
91732
 
+       
91733
 
+       /* Interface for sending mail */
91734
 
+       void *(*smtp_open)
91735
 
+               (const char *destination, const char *return_path, FILE **file_r);
91736
 
+       bool (*smtp_close)(void *handle);
91737
 
+       
91738
 
+       /* Interface for marking and checking duplicates */
91739
 
+       int (*duplicate_check)
91740
 
+               (const void *id, size_t id_size, const char *user);
91741
 
+       void (*duplicate_mark)
91742
 
+               (const void *id, size_t id_size, const char *user, time_t time);
91743
 
+       
91744
 
+       /* Execution status record */   
91745
 
+       struct sieve_exec_status *exec_status;
91746
 
+               
91747
 
+       /* Trace stream */
91748
 
+       struct ostream *trace_stream;
91749
 
+};
91750
 
+
91751
 
+#define SIEVE_SCRIPT_DEFAULT_MAILBOX(senv) \
91752
 
+       (senv->default_mailbox == NULL ? "INBOX" : senv->default_mailbox )
91753
 
+
91754
 
+/*
91755
 
+ * Script executionstatus
91756
 
+ */    
91757
 
+
91758
 
+struct sieve_exec_status {
91759
 
+       bool message_saved;
91760
 
+       bool message_forwarded;
91761
 
+       bool tried_default_save;
91762
 
+       bool keep_original;
91763
 
+       struct mail_storage *last_storage;
91764
 
+};
91765
 
+
91766
 
+/*
91767
 
+ * Execution exit codes
91768
 
+ */
91769
 
+
91770
 
+enum sieve_execution_exitcode {
91771
 
+       SIEVE_EXEC_OK          = 1,
91772
 
+       SIEVE_EXEC_FAILURE     = 0,
91773
 
+       SIEVE_EXEC_BIN_CORRUPT = -1,
91774
 
+       SIEVE_EXEC_KEEP_FAILED = -2
91775
 
+};
91776
 
+
91777
 
+#endif /* __SIEVE_TYPES_H */
91778
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-validator.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-validator.c
91779
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-validator.c      1970-01-01 01:00:00.000000000 +0100
91780
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-validator.c       2009-07-22 10:40:43.000000000 +0200
91781
 
@@ -0,0 +1,1327 @@
91782
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file 
91783
 
+ */
91784
 
+
91785
 
+#include "lib.h"
91786
 
+#include "str.h"
91787
 
+#include "str-sanitize.h"
91788
 
+#include "array.h"
91789
 
+#include "buffer.h"
91790
 
+#include "mempool.h"
91791
 
+#include "hash.h"
91792
 
+
91793
 
+#include "sieve-common.h"
91794
 
+#include "sieve-extensions.h"
91795
 
+#include "sieve-script.h"
91796
 
+#include "sieve-ast.h"
91797
 
+#include "sieve-commands.h"
91798
 
+#include "sieve-validator.h"
91799
 
+
91800
 
+#include "sieve-comparators.h"
91801
 
+#include "sieve-address-parts.h"
91802
 
+
91803
 
+/*
91804
 
+ * Forward declarations
91805
 
+ */
91806
 
91807
 
+static void sieve_validator_register_core_commands
91808
 
+       (struct sieve_validator *validator);
91809
 
+static void sieve_validator_register_core_tests
91810
 
+       (struct sieve_validator *validator);
91811
 
+       
91812
 
+/*
91813
 
+ * Types
91814
 
+ */
91815
 
91816
 
+/* Tag registration */
91817
 
+
91818
 
+struct sieve_tag_registration {
91819
 
+       const struct sieve_argument *tag;
91820
 
+       const char *identifier; 
91821
 
+       int id_code;
91822
 
+};
91823
 
+
91824
 
+/* Command registration */
91825
 
+
91826
 
+struct sieve_command_registration {
91827
 
+       const struct sieve_command *command;
91828
 
+       
91829
 
+       ARRAY_DEFINE(normal_tags, struct sieve_tag_registration *); 
91830
 
+       ARRAY_DEFINE(instanced_tags, struct sieve_tag_registration *); 
91831
 
+       ARRAY_DEFINE(persistent_tags, struct sieve_tag_registration *); 
91832
 
+};
91833
 
91834
 
+/* Default (literal) arguments */
91835
 
+
91836
 
+struct sieve_default_argument {
91837
 
+       const struct sieve_argument *argument;
91838
 
+       struct sieve_default_argument *overrides;
91839
 
+};
91840
 
+
91841
 
+/* 
91842
 
+ * Validator extension
91843
 
+ */
91844
 
+
91845
 
+struct sieve_validator_extension_reg {
91846
 
+       const struct sieve_validator_extension *val_ext;
91847
 
+       struct sieve_ast_argument *arg;
91848
 
+       void *context;
91849
 
+
91850
 
+       bool loaded;
91851
 
+};
91852
 
+
91853
 
+/* 
91854
 
+ * Validator
91855
 
+ */
91856
 
+
91857
 
+struct sieve_validator {
91858
 
+       pool_t pool;
91859
 
+
91860
 
+       struct sieve_ast *ast;
91861
 
+       struct sieve_script *script;
91862
 
+       
91863
 
+       struct sieve_error_handler *ehandler;
91864
 
+
91865
 
+       bool finished_require;
91866
 
+       
91867
 
+       /* Registries */
91868
 
+       
91869
 
+       struct hash_table *commands;
91870
 
+       
91871
 
+       ARRAY_DEFINE(extensions, struct sieve_validator_extension_reg);
91872
 
+       
91873
 
+       /* This is currently a wee bit ugly and needs more thought */
91874
 
+       struct sieve_default_argument default_arguments[SAT_COUNT];
91875
 
+
91876
 
+       /* Default argument processing state (FIXME: ugly) */
91877
 
+       struct sieve_default_argument *current_defarg;
91878
 
+       enum sieve_argument_type current_defarg_type;
91879
 
+       bool current_defarg_constant;
91880
 
+};
91881
 
+
91882
 
+/* 
91883
 
+ * Error handling 
91884
 
+ */
91885
 
+
91886
 
+void sieve_validator_warning
91887
 
+(struct sieve_validator *validator, unsigned int source_line, 
91888
 
+       const char *fmt, ...) 
91889
 
+{ 
91890
 
+       va_list args;
91891
 
+       
91892
 
+       va_start(args, fmt);
91893
 
+       sieve_vwarning(validator->ehandler, 
91894
 
+               sieve_error_script_location(validator->script, source_line),
91895
 
+               fmt, args);
91896
 
+       va_end(args);
91897
 
+       
91898
 
+}
91899
 
91900
 
+void sieve_validator_error
91901
 
+(struct sieve_validator *validator, unsigned int source_line, 
91902
 
+       const char *fmt, ...) 
91903
 
+{
91904
 
+       va_list args;
91905
 
+       
91906
 
+       va_start(args, fmt);
91907
 
+       sieve_verror(validator->ehandler, 
91908
 
+               sieve_error_script_location(validator->script, source_line),
91909
 
+               fmt, args);
91910
 
+       va_end(args);
91911
 
+}
91912
 
+
91913
 
+void sieve_validator_critical
91914
 
+(struct sieve_validator *validator, unsigned int source_line, 
91915
 
+       const char *fmt, ...) 
91916
 
+{
91917
 
+       va_list args;
91918
 
+       
91919
 
+       va_start(args, fmt);
91920
 
+       sieve_vcritical(validator->ehandler, 
91921
 
+               sieve_error_script_location(validator->script, source_line),
91922
 
+               fmt, args);
91923
 
+       va_end(args);
91924
 
+}
91925
 
+
91926
 
+/* 
91927
 
+ * Validator object 
91928
 
+ */
91929
 
+
91930
 
+struct sieve_validator *sieve_validator_create
91931
 
+(struct sieve_ast *ast, struct sieve_error_handler *ehandler) 
91932
 
+{
91933
 
+       unsigned int i;
91934
 
+       pool_t pool;
91935
 
+       struct sieve_validator *validator;
91936
 
+       
91937
 
+       pool = pool_alloconly_create("sieve_validator", 8192);  
91938
 
+       validator = p_new(pool, struct sieve_validator, 1);
91939
 
+       validator->pool = pool;
91940
 
+       
91941
 
+       validator->ehandler = ehandler;
91942
 
+       sieve_error_handler_ref(ehandler);
91943
 
+       
91944
 
+       validator->ast = ast;   
91945
 
+       validator->script = sieve_ast_script(ast);
91946
 
+       sieve_ast_ref(ast);
91947
 
+
91948
 
+       /* Setup default arguments */
91949
 
+       validator->default_arguments[SAT_NUMBER].
91950
 
+               argument = &number_argument;
91951
 
+       validator->default_arguments[SAT_VAR_STRING].
91952
 
+               argument = &string_argument;
91953
 
+       validator->default_arguments[SAT_CONST_STRING].
91954
 
+               argument = &string_argument;
91955
 
+       validator->default_arguments[SAT_STRING_LIST].
91956
 
+               argument = &string_list_argument;
91957
 
+
91958
 
+       /* Setup storage for extension contexts */              
91959
 
+       p_array_init(&validator->extensions, pool, sieve_extensions_get_count());
91960
 
+               
91961
 
+       /* Setup command registry */
91962
 
+       validator->commands = hash_table_create
91963
 
+               (default_pool, pool, 0, strcase_hash, (hash_cmp_callback_t *)strcasecmp);
91964
 
+       sieve_validator_register_core_commands(validator);
91965
 
+       sieve_validator_register_core_tests(validator);
91966
 
+       
91967
 
+       /* Pre-load core language features implemented as 'extensions' */
91968
 
+       for ( i = 0; i < sieve_preloaded_extensions_count; i++ ) {
91969
 
+               const struct sieve_extension *ext = sieve_preloaded_extensions[i];
91970
 
+               
91971
 
+               if ( ext->validator_load != NULL )
91972
 
+                       (void)ext->validator_load(validator);
91973
 
+       }
91974
 
+       
91975
 
+       return validator;
91976
 
+}
91977
 
+
91978
 
+void sieve_validator_free(struct sieve_validator **validator) 
91979
 
+{
91980
 
+       const struct sieve_validator_extension_reg *extrs;
91981
 
+       unsigned int ext_count, i;
91982
 
+
91983
 
+       hash_table_destroy(&(*validator)->commands);
91984
 
+       sieve_ast_unref(&(*validator)->ast);
91985
 
+
91986
 
+       sieve_error_handler_unref(&(*validator)->ehandler);
91987
 
+
91988
 
+       /* Signal registered extensions that the validator is being destroyed */
91989
 
+       extrs = array_get(&(*validator)->extensions, &ext_count);
91990
 
+       for ( i = 0; i < ext_count; i++ ) {
91991
 
+               if ( extrs[i].val_ext != NULL && extrs[i].val_ext->free != NULL )
91992
 
+                       extrs[i].val_ext->free(*validator, extrs[i].context);
91993
 
+       }
91994
 
+
91995
 
+       pool_unref(&(*validator)->pool);
91996
 
+
91997
 
+       *validator = NULL;
91998
 
+}
91999
 
+
92000
 
+/*
92001
 
+ * Accessors
92002
 
+ */
92003
 
+
92004
 
+pool_t sieve_validator_pool(struct sieve_validator *validator)
92005
 
+{
92006
 
+       return validator->pool;
92007
 
+}
92008
 
+
92009
 
+struct sieve_error_handler *sieve_validator_error_handler
92010
 
+(struct sieve_validator *validator)
92011
 
+{
92012
 
+       return validator->ehandler;
92013
 
+}
92014
 
+
92015
 
+struct sieve_ast *sieve_validator_ast
92016
 
+(struct sieve_validator *validator)
92017
 
+{
92018
 
+       return validator->ast;
92019
 
+}
92020
 
+
92021
 
+struct sieve_script *sieve_validator_script
92022
 
+(struct sieve_validator *validator)
92023
 
+{
92024
 
+       return validator->script;
92025
 
+}
92026
 
+
92027
 
+/* 
92028
 
+ * Command registry 
92029
 
+ */
92030
 
+
92031
 
+/* Dummy command object to mark unknown commands in the registry */
92032
 
+
92033
 
+static bool _cmd_unknown_validate
92034
 
+(struct sieve_validator *validator ATTR_UNUSED, 
92035
 
+       struct sieve_command_context *cmd ATTR_UNUSED) 
92036
 
+{
92037
 
+       i_unreached();
92038
 
+       return FALSE;
92039
 
+}
92040
 
+
92041
 
+static const struct sieve_command unknown_command = { 
92042
 
+       "", SCT_NONE, 0, 0, FALSE, FALSE , 
92043
 
+       NULL, NULL, _cmd_unknown_validate, NULL, NULL 
92044
 
+};
92045
 
+
92046
 
+/* Registration of the core commands of the language */
92047
 
+
92048
 
+static void sieve_validator_register_core_tests
92049
 
+(struct sieve_validator *validator) 
92050
 
+{
92051
 
+       unsigned int i;
92052
 
+       
92053
 
+       for ( i = 0; i < sieve_core_tests_count; i++ ) {
92054
 
+               sieve_validator_register_command(validator, sieve_core_tests[i]); 
92055
 
+       }
92056
 
+}
92057
 
+
92058
 
+static void sieve_validator_register_core_commands
92059
 
+(struct sieve_validator *validator) 
92060
 
+{
92061
 
+       unsigned int i;
92062
 
+       
92063
 
+       for ( i = 0; i < sieve_core_commands_count; i++ ) {
92064
 
+               sieve_validator_register_command(validator, sieve_core_commands[i]); 
92065
 
+       }
92066
 
+}
92067
 
+
92068
 
+/* Registry functions */
92069
 
+
92070
 
+static struct sieve_command_registration *
92071
 
+sieve_validator_find_command_registration
92072
 
+(struct sieve_validator *validator, const char *command) 
92073
 
+{
92074
 
+       return (struct sieve_command_registration *) 
92075
 
+               hash_table_lookup(validator->commands, command);
92076
 
+}
92077
 
+
92078
 
+static struct sieve_command_registration *_sieve_validator_register_command
92079
 
+(struct sieve_validator *validator, const struct sieve_command *command,
92080
 
+       const char *identifier) 
92081
 
+{
92082
 
+       struct sieve_command_registration *record = 
92083
 
+               p_new(validator->pool, struct sieve_command_registration, 1);
92084
 
+       record->command = command;
92085
 
+       hash_table_insert(validator->commands, (void *) identifier, (void *) record);
92086
 
+               
92087
 
+       return record;
92088
 
+}
92089
 
+
92090
 
+void sieve_validator_register_command
92091
 
+(struct sieve_validator *validator, const struct sieve_command *command) 
92092
 
+{
92093
 
+       struct sieve_command_registration *cmd_reg =
92094
 
+               sieve_validator_find_command_registration(validator, command->identifier);
92095
 
+               
92096
 
+       if ( cmd_reg == NULL ) 
92097
 
+               cmd_reg = _sieve_validator_register_command
92098
 
+                       (validator, command, command->identifier);
92099
 
+       else
92100
 
+               cmd_reg->command = command;
92101
 
+       
92102
 
+       if ( command->registered != NULL ) 
92103
 
+               command->registered(validator, cmd_reg);
92104
 
+}
92105
 
+
92106
 
+static void sieve_validator_register_unknown_command
92107
 
+(struct sieve_validator *validator, const char *command) 
92108
 
+{
92109
 
+       (void)_sieve_validator_register_command(validator, &unknown_command, command);          
92110
 
+}
92111
 
+
92112
 
+const struct sieve_command *sieve_validator_find_command
92113
 
+(struct sieve_validator *validator, const char *command) 
92114
 
+{
92115
 
+  struct sieve_command_registration *record = 
92116
 
+       sieve_validator_find_command_registration(validator, command);
92117
 
+  
92118
 
+  return ( record == NULL ? NULL : record->command );
92119
 
+}
92120
 
+
92121
 
+/* 
92122
 
+ * Per-command tagged argument registry 
92123
 
+ */
92124
 
+
92125
 
+/* Dummy argument object to mark unknown arguments in the registry */
92126
 
+
92127
 
+static bool _unknown_tag_validate
92128
 
+(struct sieve_validator *validator ATTR_UNUSED, 
92129
 
+       struct sieve_ast_argument **arg ATTR_UNUSED, 
92130
 
+       struct sieve_command_context *tst ATTR_UNUSED)
92131
 
+{
92132
 
+       i_unreached();
92133
 
+       return FALSE;
92134
 
+}
92135
 
+
92136
 
+static const struct sieve_argument _unknown_tag = { 
92137
 
+       "", 
92138
 
+       NULL, NULL, 
92139
 
+       _unknown_tag_validate, 
92140
 
+       NULL, NULL 
92141
 
+};
92142
 
+
92143
 
+/* Registry functions */
92144
 
+
92145
 
+static void _sieve_validator_register_tag
92146
 
+(struct sieve_validator *validator, struct sieve_command_registration *cmd_reg, 
92147
 
+       const struct sieve_argument *tag, const char *identifier, int id_code) 
92148
 
+{
92149
 
+       struct sieve_tag_registration *reg;
92150
 
+
92151
 
+       reg = p_new(validator->pool, struct sieve_tag_registration, 1);
92152
 
+       reg->tag = tag;
92153
 
+       reg->id_code = id_code;
92154
 
+       if ( identifier == NULL )
92155
 
+               reg->identifier = tag->identifier;
92156
 
+       else
92157
 
+               reg->identifier = p_strdup(validator->pool, identifier);
92158
 
+       
92159
 
+       if ( !array_is_created(&cmd_reg->normal_tags) )
92160
 
+               p_array_init(&cmd_reg->normal_tags, validator->pool, 4);
92161
 
+
92162
 
+       array_append(&cmd_reg->normal_tags, &reg, 1);
92163
 
+}
92164
 
+
92165
 
+void sieve_validator_register_persistent_tag
92166
 
+(struct sieve_validator *validator, const struct sieve_argument *tag, 
92167
 
+       const char *command)
92168
 
+{
92169
 
+       struct sieve_command_registration *cmd_reg = 
92170
 
+               sieve_validator_find_command_registration(validator, command);
92171
 
+       struct sieve_tag_registration *reg = 
92172
 
+               p_new(validator->pool, struct sieve_tag_registration, 1);
92173
 
+       
92174
 
+       reg->tag = tag;
92175
 
+       reg->id_code = -1;
92176
 
+       
92177
 
+       if ( cmd_reg == NULL ) {
92178
 
+               cmd_reg = _sieve_validator_register_command(validator, NULL, command);
92179
 
+       }       
92180
 
+               
92181
 
+       /* Add the tag to the persistent tags list if necessary */
92182
 
+       if ( tag->validate_persistent != NULL ) {
92183
 
+               if ( !array_is_created(&cmd_reg->persistent_tags) ) 
92184
 
+                       p_array_init(&cmd_reg->persistent_tags, validator->pool, 4);
92185
 
+                               
92186
 
+               array_append(&cmd_reg->persistent_tags, &reg, 1);
92187
 
+       }
92188
 
+}
92189
 
+
92190
 
+void sieve_validator_register_external_tag
92191
 
+(struct sieve_validator *validator, const struct sieve_argument *tag, 
92192
 
+       const char *command, int id_code) 
92193
 
+{
92194
 
+       struct sieve_command_registration *cmd_reg = 
92195
 
+               sieve_validator_find_command_registration(validator, command);
92196
 
+               
92197
 
+       if ( cmd_reg == NULL ) {
92198
 
+               cmd_reg = _sieve_validator_register_command(validator, NULL, command);
92199
 
+       }
92200
 
+       
92201
 
+       _sieve_validator_register_tag
92202
 
+               (validator, cmd_reg, tag, NULL, id_code);
92203
 
+}
92204
 
+
92205
 
+void sieve_validator_register_tag
92206
 
+(struct sieve_validator *validator, struct sieve_command_registration *cmd_reg, 
92207
 
+       const struct sieve_argument *tag, int id_code) 
92208
 
+{
92209
 
+       if ( tag->is_instance_of == NULL )
92210
 
+               _sieve_validator_register_tag(validator, cmd_reg, tag, NULL, id_code);
92211
 
+       else {
92212
 
+               struct sieve_tag_registration *reg = 
92213
 
+                       p_new(validator->pool, struct sieve_tag_registration, 1);
92214
 
+               reg->tag = tag;
92215
 
+               reg->id_code = id_code;
92216
 
+
92217
 
+               if ( !array_is_created(&cmd_reg->instanced_tags) ) 
92218
 
+                               p_array_init(&cmd_reg->instanced_tags, validator->pool, 4);
92219
 
+                               
92220
 
+               array_append(&cmd_reg->instanced_tags, &reg, 1);
92221
 
+       }
92222
 
+}
92223
 
+
92224
 
+static void sieve_validator_register_unknown_tag
92225
 
+(struct sieve_validator *validator, struct sieve_command_registration *cmd_reg, 
92226
 
+       const char *tag) 
92227
 
+{
92228
 
+       _sieve_validator_register_tag(validator, cmd_reg, &_unknown_tag, tag, 0);
92229
 
+}
92230
 
+
92231
 
+static const struct sieve_argument *sieve_validator_find_tag
92232
 
+(struct sieve_validator *valdtr, struct sieve_command_context *cmd, 
92233
 
+       struct sieve_ast_argument *arg, int *id_code) 
92234
 
+{
92235
 
+       struct sieve_command_registration *cmd_reg = cmd->cmd_reg;
92236
 
+       const char *tag = sieve_ast_argument_tag(arg);
92237
 
+       unsigned int i;
92238
 
+                       
92239
 
+       if ( id_code != NULL )
92240
 
+               *id_code = 0;
92241
 
+       
92242
 
+       /* First check normal tags */
92243
 
+       if ( array_is_created(&cmd_reg->normal_tags) ) {
92244
 
+               for ( i = 0; i < array_count(&cmd_reg->normal_tags); i++ ) {
92245
 
+                       struct sieve_tag_registration * const *reg =
92246
 
+                               array_idx(&cmd_reg->normal_tags, i);
92247
 
+
92248
 
+                       if ( (*reg)->tag != NULL && strcasecmp((*reg)->identifier,tag) == 0) {
92249
 
+                               if ( id_code != NULL )                          
92250
 
+                                       *id_code = (*reg)->id_code;
92251
 
+
92252
 
+                               return (*reg)->tag;
92253
 
+                       }
92254
 
+               }
92255
 
+       }       
92256
 
+  
92257
 
+       /* Not found so far, try the instanced tags */
92258
 
+       if ( array_is_created(&cmd_reg->instanced_tags) ) {
92259
 
+               for ( i = 0; i < array_count(&cmd_reg->instanced_tags); i++ ) {
92260
 
+                       struct sieve_tag_registration * const *reg = 
92261
 
+                               array_idx(&cmd_reg->instanced_tags, i);
92262
 
+       
92263
 
+                       if ( (*reg)->tag != NULL && 
92264
 
+                               (*reg)->tag->is_instance_of(valdtr, cmd, arg) ) {
92265
 
+                               if ( id_code != NULL )
92266
 
+                                       *id_code = (*reg)->id_code;
92267
 
+                               
92268
 
+                               return (*reg)->tag;
92269
 
+                       }
92270
 
+               }
92271
 
+       }
92272
 
+       
92273
 
+       return NULL;
92274
 
+}
92275
 
+
92276
 
+static const struct sieve_argument *sieve_validator_find_tag_by_identifier
92277
 
+(struct sieve_validator *valdtr, struct sieve_command_context *cmd, 
92278
 
+       const char *tag) 
92279
 
+{
92280
 
+       struct sieve_ast_argument *arg;
92281
 
+
92282
 
+       /* Construct dummy argument */
92283
 
+       arg = t_new(struct sieve_ast_argument, 1);
92284
 
+       arg->type = SAAT_TAG;
92285
 
+       arg->_value.tag = tag; 
92286
 
+
92287
 
+       return sieve_validator_find_tag(valdtr, cmd, arg, NULL);  
92288
 
+}
92289
 
+
92290
 
+/* 
92291
 
+ * Extension support 
92292
 
+ */
92293
 
+
92294
 
+const struct sieve_extension *sieve_validator_extension_load
92295
 
+(struct sieve_validator *valdtr, struct sieve_command_context *cmd,
92296
 
+       struct sieve_ast_argument *ext_arg, string_t *ext_name) 
92297
 
+{
92298
 
+       int ext_id;
92299
 
+       struct sieve_validator_extension_reg *reg;
92300
 
+       const struct sieve_extension *ext;
92301
 
+       const char *name = str_c(ext_name);
92302
 
+
92303
 
+       if ( str_len(ext_name) > 128 ) {
92304
 
+               sieve_argument_validate_error(valdtr, ext_arg, 
92305
 
+                       "%s %s: unknown Sieve capability '%s' (name is impossibly long)",
92306
 
+                       cmd->command->identifier, sieve_command_type_name(cmd->command),
92307
 
+                       str_sanitize(name, 128));
92308
 
+               return NULL;
92309
 
+       }
92310
 
+
92311
 
+       ext = sieve_extension_get_by_name(name); 
92312
 
+       
92313
 
+       if ( ext == NULL ) {
92314
 
+               unsigned int i;
92315
 
+               bool core_test = FALSE;
92316
 
+               bool core_command = FALSE;
92317
 
+
92318
 
+               for ( i = 0; !core_command && i < sieve_core_commands_count; i++ ) {
92319
 
+                       if ( strcasecmp(sieve_core_commands[i]->identifier, name) == 0 )
92320
 
+                               core_command = TRUE;
92321
 
+               }
92322
 
+
92323
 
+               for ( i = 0; !core_test && i < sieve_core_tests_count; i++ ) {
92324
 
+                       if ( strcasecmp(sieve_core_tests[i]->identifier, name) == 0 )
92325
 
+                               core_test = TRUE;
92326
 
+               }
92327
 
+
92328
 
+               if ( core_test || core_command ) {
92329
 
+                       sieve_argument_validate_error(valdtr, ext_arg,
92330
 
+                "%s %s: '%s' is not known as a Sieve capability, "
92331
 
+                               "but it is known as a Sieve %s that is always available",
92332
 
+                cmd->command->identifier, sieve_command_type_name(cmd->command),
92333
 
+                name, ( core_test ? "test" : "command" ));
92334
 
+               } else {
92335
 
+                       sieve_argument_validate_error(valdtr, ext_arg,
92336
 
+                               "%s %s: unknown Sieve capability '%s'", 
92337
 
+                               cmd->command->identifier, sieve_command_type_name(cmd->command),
92338
 
+                               name);
92339
 
+               }
92340
 
+               return NULL;
92341
 
+       }
92342
 
+       
92343
 
+       sieve_ast_extension_link(valdtr->ast, ext);
92344
 
+
92345
 
+       if ( ext->validator_load != NULL && !ext->validator_load(valdtr) ) {
92346
 
+               sieve_argument_validate_error(valdtr, ext_arg, 
92347
 
+                       "%s %s: failed to load Sieve capability '%s'",
92348
 
+                       cmd->command->identifier, sieve_command_type_name(cmd->command),
92349
 
+                       ext->name);
92350
 
+               return NULL;
92351
 
+       }
92352
 
+
92353
 
+       /* Register extension no matter what and store the AST argument registering it */
92354
 
+       ext_id = SIEVE_EXT_ID(ext);
92355
 
+       if ( ext_id >= 0 ) {
92356
 
+               reg = array_idx_modifiable(&valdtr->extensions, (unsigned int) ext_id);
92357
 
+               reg->arg = ext_arg;
92358
 
+               reg->loaded = TRUE;
92359
 
+       }
92360
 
+
92361
 
+       return ext;
92362
 
+}
92363
 
+
92364
 
+void sieve_validator_extension_register
92365
 
+(struct sieve_validator *valdtr, 
92366
 
+       const struct sieve_validator_extension *val_ext, void *context)
92367
 
+{
92368
 
+       struct sieve_validator_extension_reg *reg;
92369
 
+       int ext_id = SIEVE_EXT_ID(val_ext->ext);
92370
 
+
92371
 
+       if ( ext_id < 0 ) return;
92372
 
+       
92373
 
+       reg = array_idx_modifiable(&valdtr->extensions, (unsigned int) ext_id);
92374
 
+       reg->val_ext = val_ext;
92375
 
+       reg->context = context;
92376
 
+}
92377
 
+
92378
 
+bool sieve_validator_extension_loaded
92379
 
+       (struct sieve_validator *valdtr, const struct sieve_extension *ext)
92380
 
+{
92381
 
+       int ext_id = SIEVE_EXT_ID(ext);
92382
 
+       const struct sieve_validator_extension_reg *reg;
92383
 
+
92384
 
+       if ( ext_id < 0 || ext_id >= (int) array_count(&valdtr->extensions))
92385
 
+               return FALSE;
92386
 
+
92387
 
+       reg = array_idx(&valdtr->extensions, (unsigned int) ext_id);
92388
 
+
92389
 
+       return ( reg->loaded );
92390
 
+}
92391
 
+
92392
 
+void sieve_validator_extension_set_context
92393
 
+(struct sieve_validator *valdtr, const struct sieve_extension *ext, 
92394
 
+       void *context)
92395
 
+{
92396
 
+       struct sieve_validator_extension_reg *reg;
92397
 
+       int ext_id = SIEVE_EXT_ID(ext);
92398
 
+
92399
 
+       if ( ext_id < 0 ) return;
92400
 
+       
92401
 
+       reg = array_idx_modifiable(&valdtr->extensions, (unsigned int) ext_id);
92402
 
+       reg->context = context;
92403
 
+}
92404
 
+
92405
 
+void *sieve_validator_extension_get_context
92406
 
+(struct sieve_validator *valdtr, const struct sieve_extension *ext) 
92407
 
+{
92408
 
+       int ext_id = SIEVE_EXT_ID(ext);
92409
 
+       const struct sieve_validator_extension_reg *reg;
92410
 
+
92411
 
+       if  ( ext_id < 0 || ext_id >= (int) array_count(&valdtr->extensions) )
92412
 
+               return NULL;
92413
 
+       
92414
 
+       reg = array_idx(&valdtr->extensions, (unsigned int) ext_id);            
92415
 
+
92416
 
+       return reg->context;
92417
 
+}
92418
 
+
92419
 
+/* 
92420
 
+ * Overriding the default literal arguments
92421
 
+ */
92422
 
+
92423
 
+void sieve_validator_argument_override
92424
 
+(struct sieve_validator *validator, enum sieve_argument_type type, 
92425
 
+       const struct sieve_argument *argument)
92426
 
+{
92427
 
+       struct sieve_default_argument *arg;
92428
 
+       
92429
 
+       if ( validator->default_arguments[type].argument != NULL ) {
92430
 
+               arg = p_new(validator->pool, struct sieve_default_argument, 1);
92431
 
+               *arg = validator->default_arguments[type];      
92432
 
+               
92433
 
+               validator->default_arguments[type].overrides = arg;
92434
 
+       }
92435
 
+       
92436
 
+       validator->default_arguments[type].argument = argument;
92437
 
+}
92438
 
+
92439
 
+static bool sieve_validator_argument_default_activate
92440
 
+(struct sieve_validator *validator, struct sieve_command_context *cmd,
92441
 
+       struct sieve_default_argument *defarg, struct sieve_ast_argument *arg)
92442
 
+{
92443
 
+       bool result = TRUE;
92444
 
+       struct sieve_default_argument *prev_defarg;
92445
 
+       
92446
 
+       prev_defarg = validator->current_defarg;
92447
 
+       validator->current_defarg = defarg;
92448
 
+       
92449
 
+       arg->argument = defarg->argument;
92450
 
+       if (defarg->argument != NULL && defarg->argument->validate != NULL )
92451
 
+               result = defarg->argument->validate(validator, &arg, cmd); 
92452
 
+               
92453
 
+       validator->current_defarg = prev_defarg;        
92454
 
+               
92455
 
+       return result;
92456
 
+}
92457
 
+
92458
 
+bool sieve_validator_argument_activate_super
92459
 
+(struct sieve_validator *validator, struct sieve_command_context *cmd, 
92460
 
+       struct sieve_ast_argument *arg, bool constant ATTR_UNUSED)
92461
 
+{
92462
 
+       struct sieve_default_argument *defarg;
92463
 
+
92464
 
+       if ( validator->current_defarg == NULL ||       
92465
 
+               validator->current_defarg->overrides == NULL )
92466
 
+               return FALSE;
92467
 
+       
92468
 
+       if ( validator->current_defarg->overrides->argument == &string_argument ) {
92469
 
+               switch ( validator->current_defarg_type) {
92470
 
+               case SAT_CONST_STRING:
92471
 
+                       if ( !validator->current_defarg_constant ) {
92472
 
+                               validator->current_defarg_type = SAT_VAR_STRING;
92473
 
+                               defarg = &validator->default_arguments[SAT_VAR_STRING];
92474
 
+                       } else
92475
 
+                               defarg = validator->current_defarg->overrides;
92476
 
+                       break;
92477
 
+               case SAT_VAR_STRING:
92478
 
+                       defarg = validator->current_defarg->overrides;
92479
 
+                       break;
92480
 
+               default:
92481
 
+                       return FALSE;
92482
 
+               }
92483
 
+       } else
92484
 
+               defarg = validator->current_defarg->overrides;
92485
 
+       
92486
 
+       return sieve_validator_argument_default_activate
92487
 
+               (validator, cmd, defarg, arg);
92488
 
+}
92489
 
+
92490
 
+/* 
92491
 
+ * Argument Validation API 
92492
 
+ */
92493
 
+
92494
 
+bool sieve_validator_argument_activate
92495
 
+(struct sieve_validator *validator, struct sieve_command_context *cmd, 
92496
 
+       struct sieve_ast_argument *arg, bool constant)
92497
 
+{
92498
 
+       struct sieve_default_argument *defarg;
92499
 
+       
92500
 
+       switch ( sieve_ast_argument_type(arg) ) {
92501
 
+       case SAAT_NUMBER:       
92502
 
+               validator->current_defarg_type = SAT_NUMBER;
92503
 
+               break;
92504
 
+       case SAAT_STRING:
92505
 
+               validator->current_defarg_type = SAT_CONST_STRING;
92506
 
+               break;
92507
 
+       case SAAT_STRING_LIST:
92508
 
+               validator->current_defarg_type = SAT_STRING_LIST;
92509
 
+               break;
92510
 
+       default:
92511
 
+               return FALSE;
92512
 
+       }
92513
 
+
92514
 
+       validator->current_defarg_constant = constant;
92515
 
+       defarg = &validator->default_arguments[validator->current_defarg_type];
92516
 
+
92517
 
+       if ( !constant && defarg->argument == &string_argument ) {
92518
 
+               validator->current_defarg_type = SAT_VAR_STRING;
92519
 
+               defarg = &validator->default_arguments[SAT_VAR_STRING];
92520
 
+       }
92521
 
+       
92522
 
+       return sieve_validator_argument_default_activate(validator, cmd, defarg, arg);
92523
 
+}
92524
 
+
92525
 
+bool sieve_validate_positional_argument
92526
 
+(struct sieve_validator *validator, struct sieve_command_context *cmd,
92527
 
+       struct sieve_ast_argument *arg, const char *arg_name, unsigned int arg_pos,
92528
 
+       enum sieve_ast_argument_type req_type)
92529
 
+{
92530
 
+       if ( sieve_ast_argument_type(arg) != req_type && 
92531
 
+               (sieve_ast_argument_type(arg) != SAAT_STRING || 
92532
 
+                       req_type != SAAT_STRING_LIST) ) 
92533
 
+       {
92534
 
+               sieve_argument_validate_error(validator, arg, 
92535
 
+                       "the %s %s expects %s as argument %d (%s), but %s was found", 
92536
 
+                       cmd->command->identifier, sieve_command_type_name(cmd->command), 
92537
 
+                       sieve_ast_argument_type_name(req_type),
92538
 
+                       arg_pos, arg_name, sieve_ast_argument_name(arg));
92539
 
+               return FALSE; 
92540
 
+       }
92541
 
+       
92542
 
+       return TRUE;
92543
 
+}
92544
 
+
92545
 
+bool sieve_validate_tag_parameter
92546
 
+(struct sieve_validator *validator, struct sieve_command_context *cmd,
92547
 
+       struct sieve_ast_argument *tag, struct sieve_ast_argument *param,
92548
 
+       enum sieve_ast_argument_type req_type)
92549
 
+{
92550
 
+       if ( param == NULL ) {
92551
 
+               sieve_argument_validate_error(validator, tag, 
92552
 
+                       "the :%s tag for the %s %s requires %s as parameter, "
92553
 
+                       "but no more arguments were found", sieve_ast_argument_tag(tag), 
92554
 
+                       cmd->command->identifier, sieve_command_type_name(cmd->command),
92555
 
+                       sieve_ast_argument_type_name(req_type));
92556
 
+               return FALSE;   
92557
 
+       }
92558
 
+
92559
 
+       if ( sieve_ast_argument_type(param) != req_type && 
92560
 
+               (sieve_ast_argument_type(param) != SAAT_STRING || 
92561
 
+                       req_type != SAAT_STRING_LIST) ) 
92562
 
+       {
92563
 
+               sieve_argument_validate_error(validator, param, 
92564
 
+                       "the :%s tag for the %s %s requires %s as parameter, "
92565
 
+                       "but %s was found", sieve_ast_argument_tag(tag), 
92566
 
+                       cmd->command->identifier, sieve_command_type_name(cmd->command),
92567
 
+                       sieve_ast_argument_type_name(req_type), sieve_ast_argument_name(param));
92568
 
+               return FALSE;
92569
 
+       }
92570
 
+
92571
 
+       param->arg_id_code = tag->arg_id_code;
92572
 
+
92573
 
+       return sieve_validator_argument_activate(validator, cmd, param, FALSE);
92574
 
+}
92575
 
+
92576
 
+/* 
92577
 
+ * Command argument validation 
92578
 
+ */
92579
 
+
92580
 
+static bool sieve_validate_command_arguments
92581
 
+(struct sieve_validator *validator, struct sieve_command_context *cmd) 
92582
 
+{
92583
 
+       int arg_count = cmd->command->positional_arguments;
92584
 
+       int real_count = 0;
92585
 
+       struct sieve_ast_argument *arg;
92586
 
+       struct sieve_command_registration *cmd_reg = cmd->cmd_reg;
92587
 
+
92588
 
+       /* Validate any tags that might be present */
92589
 
+       arg = sieve_ast_argument_first(cmd->ast_node);
92590
 
+               
92591
 
+       /* Visit tagged and optional arguments */
92592
 
+       while ( sieve_ast_argument_type(arg) == SAAT_TAG ) {
92593
 
+               int id_code;
92594
 
+               struct sieve_ast_argument *parg; 
92595
 
+               const struct sieve_argument *tag = 
92596
 
+                       sieve_validator_find_tag(validator, cmd, arg, &id_code);
92597
 
+               
92598
 
+               if ( tag == NULL ) {
92599
 
+                       sieve_argument_validate_error(validator, arg, 
92600
 
+                               "unknown tagged argument ':%s' for the %s %s "
92601
 
+                               "(reported only once at first occurence)",
92602
 
+                               sieve_ast_argument_tag(arg), cmd->command->identifier, 
92603
 
+                               sieve_command_type_name(cmd->command));
92604
 
+                       sieve_validator_register_unknown_tag
92605
 
+                               (validator, cmd_reg, sieve_ast_argument_tag(arg));
92606
 
+                       return FALSE;                                   
92607
 
+               }
92608
 
+               
92609
 
+               /* Check whether previously tagged as unknown */
92610
 
+               if ( tag->identifier != NULL && *(tag->identifier) == '\0' ) 
92611
 
+                       return FALSE;
92612
 
+               
92613
 
+               /* Assign the tagged argument type to the ast for later reference 
92614
 
+                * (in generator) 
92615
 
+                */
92616
 
+               arg->argument = tag;
92617
 
+               arg->arg_id_code = id_code;  
92618
 
+                       
92619
 
+               /* Scan backwards for any duplicates */
92620
 
+               parg = sieve_ast_argument_prev(arg);
92621
 
+               while ( parg != NULL ) {
92622
 
+                       if ( (sieve_ast_argument_type(parg) == SAAT_TAG && parg->argument == tag) 
92623
 
+                               || (id_code > 0 && parg->arg_id_code == id_code) ) 
92624
 
+                       {
92625
 
+                               const char *tag_id = sieve_ast_argument_tag(arg);
92626
 
+                               const char *tag_desc =
92627
 
+                                       strcmp(tag->identifier, tag_id) != 0 ?
92628
 
+                                       t_strdup_printf("%s argument (:%s)", tag->identifier, tag_id) : 
92629
 
+                                       t_strdup_printf(":%s argument", tag->identifier);        
92630
 
+                               
92631
 
+                               sieve_argument_validate_error(validator, arg, 
92632
 
+                                       "encountered duplicate %s for the %s %s",
92633
 
+                                       tag_desc, cmd->command->identifier, 
92634
 
+                                       sieve_command_type_name(cmd->command));
92635
 
+                                       
92636
 
+                               return FALSE;   
92637
 
+                       }
92638
 
+                       
92639
 
+                       parg = sieve_ast_argument_prev(parg);
92640
 
+               }
92641
 
+               
92642
 
+               /* Call the validation function for the tag (if present)
92643
 
+                *   Fail if the validation fails:
92644
 
+                *     Let's not whine multiple times about a single command having multiple 
92645
 
+                *     bad arguments...
92646
 
+                */ 
92647
 
+               if ( tag->validate != NULL ) { 
92648
 
+                       if ( !tag->validate(validator, &arg, cmd) ) 
92649
 
+                               return FALSE;
92650
 
+               } else
92651
 
+                       arg = sieve_ast_argument_next(arg);
92652
 
+       } 
92653
 
+       
92654
 
+       /* Remaining arguments should be positional (tags are not allowed here) */
92655
 
+       cmd->first_positional = arg;
92656
 
+       
92657
 
+       while ( arg != NULL ) {
92658
 
+               if ( sieve_ast_argument_type(arg) == SAAT_TAG ) {
92659
 
+                       sieve_argument_validate_error(validator, arg, 
92660
 
+                               "encountered an unexpected tagged argument ':%s' "
92661
 
+                               "while validating positional arguments for the %s %s",
92662
 
+                               sieve_ast_argument_tag(arg), cmd->command->identifier, 
92663
 
+                               sieve_command_type_name(cmd->command));
92664
 
+                       return FALSE;
92665
 
+               }
92666
 
+               
92667
 
+               real_count++;
92668
 
+        
92669
 
+               arg = sieve_ast_argument_next(arg);
92670
 
+       }
92671
 
+       
92672
 
+       /* Check the required count versus the real number of arguments */
92673
 
+       if ( arg_count >= 0 && real_count != arg_count ) {
92674
 
+               sieve_command_validate_error(validator, cmd, 
92675
 
+                       "the %s %s requires %d positional argument(s), but %d is/are specified",
92676
 
+                       cmd->command->identifier, sieve_command_type_name(cmd->command), 
92677
 
+                       arg_count, real_count);
92678
 
+               return FALSE;
92679
 
+       }
92680
 
+       
92681
 
+       /* Call initial validation for persistent arguments */
92682
 
+       if ( array_is_created(&cmd_reg->persistent_tags) ) {
92683
 
+               unsigned int i;
92684
 
+       
92685
 
+               for ( i = 0; i < array_count(&cmd_reg->persistent_tags); i++ ) {
92686
 
+                       struct sieve_tag_registration * const *reg = 
92687
 
+                               array_idx(&cmd_reg->persistent_tags, i);
92688
 
+                       const struct sieve_argument *tag = (*reg)->tag;
92689
 
+  
92690
 
+                       if ( tag != NULL && tag->validate_persistent != NULL ) { /* To be sure */
92691
 
+                               if ( !tag->validate_persistent(validator, cmd) )
92692
 
+                                       return FALSE;
92693
 
+                       }
92694
 
+               }
92695
 
+       }
92696
 
+
92697
 
+       return TRUE;
92698
 
+}
92699
 
+
92700
 
+static bool sieve_validate_arguments_context
92701
 
+(struct sieve_validator *validator, struct sieve_command_context *cmd)
92702
 
+{ 
92703
 
+       struct sieve_ast_argument *arg = 
92704
 
+               sieve_command_first_argument(cmd);
92705
 
+       
92706
 
+       while ( arg != NULL ) {
92707
 
+               const struct sieve_argument *argument = arg->argument;
92708
 
+               
92709
 
+               if ( argument != NULL && argument->validate_context != NULL ) { 
92710
 
+                       if ( !argument->validate_context(validator, arg, cmd) ) 
92711
 
+                               return FALSE;
92712
 
+               }
92713
 
+               
92714
 
+               arg = sieve_ast_argument_next(arg);
92715
 
+       }
92716
 
+
92717
 
+       return TRUE;
92718
 
+}
92719
 
92720
 
+/* 
92721
 
+ * Command Validation API 
92722
 
+ */ 
92723
 
+                 
92724
 
+static bool sieve_validate_command_subtests
92725
 
+(struct sieve_validator *valdtr, struct sieve_command_context *cmd, 
92726
 
+       const unsigned int count) 
92727
 
+{
92728
 
+       switch ( count ) {
92729
 
+       
92730
 
+       case 0:
92731
 
+               if ( sieve_ast_test_count(cmd->ast_node) > 0 ) {
92732
 
+                       /* Unexpected command specified */
92733
 
+                       enum sieve_command_type ctype = SCT_NONE;
92734
 
+                       struct sieve_command_registration *cmd_reg;
92735
 
+                       struct sieve_ast_node *test = sieve_ast_test_first(cmd->ast_node);
92736
 
+
92737
 
+                       cmd_reg = sieve_validator_find_command_registration
92738
 
+                               (valdtr, test->identifier);
92739
 
+       
92740
 
+                       /* First check what we are dealing with */
92741
 
+                       if ( cmd_reg != NULL && cmd_reg->command != NULL )
92742
 
+                               ctype = cmd_reg->command->type;
92743
 
+
92744
 
+                       switch ( ctype ) {
92745
 
+                       case SCT_TEST: /* Spurious test */
92746
 
+                       case SCT_HYBRID:
92747
 
+                               sieve_command_validate_error(valdtr, cmd, 
92748
 
+                                       "the %s %s accepts no sub-tests, but tests are specified", 
92749
 
+                                       cmd->command->identifier, sieve_command_type_name(cmd->command));
92750
 
+                               break;
92751
 
+
92752
 
+                       case SCT_NONE: /* Unknown command */
92753
 
+
92754
 
+                               /* Is it perhaps a tag for which the ':' was omitted ? */
92755
 
+                               if (    sieve_validator_find_tag_by_identifier
92756
 
+                                       (valdtr, cmd, test->identifier) != NULL ) {
92757
 
+                                       sieve_command_validate_error(valdtr, cmd, 
92758
 
+                                               "missing colon ':' before ':%s' tag in %s %s", test->identifier, 
92759
 
+                                               cmd->command->identifier, sieve_command_type_name(cmd->command));
92760
 
+                                       break;
92761
 
+                               } 
92762
 
+                               /* Fall through */
92763
 
+                       
92764
 
+                       case SCT_COMMAND:
92765
 
+                               sieve_command_validate_error(valdtr, cmd, 
92766
 
+                                       "missing semicolon ';' after %s %s", 
92767
 
+                                       cmd->command->identifier, sieve_command_type_name(cmd->command));
92768
 
+                               break;
92769
 
+                       }
92770
 
+                       return FALSE;
92771
 
+               }
92772
 
+               break;
92773
 
+       case 1:
92774
 
+               if ( sieve_ast_test_count(cmd->ast_node) == 0 ) {
92775
 
+                       sieve_command_validate_error(valdtr, cmd, 
92776
 
+                               "the %s %s requires one sub-test, but none is specified", 
92777
 
+                               cmd->command->identifier, sieve_command_type_name(cmd->command));
92778
 
+                               
92779
 
+                       return FALSE;
92780
 
+                       
92781
 
+               } else if ( sieve_ast_test_count(cmd->ast_node) > 1 || 
92782
 
+                       cmd->ast_node->test_list ) {
92783
 
+                       
92784
 
+                       sieve_command_validate_error(valdtr, cmd, 
92785
 
+                               "the %s %s requires one sub-test, but a list of tests is specified", 
92786
 
+                               cmd->command->identifier, sieve_command_type_name(cmd->command));
92787
 
+                               
92788
 
+                       return FALSE;
92789
 
+               }
92790
 
+               break;
92791
 
+               
92792
 
+       default:
92793
 
+               if ( sieve_ast_test_count(cmd->ast_node) == 0 ) {
92794
 
+                       sieve_command_validate_error(valdtr, cmd, 
92795
 
+                               "the %s %s requires a list of sub-tests, but none is specified", 
92796
 
+                               cmd->command->identifier, sieve_command_type_name(cmd->command));
92797
 
+                       
92798
 
+                       return FALSE;
92799
 
+                       
92800
 
+               } else if ( sieve_ast_test_count(cmd->ast_node) == 1 && 
92801
 
+                       !cmd->ast_node->test_list ) {
92802
 
+                       
92803
 
+                       sieve_command_validate_error(valdtr, cmd, 
92804
 
+                               "the %s %s requires a list of sub-tests, "
92805
 
+                               "but a single test is specified", 
92806
 
+                               cmd->command->identifier, sieve_command_type_name(cmd->command) );
92807
 
+                       
92808
 
+                       return FALSE;
92809
 
+               }
92810
 
+               break;          
92811
 
+       }
92812
 
+
92813
 
+       return TRUE;
92814
 
+}
92815
 
+
92816
 
+static bool sieve_validate_command_block
92817
 
+(struct sieve_validator *validator, struct sieve_command_context *cmd, 
92818
 
+       bool block_allowed, bool block_required) 
92819
 
+{
92820
 
+       i_assert( cmd->ast_node->type == SAT_COMMAND );
92821
 
+       
92822
 
+       if ( block_required ) {
92823
 
+               if ( !cmd->ast_node->block ) {
92824
 
+                       sieve_command_validate_error(validator, cmd, 
92825
 
+                               "the %s command requires a command block, but it is missing", 
92826
 
+                               cmd->command->identifier);
92827
 
+                       
92828
 
+                       return FALSE;
92829
 
+               }
92830
 
+       } else if ( !block_allowed && cmd->ast_node->block ) {
92831
 
+               sieve_command_validate_error(validator, cmd, 
92832
 
+                       "the %s command does not accept a command block, "
92833
 
+                       "but one is specified anyway", 
92834
 
+                       cmd->command->identifier );
92835
 
+               
92836
 
+               return FALSE;
92837
 
+       }
92838
 
+       
92839
 
+       return TRUE;
92840
 
+} 
92841
 
+
92842
 
+/* 
92843
 
+ * AST Validation 
92844
 
+ */
92845
 
+
92846
 
+static bool sieve_validate_test_list
92847
 
+       (struct sieve_validator *validator, struct sieve_ast_node *test_list); 
92848
 
+static bool sieve_validate_block
92849
 
+       (struct sieve_validator *validator, struct sieve_ast_node *block);
92850
 
+static bool sieve_validate_command
92851
 
+       (struct sieve_validator *validator, struct sieve_ast_node *cmd_node);
92852
 
+       
92853
 
+static bool sieve_validate_command_context
92854
 
+(struct sieve_validator *valdtr, struct sieve_ast_node *cmd_node) 
92855
 
+{
92856
 
+       enum sieve_ast_type ast_type = sieve_ast_node_type(cmd_node);
92857
 
+       struct sieve_command_registration *cmd_reg;
92858
 
+       
92859
 
+       i_assert( ast_type == SAT_TEST || ast_type == SAT_COMMAND );
92860
 
+       
92861
 
+       /* Verify the command specified by this node */
92862
 
+       
92863
 
+       cmd_reg = sieve_validator_find_command_registration
92864
 
+               (valdtr, cmd_node->identifier);
92865
 
+       
92866
 
+       if ( cmd_reg != NULL && cmd_reg->command != NULL ) {
92867
 
+               const struct sieve_command *command = cmd_reg->command;
92868
 
+
92869
 
+               /* Identifier = "" when the command was previously marked as unknown */
92870
 
+               if ( *(command->identifier) != '\0' ) {
92871
 
+                       if ( (command->type == SCT_COMMAND && ast_type == SAT_TEST)
92872
 
+                               || (command->type == SCT_TEST && ast_type == SAT_COMMAND) ) {
92873
 
+                               sieve_validator_error(
92874
 
+                                       valdtr, cmd_node->source_line, "attempted to use %s '%s' as %s", 
92875
 
+                                       sieve_command_type_name(command), cmd_node->identifier,
92876
 
+                                       sieve_ast_type_name(ast_type));
92877
 
+                       
92878
 
+                               return FALSE;
92879
 
+                       } 
92880
 
+                        
92881
 
+                       struct sieve_command_context *ctx = 
92882
 
+                               sieve_command_context_create(cmd_node, command, cmd_reg); 
92883
 
+                       cmd_node->context = ctx;
92884
 
+
92885
 
+               } else {
92886
 
+                       return FALSE;
92887
 
+               }
92888
 
+
92889
 
+       }       else {
92890
 
+               sieve_validator_error(
92891
 
+                       valdtr, cmd_node->source_line, 
92892
 
+                       "unknown %s '%s' (only reported once at first occurence)", 
92893
 
+                       sieve_ast_type_name(ast_type), cmd_node->identifier);
92894
 
+                       
92895
 
+               sieve_validator_register_unknown_command(valdtr, cmd_node->identifier);
92896
 
+               
92897
 
+               return FALSE;
92898
 
+       }
92899
 
+
92900
 
+       return TRUE;
92901
 
+}
92902
 
+
92903
 
+static bool sieve_validate_command
92904
 
+(struct sieve_validator *valdtr, struct sieve_ast_node *cmd_node) 
92905
 
+{
92906
 
+       enum sieve_ast_type ast_type = sieve_ast_node_type(cmd_node);
92907
 
+       struct sieve_command_context *ctx = cmd_node->context;
92908
 
+       const struct sieve_command *command = ( ctx != NULL ? ctx->command : NULL );
92909
 
+       bool result = TRUE;
92910
 
+       
92911
 
+       i_assert( ast_type == SAT_TEST || ast_type == SAT_COMMAND );
92912
 
+
92913
 
+       if ( command != NULL && *(command->identifier) != '\0' ) {
92914
 
+               
92915
 
+               if ( command->pre_validate == NULL 
92916
 
+                       || command->pre_validate(valdtr, ctx) ) {
92917
 
+       
92918
 
+                       /* Check argument syntax */
92919
 
+                       if ( !sieve_validate_command_arguments(valdtr, ctx) ) {
92920
 
+                               result = FALSE;
92921
 
+
92922
 
+                               /* A missing ':' causes a tag to become a test. This can be the cause
92923
 
+                                * of the arguments validation failing. Therefore we must produce an
92924
 
+                                * error for the sub-tests as well if appropriate.
92925
 
+                                */
92926
 
+                               (void)sieve_validate_command_subtests(valdtr, ctx, command->subtests);
92927
 
+
92928
 
+                       } else if (
92929
 
+                               !sieve_validate_command_subtests(valdtr, ctx, command->subtests) || 
92930
 
+                               (ast_type == SAT_COMMAND && !sieve_validate_command_block
92931
 
+                                       (valdtr, ctx, command->block_allowed, command->block_required)) ) {
92932
 
+
92933
 
+                               result = FALSE;
92934
 
+
92935
 
+                       } else {
92936
 
+                               /* Call command validation function if specified */
92937
 
+                               if ( command->validate != NULL )
92938
 
+                                       result = command->validate(valdtr, ctx) && result;
92939
 
+                       }
92940
 
+               } else {
92941
 
+                       /* If pre-validation fails, don't bother to validate further 
92942
 
+                        * as context might be missing and doing so is not very useful for 
92943
 
+                        * further error reporting anyway
92944
 
+                        */
92945
 
+                       return FALSE;
92946
 
+               }
92947
 
+                       
92948
 
+               result = result && sieve_validate_arguments_context(valdtr, ctx);
92949
 
+                                                               
92950
 
+       }
92951
 
+
92952
 
+       /*  
92953
 
+        * Descend further into the AST 
92954
 
+        */
92955
 
+       
92956
 
+       if ( command != NULL ) {
92957
 
+               /* Tests */
92958
 
+               if ( command->subtests > 0 && 
92959
 
+                       (result || sieve_errors_more_allowed(valdtr->ehandler)) )
92960
 
+                       result = sieve_validate_test_list(valdtr, cmd_node) && result;
92961
 
+
92962
 
+               /* Command block */
92963
 
+               if ( command->block_allowed && ast_type == SAT_COMMAND && 
92964
 
+                       (result || sieve_errors_more_allowed(valdtr->ehandler)) )
92965
 
+                       result = sieve_validate_block(valdtr, cmd_node) && result;
92966
 
+       }
92967
 
+       
92968
 
+       return result;
92969
 
+}
92970
 
+
92971
 
+static bool sieve_validate_test_list
92972
 
+(struct sieve_validator *valdtr, struct sieve_ast_node *test_list) 
92973
 
+{
92974
 
+       bool result = TRUE;
92975
 
+       struct sieve_ast_node *test;
92976
 
+
92977
 
+       test = sieve_ast_test_first(test_list);
92978
 
+       while ( test != NULL 
92979
 
+               && (result || sieve_errors_more_allowed(valdtr->ehandler)) ) {
92980
 
+       
92981
 
+               result = 
92982
 
+                       sieve_validate_command_context(valdtr, test) && 
92983
 
+                       sieve_validate_command(valdtr, test) &&
92984
 
+                       result; 
92985
 
+               
92986
 
+               test = sieve_ast_test_next(test);
92987
 
+       }               
92988
 
+       
92989
 
+       return result;
92990
 
+}
92991
 
+
92992
 
+static bool sieve_validate_block
92993
 
+(struct sieve_validator *valdtr, struct sieve_ast_node *block) 
92994
 
+{
92995
 
+       bool result = TRUE, fatal = FALSE;
92996
 
+       struct sieve_ast_node *command, *next;
92997
 
+
92998
 
+       T_BEGIN {       
92999
 
+               command = sieve_ast_command_first(block);
93000
 
+               while ( !fatal &&  command != NULL
93001
 
+                       && (result || sieve_errors_more_allowed(valdtr->ehandler)) ) {  
93002
 
+                       bool command_success;
93003
 
+
93004
 
+                       next = sieve_ast_command_next(command);
93005
 
+                       command_success = sieve_validate_command_context(valdtr, command);
93006
 
+                       result = command_success && result;     
93007
 
+
93008
 
+                       /* Check if this is the first non-require command */
93009
 
+                       if ( command_success && sieve_ast_node_type(block) == SAT_ROOT
93010
 
+                               && !valdtr->finished_require && command->context != NULL
93011
 
+                               && command->context->command != &cmd_require ) {
93012
 
+                               const struct sieve_validator_extension_reg *extrs;
93013
 
+                               unsigned int ext_count, i;
93014
 
+
93015
 
+                               valdtr->finished_require = TRUE;
93016
 
+
93017
 
+                               /* Validate all 'require'd extensions */
93018
 
+                               extrs = array_get(&valdtr->extensions, &ext_count);
93019
 
+                               for ( i = 0; i < ext_count; i++ ) {
93020
 
+                                       if ( extrs[i].val_ext != NULL 
93021
 
+                                               && extrs[i].val_ext->validate != NULL ) {
93022
 
+
93023
 
+                                               if ( !extrs[i].val_ext->validate
93024
 
+                                                       (valdtr, extrs[i].context, extrs[i].arg) )
93025
 
+                                               fatal = TRUE;
93026
 
+                                               break;
93027
 
+                                       } 
93028
 
+                               }
93029
 
+                       }
93030
 
+
93031
 
+                       result = !fatal && sieve_validate_command(valdtr, command) && result;
93032
 
+                       
93033
 
+                       command = next;
93034
 
+               }               
93035
 
+       } T_END;
93036
 
+       
93037
 
+       return result && !fatal;
93038
 
+}
93039
 
+
93040
 
+bool sieve_validator_run(struct sieve_validator *validator) 
93041
 
+{      
93042
 
+       return sieve_validate_block(validator, sieve_ast_root(validator->ast));
93043
 
+}
93044
 
+
93045
 
+/*
93046
 
+ * Validator object registry
93047
 
+ */
93048
 
+
93049
 
+struct sieve_validator_object_registry {
93050
 
+       struct sieve_validator *validator;
93051
 
+       ARRAY_DEFINE(registrations, const struct sieve_object *);
93052
 
+};
93053
 
+
93054
 
+struct sieve_validator_object_registry *sieve_validator_object_registry_get
93055
 
+(struct sieve_validator *validator, const struct sieve_extension *ext)
93056
 
+{
93057
 
+       return (struct sieve_validator_object_registry *) 
93058
 
+               sieve_validator_extension_get_context(validator, ext);
93059
 
+}
93060
 
+
93061
 
+void sieve_validator_object_registry_add
93062
 
+(struct sieve_validator_object_registry *regs, 
93063
 
+       const struct sieve_object *object) 
93064
 
+{
93065
 
+    array_append(&regs->registrations, &object, 1);
93066
 
+}
93067
 
+
93068
 
+const struct sieve_object *sieve_validator_object_registry_find
93069
 
+(struct sieve_validator_object_registry *regs, const char *identifier) 
93070
 
+{
93071
 
+       unsigned int i;
93072
 
+
93073
 
+       for ( i = 0; i < array_count(&regs->registrations); i++ ) {
93074
 
+               const struct sieve_object * const *obj = array_idx(&regs->registrations, i);
93075
 
+
93076
 
+               if ( strcasecmp((*obj)->identifier, identifier) == 0)
93077
 
+                       return *obj;
93078
 
+       }
93079
 
+
93080
 
+       return NULL;
93081
 
+}
93082
 
+
93083
 
+struct sieve_validator_object_registry *sieve_validator_object_registry_create
93084
 
+(struct sieve_validator *validator)
93085
 
+{
93086
 
+       pool_t pool = validator->pool;
93087
 
+       struct sieve_validator_object_registry *regs = 
93088
 
+               p_new(pool, struct sieve_validator_object_registry, 1);
93089
 
+       
93090
 
+       /* Setup registry */        
93091
 
+       p_array_init(&regs->registrations, validator->pool, 4);
93092
 
+
93093
 
+       regs->validator = validator;
93094
 
+
93095
 
+       return regs;
93096
 
+}
93097
 
+
93098
 
+struct sieve_validator_object_registry *sieve_validator_object_registry_init
93099
 
+(struct sieve_validator *validator, const struct sieve_extension *ext)
93100
 
+{
93101
 
+       struct sieve_validator_object_registry *regs = 
93102
 
+               sieve_validator_object_registry_create(validator);
93103
 
+       
93104
 
+       sieve_validator_extension_set_context(validator, ext, regs);
93105
 
+       return regs;
93106
 
+}
93107
 
+
93108
 
+
93109
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-validator.h dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-validator.h
93110
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/sieve-validator.h      1970-01-01 01:00:00.000000000 +0100
93111
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/sieve-validator.h       2009-04-18 09:35:33.000000000 +0200
93112
 
@@ -0,0 +1,164 @@
93113
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file 
93114
 
+ */
93115
 
93116
 
+#ifndef __SIEVE_VALIDATOR_H
93117
 
+#define __SIEVE_VALIDATOR_H
93118
 
+
93119
 
+#include "lib.h"
93120
 
+
93121
 
+#include "sieve-common.h"
93122
 
+
93123
 
+/*
93124
 
+ * Types
93125
 
+ */
93126
 
+
93127
 
+enum sieve_argument_type {
93128
 
+       SAT_NUMBER,
93129
 
+       SAT_CONST_STRING,
93130
 
+       SAT_VAR_STRING,
93131
 
+       SAT_STRING_LIST,
93132
 
+       
93133
 
+       SAT_COUNT
93134
 
+};
93135
 
+
93136
 
+struct sieve_command_registration;
93137
 
+
93138
 
+/*
93139
 
+ * Validator
93140
 
+ */
93141
 
93142
 
+struct sieve_validator;
93143
 
+
93144
 
+struct sieve_validator *sieve_validator_create
93145
 
+       (struct sieve_ast *ast, struct sieve_error_handler *ehandler);
93146
 
+void sieve_validator_free(struct sieve_validator **validator);
93147
 
+pool_t sieve_validator_pool(struct sieve_validator *validator);
93148
 
+
93149
 
+bool sieve_validator_run(struct sieve_validator *validator);
93150
 
+
93151
 
+/*
93152
 
+ * Accessors
93153
 
+ */
93154
 
93155
 
+struct sieve_error_handler *sieve_validator_error_handler
93156
 
+       (struct sieve_validator *validator);
93157
 
+struct sieve_ast *sieve_validator_ast
93158
 
+       (struct sieve_validator *validator);
93159
 
+struct sieve_script *sieve_validator_script
93160
 
+       (struct sieve_validator *validator);
93161
 
+
93162
 
+/*
93163
 
+ * Error handling
93164
 
+ */
93165
 
+
93166
 
+void sieve_validator_warning
93167
 
+       (struct sieve_validator *validator, unsigned int source_line, 
93168
 
+               const char *fmt, ...) ATTR_FORMAT(3, 4);
93169
 
+void sieve_validator_error
93170
 
+       (struct sieve_validator *validator, unsigned int source_line, 
93171
 
+               const char *fmt, ...) ATTR_FORMAT(3, 4);
93172
 
+void sieve_validator_critical
93173
 
+       (struct sieve_validator *validator, unsigned int source_line, 
93174
 
+               const char *fmt, ...) ATTR_FORMAT(3, 4);
93175
 
+               
93176
 
+/* 
93177
 
+ * Command/Test registry
93178
 
+ */
93179
 
93180
 
+void sieve_validator_register_command
93181
 
+       (struct sieve_validator *validator, const struct sieve_command *command);
93182
 
+const struct sieve_command *sieve_validator_find_command
93183
 
+       (struct sieve_validator *validator, const char *command);       
93184
 
+       
93185
 
+void sieve_validator_register_external_tag
93186
 
+       (struct sieve_validator *validator, const struct sieve_argument *tag, 
93187
 
+               const char *command, int id_code);
93188
 
+
93189
 
+/* 
93190
 
+ * Per-command tagged argument registry
93191
 
+ */
93192
 
+
93193
 
+void sieve_validator_register_tag
93194
 
+       (struct sieve_validator *validator, 
93195
 
+               struct sieve_command_registration *cmd_reg, 
93196
 
+               const struct sieve_argument *argument, int id_code);
93197
 
+void sieve_validator_register_persistent_tag
93198
 
+       (struct sieve_validator *validator, const struct sieve_argument *tag, 
93199
 
+               const char *command);
93200
 
+       
93201
 
+/*
93202
 
+ * Overriding the default literal arguments
93203
 
+ */    
93204
 
93205
 
+void sieve_validator_argument_override
93206
 
+(struct sieve_validator *validator, enum sieve_argument_type type, 
93207
 
+       const struct sieve_argument *argument);
93208
 
+bool sieve_validator_argument_activate_super
93209
 
+(struct sieve_validator *validator, struct sieve_command_context *cmd, 
93210
 
+       struct sieve_ast_argument *arg, bool constant);
93211
 
+               
93212
 
+/* 
93213
 
+ * Argument validation API
93214
 
+ */
93215
 
+
93216
 
+bool sieve_validate_positional_argument
93217
 
+       (struct sieve_validator *validator, struct sieve_command_context *cmd,
93218
 
+       struct sieve_ast_argument *arg, const char *arg_name, unsigned int arg_pos,
93219
 
+       enum sieve_ast_argument_type req_type);
93220
 
+bool sieve_validator_argument_activate
93221
 
+(struct sieve_validator *validator, struct sieve_command_context *cmd,
93222
 
+       struct sieve_ast_argument *arg, bool constant);
93223
 
+               
93224
 
+bool sieve_validate_tag_parameter
93225
 
+       (struct sieve_validator *validator, struct sieve_command_context *cmd,
93226
 
+       struct sieve_ast_argument *tag, struct sieve_ast_argument *param,
93227
 
+       enum sieve_ast_argument_type req_type);
93228
 
+       
93229
 
+/* 
93230
 
+ * Extension support
93231
 
+ */
93232
 
+
93233
 
+struct sieve_validator_extension {
93234
 
+       const struct sieve_extension *ext;      
93235
 
+
93236
 
+       bool (*validate)(struct sieve_validator *valdtr, void *context,
93237
 
+               struct sieve_ast_argument *require_arg);
93238
 
+
93239
 
+       void (*free)(struct sieve_validator *valdtr, void *context);
93240
 
+};
93241
 
+
93242
 
+const struct sieve_extension *sieve_validator_extension_load
93243
 
+       (struct sieve_validator *validator, struct sieve_command_context *cmd,
93244
 
+               struct sieve_ast_argument *ext_arg, string_t *ext_name); 
93245
 
+
93246
 
+void sieve_validator_extension_register
93247
 
+       (struct sieve_validator *valdtr, 
93248
 
+               const struct sieve_validator_extension *val_ext, void *context);
93249
 
+bool sieve_validator_extension_loaded
93250
 
+    (struct sieve_validator *valdtr, const struct sieve_extension *ext);
93251
 
+
93252
 
+void sieve_validator_extension_set_context
93253
 
+(struct sieve_validator *valdtr, const struct sieve_extension *ext, 
93254
 
+       void *context);
93255
 
+void *sieve_validator_extension_get_context
93256
 
+(struct sieve_validator *valdtr, const struct sieve_extension *ext);
93257
 
+
93258
 
+/*
93259
 
+ * Validator object registry
93260
 
+ */
93261
 
+
93262
 
+struct sieve_validator_object_registry;
93263
 
+
93264
 
+struct sieve_validator_object_registry *sieve_validator_object_registry_get
93265
 
+       (struct sieve_validator *validator, const struct sieve_extension *ext);
93266
 
+void sieve_validator_object_registry_add
93267
 
+       (struct sieve_validator_object_registry *regs,
93268
 
+               const struct sieve_object *object);
93269
 
+const struct sieve_object *sieve_validator_object_registry_find
93270
 
+       (struct sieve_validator_object_registry *regs, const char *identifier);
93271
 
+struct sieve_validator_object_registry *sieve_validator_object_registry_create
93272
 
+       (struct sieve_validator *validator);
93273
 
+struct sieve_validator_object_registry *sieve_validator_object_registry_init
93274
 
+       (struct sieve_validator *validator, const struct sieve_extension *ext);
93275
 
+
93276
 
+#endif /* __SIEVE_VALIDATOR_H */
93277
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/tst-address.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/tst-address.c
93278
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/tst-address.c  1970-01-01 01:00:00.000000000 +0100
93279
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/tst-address.c   2009-07-30 00:45:54.000000000 +0200
93280
 
@@ -0,0 +1,294 @@
93281
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
93282
 
+ */
93283
 
+
93284
 
+#include "lib.h"
93285
 
+#include "str-sanitize.h"
93286
 
+
93287
 
+#include "sieve-common.h"
93288
 
+#include "sieve-commands.h"
93289
 
+#include "sieve-code.h"
93290
 
+#include "sieve-comparators.h"
93291
 
+#include "sieve-match-types.h"
93292
 
+#include "sieve-address-parts.h"
93293
 
+#include "sieve-validator.h"
93294
 
+#include "sieve-generator.h"
93295
 
+#include "sieve-interpreter.h"
93296
 
+#include "sieve-dump.h"
93297
 
+#include "sieve-match.h"
93298
 
+
93299
 
+#include <stdio.h>
93300
 
+
93301
 
+/* 
93302
 
+ * Address test
93303
 
+ *
93304
 
+ * Syntax:
93305
 
+ *    address [ADDRESS-PART] [COMPARATOR] [MATCH-TYPE]
93306
 
+ *       <header-list: string-list> <key-list: string-list>
93307
 
+ */
93308
 
+
93309
 
+static bool tst_address_registered
93310
 
+       (struct sieve_validator *valdtr, struct sieve_command_registration *cmd_reg);
93311
 
+static bool tst_address_validate
93312
 
+       (struct sieve_validator *valdtr, struct sieve_command_context *tst);
93313
 
+static bool tst_address_generate
93314
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx);
93315
 
+
93316
 
+const struct sieve_command tst_address = { 
93317
 
+       "address", 
93318
 
+       SCT_TEST, 
93319
 
+       2, 0, FALSE, FALSE,
93320
 
+       tst_address_registered,
93321
 
+       NULL, 
93322
 
+       tst_address_validate, 
93323
 
+       tst_address_generate, 
93324
 
+       NULL 
93325
 
+};
93326
 
+
93327
 
+/* 
93328
 
+ * Address operation 
93329
 
+ */
93330
 
+
93331
 
+static bool tst_address_operation_dump
93332
 
+       (const struct sieve_operation *op, 
93333
 
+               const struct sieve_dumptime_env *denv, sieve_size_t *address);
93334
 
+static int tst_address_operation_execute
93335
 
+       (const struct sieve_operation *op, 
93336
 
+               const struct sieve_runtime_env *renv, sieve_size_t *address);
93337
 
+
93338
 
+const struct sieve_operation tst_address_operation = { 
93339
 
+       "ADDRESS",
93340
 
+       NULL,
93341
 
+       SIEVE_OPERATION_ADDRESS,
93342
 
+       tst_address_operation_dump, 
93343
 
+       tst_address_operation_execute 
93344
 
+};
93345
 
+
93346
 
+/* 
93347
 
+ * Test registration 
93348
 
+ */
93349
 
+
93350
 
+static bool tst_address_registered
93351
 
+       (struct sieve_validator *valdtr, struct sieve_command_registration *cmd_reg) 
93352
 
+{
93353
 
+       /* The order of these is not significant */
93354
 
+       sieve_comparators_link_tag(valdtr, cmd_reg, SIEVE_AM_OPT_COMPARATOR );
93355
 
+       sieve_address_parts_link_tags(valdtr, cmd_reg, SIEVE_AM_OPT_ADDRESS_PART);
93356
 
+       sieve_match_types_link_tags(valdtr, cmd_reg, SIEVE_AM_OPT_MATCH_TYPE);
93357
 
+
93358
 
+       return TRUE;
93359
 
+}
93360
 
+
93361
 
+/* 
93362
 
+ * Validation 
93363
 
+ */
93364
 
93365
 
+/* List of valid headers:
93366
 
+ *   Implementations MUST restrict the address test to headers that
93367
 
+ *   contain addresses, but MUST include at least From, To, Cc, Bcc,
93368
 
+ *   Sender, Resent-From, and Resent-To, and it SHOULD include any other
93369
 
+ *   header that utilizes an "address-list" structured header body.
93370
 
+ *
93371
 
+ * This list explicitly does not contain the envelope-to and return-path 
93372
 
+ * headers. The envelope test must be used to test against these addresses.
93373
 
+ *
93374
 
+ * FIXME: this restriction is somewhat odd. Sieve list advises to allow 
93375
 
+ *        any other header as long as its content matches the address-list
93376
 
+ *        grammar.
93377
 
+ */
93378
 
+static const char * const _allowed_headers[] = {
93379
 
+       /* Required */
93380
 
+       "from", "to", "cc", "bcc", "sender", "resent-from", "resent-to",
93381
 
+
93382
 
+       /* Additional (RFC 822 / RFC 2822) */
93383
 
+       "reply-to", "resent-reply-to", "resent-sender", "resent-cc", "resent-bcc",  
93384
 
+
93385
 
+       /* Non-standard (RFC 2076, draft-palme-mailext-headers-08.txt) */
93386
 
+       "for-approval", "for-handling", "for-comment", "apparently-to", "errors-to", 
93387
 
+       "delivered-to", "return-receipt-to", "x-admin", "read-receipt-to", 
93388
 
+       "x-confirm-reading-to", "return-receipt-requested", 
93389
 
+       "registered-mail-reply-requested-by", "mail-followup-to", "mail-reply-to",
93390
 
+       "abuse-reports-to", "x-complaints-to", "x-report-abuse-to",
93391
 
+       
93392
 
+       /* Undocumented */
93393
 
+       "x-beenthere",
93394
 
+       
93395
 
+       NULL  
93396
 
+};
93397
 
+
93398
 
+static int _header_is_allowed
93399
 
+(void *context ATTR_UNUSED, struct sieve_ast_argument *arg)
93400
 
+{
93401
 
+       if ( sieve_argument_is_string_literal(arg) ) {
93402
 
+               const char *header = sieve_ast_strlist_strc(arg);
93403
 
+
93404
 
+               const char * const *hdsp = _allowed_headers;
93405
 
+               while ( *hdsp != NULL ) {
93406
 
+                       if ( strcasecmp( *hdsp, header ) == 0 ) 
93407
 
+                               return TRUE;
93408
 
+
93409
 
+                       hdsp++;
93410
 
+               }
93411
 
+               
93412
 
+               return FALSE;
93413
 
+       }
93414
 
+       
93415
 
+       return TRUE;
93416
 
+}
93417
 
+
93418
 
+static bool tst_address_validate
93419
 
+       (struct sieve_validator *valdtr, struct sieve_command_context *tst) 
93420
 
+{
93421
 
+       struct sieve_ast_argument *arg = tst->first_positional;
93422
 
+       struct sieve_ast_argument *header;
93423
 
+               
93424
 
+       if ( !sieve_validate_positional_argument
93425
 
+               (valdtr, tst, arg, "header list", 1, SAAT_STRING_LIST) ) {
93426
 
+               return FALSE;
93427
 
+       }
93428
 
+       
93429
 
+       if ( !sieve_validator_argument_activate(valdtr, tst, arg, FALSE) )
93430
 
+               return FALSE;
93431
 
+
93432
 
+       if ( !sieve_command_verify_headers_argument(valdtr, arg) )
93433
 
+        return FALSE;
93434
 
+
93435
 
+       /* Check if supplied header names are allowed
93436
 
+        *   FIXME: verify dynamic header names at runtime 
93437
 
+        */
93438
 
+       header = arg;
93439
 
+       if ( !sieve_ast_stringlist_map(&header, NULL, _header_is_allowed) ) {           
93440
 
+               sieve_argument_validate_error(valdtr, header, 
93441
 
+                       "specified header '%s' is not allowed for the address test", 
93442
 
+                       str_sanitize(sieve_ast_strlist_strc(header), 64));
93443
 
+               return FALSE;
93444
 
+       }
93445
 
+
93446
 
+       /* Check key list */
93447
 
+       
93448
 
+       arg = sieve_ast_argument_next(arg);
93449
 
+       
93450
 
+       if ( !sieve_validate_positional_argument
93451
 
+               (valdtr, tst, arg, "key list", 2, SAAT_STRING_LIST) ) {
93452
 
+               return FALSE;
93453
 
+       }
93454
 
+
93455
 
+       if ( !sieve_validator_argument_activate(valdtr, tst, arg, FALSE) )
93456
 
+               return FALSE;
93457
 
+       
93458
 
+       /* Validate the key argument to a specified match type */
93459
 
+       return sieve_match_type_validate
93460
 
+               (valdtr, tst, arg, &is_match_type, &i_ascii_casemap_comparator); 
93461
 
+}
93462
 
+
93463
 
+/* 
93464
 
+ * Code generation 
93465
 
+ */
93466
 
+
93467
 
+static bool tst_address_generate
93468
 
+(const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx) 
93469
 
+{
93470
 
+       sieve_operation_emit_code(cgenv->sbin, &tst_address_operation);
93471
 
+       
93472
 
+       /* Generate arguments */        
93473
 
+       return sieve_generate_arguments(cgenv, ctx, NULL);
93474
 
+}
93475
 
+
93476
 
+/* 
93477
 
+ * Code dump 
93478
 
+ */
93479
 
+
93480
 
+static bool tst_address_operation_dump
93481
 
+(const struct sieve_operation *op ATTR_UNUSED, 
93482
 
+       const struct sieve_dumptime_env *denv, sieve_size_t *address)
93483
 
+{
93484
 
+       sieve_code_dumpf(denv, "ADDRESS");
93485
 
+       sieve_code_descend(denv);
93486
 
+       
93487
 
+       /* Handle any optional arguments */
93488
 
+       if ( !sieve_addrmatch_default_dump_optionals(denv, address) )
93489
 
+               return FALSE;
93490
 
+
93491
 
+       return
93492
 
+               sieve_opr_stringlist_dump(denv, address, "header list") &&
93493
 
+               sieve_opr_stringlist_dump(denv, address, "key list");
93494
 
+}
93495
 
+
93496
 
+/* 
93497
 
+ * Code execution 
93498
 
+ */
93499
 
+
93500
 
+static int tst_address_operation_execute
93501
 
+(const struct sieve_operation *op ATTR_UNUSED, 
93502
 
+       const struct sieve_runtime_env *renv, sieve_size_t *address)
93503
 
+{      
93504
 
+       bool result = TRUE;
93505
 
+       const struct sieve_comparator *cmp = &i_ascii_casemap_comparator;
93506
 
+       const struct sieve_match_type *mtch = &is_match_type;
93507
 
+       const struct sieve_address_part *addrp = &all_address_part;
93508
 
+       struct sieve_match_context *mctx;
93509
 
+       struct sieve_coded_stringlist *hdr_list;
93510
 
+       struct sieve_coded_stringlist *key_list;
93511
 
+       string_t *hdr_item;
93512
 
+       bool matched;
93513
 
+       int ret;
93514
 
+       
93515
 
+       /* Read optional operands */
93516
 
+       if ( (ret=sieve_addrmatch_default_get_optionals
93517
 
+               (renv, address, &addrp, &mtch, &cmp)) <= 0 ) 
93518
 
+               return ret;
93519
 
+               
93520
 
+       /* Read header-list */
93521
 
+       if ( (hdr_list=sieve_opr_stringlist_read(renv, address)) == NULL ) {
93522
 
+               sieve_runtime_trace_error(renv, "invalid header-list operand");
93523
 
+               return SIEVE_EXEC_BIN_CORRUPT;
93524
 
+       }
93525
 
+
93526
 
+       /* Read key-list */
93527
 
+       if ( (key_list=sieve_opr_stringlist_read(renv, address)) == NULL ) {
93528
 
+               sieve_runtime_trace_error(renv, "invalid key-list operand");
93529
 
+               return SIEVE_EXEC_BIN_CORRUPT;
93530
 
+       }
93531
 
+
93532
 
+       sieve_runtime_trace(renv, "ADDRESS test");
93533
 
+
93534
 
+       /* Initialize match context */
93535
 
+       mctx = sieve_match_begin(renv->interp, mtch, cmp, NULL, key_list);
93536
 
+       
93537
 
+       /* Iterate through all requested headers to match */
93538
 
+       hdr_item = NULL;
93539
 
+       matched = FALSE;
93540
 
+       while ( result && !matched && 
93541
 
+               (result=sieve_coded_stringlist_next_item(hdr_list, &hdr_item)) 
93542
 
+               && hdr_item != NULL ) {
93543
 
+               const char *const *headers;
93544
 
+                       
93545
 
+               if ( mail_get_headers_utf8(renv->msgdata->mail, str_c(hdr_item), &headers) >= 0 ) {     
93546
 
+                       int i;
93547
 
+
93548
 
+                       for ( i = 0; !matched && headers[i] != NULL; i++ ) {
93549
 
+                               if ( (ret=sieve_address_match(addrp, mctx, headers[i])) < 0 ) {
93550
 
+                                       result = FALSE;
93551
 
+                                       break;
93552
 
+                               }
93553
 
+                               
93554
 
+                               matched = ret > 0;                              
93555
 
+                       } 
93556
 
+               }
93557
 
+       }
93558
 
+       
93559
 
+       /* Finish match */
93560
 
+
93561
 
+       if ( (ret=sieve_match_end(&mctx)) < 0 )
93562
 
+               result = FALSE;
93563
 
+       else
93564
 
+               matched = ( ret > 0 || matched );
93565
 
+       
93566
 
+       /* Set test result for subsequent conditional jump */
93567
 
+       if ( result ) {
93568
 
+               sieve_interpreter_set_test_result(renv->interp, matched);
93569
 
+               return SIEVE_EXEC_OK;
93570
 
+       }
93571
 
+
93572
 
+       sieve_runtime_trace_error(renv, "invalid string-list item");    
93573
 
+       return SIEVE_EXEC_BIN_CORRUPT;
93574
 
+}
93575
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/tst-allof.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/tst-allof.c
93576
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/tst-allof.c    1970-01-01 01:00:00.000000000 +0100
93577
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/tst-allof.c     2009-01-06 00:15:52.000000000 +0100
93578
 
@@ -0,0 +1,86 @@
93579
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
93580
 
+ */
93581
 
+
93582
 
+#include "sieve-common.h"
93583
 
+#include "sieve-commands.h"
93584
 
+#include "sieve-validator.h"
93585
 
+#include "sieve-generator.h"
93586
 
+#include "sieve-binary.h"
93587
 
+#include "sieve-code.h"
93588
 
+#include "sieve-binary.h"
93589
 
+
93590
 
+/* 
93591
 
+ * Allof test 
93592
 
+ * 
93593
 
+ * Syntax 
93594
 
+ *   allof <tests: test-list>   
93595
 
+ */
93596
 
+
93597
 
+static bool tst_allof_generate
93598
 
+       (const struct sieve_codegen_env *cgenv, 
93599
 
+               struct sieve_command_context *ctx,
93600
 
+               struct sieve_jumplist *jumps, bool jump_true);
93601
 
+
93602
 
+const struct sieve_command tst_allof = { 
93603
 
+       "allof", 
93604
 
+       SCT_TEST, 
93605
 
+       0, 2, FALSE, FALSE,
93606
 
+       NULL, NULL, NULL, NULL, 
93607
 
+       tst_allof_generate 
93608
 
+};
93609
 
+
93610
 
+/* 
93611
 
+ * Code generation 
93612
 
+ */
93613
 
+
93614
 
+static bool tst_allof_generate
93615
 
+(const struct sieve_codegen_env *cgenv, 
93616
 
+       struct sieve_command_context *ctx,
93617
 
+       struct sieve_jumplist *jumps, bool jump_true)
93618
 
+{
93619
 
+       struct sieve_binary *sbin = cgenv->sbin;
93620
 
+       struct sieve_ast_node *test;
93621
 
+       struct sieve_jumplist false_jumps;
93622
 
+
93623
 
+       if ( sieve_ast_test_count(ctx->ast_node) > 1 ) {        
93624
 
+               if ( jump_true ) {
93625
 
+                       /* Prepare jumplist */
93626
 
+                       sieve_jumplist_init_temp(&false_jumps, sbin);
93627
 
+               }
93628
 
+       
93629
 
+               test = sieve_ast_test_first(ctx->ast_node);
93630
 
+               while ( test != NULL ) {        
93631
 
+                       bool result; 
93632
 
+
93633
 
+                       /* If this test list must jump on false, all sub-tests can simply add their jumps
93634
 
+                        * to the caller's jump list, otherwise this test redirects all false jumps to the 
93635
 
+                        * end of the currently generated code. This is just after a final jump to the true
93636
 
+                        * case 
93637
 
+                        */
93638
 
+                       if ( jump_true ) 
93639
 
+                               result = sieve_generate_test(cgenv, test, &false_jumps, FALSE);
93640
 
+                       else
93641
 
+                               result = sieve_generate_test(cgenv, test, jumps, FALSE);
93642
 
+               
93643
 
+                       if ( !result ) return FALSE;
93644
 
+
93645
 
+                       test = sieve_ast_test_next(test);
93646
 
+               }       
93647
 
+       
93648
 
+               if ( jump_true ) {
93649
 
+                       /* All tests succeeded, jump to case TRUE */
93650
 
+                       sieve_operation_emit_code(cgenv->sbin, &sieve_jmp_operation);
93651
 
+                       sieve_jumplist_add(jumps, sieve_binary_emit_offset(sbin, 0));
93652
 
+                       
93653
 
+                       /* All false exits jump here */
93654
 
+                       sieve_jumplist_resolve(&false_jumps);
93655
 
+               }
93656
 
+       } else {
93657
 
+               /* Script author is being inefficient; we can optimize the allof test away */
93658
 
+               test = sieve_ast_test_first(ctx->ast_node);
93659
 
+               sieve_generate_test(cgenv, test, jumps, jump_true);
93660
 
+       }
93661
 
+               
93662
 
+       return TRUE;
93663
 
+}
93664
 
+
93665
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/tst-anyof.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/tst-anyof.c
93666
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/tst-anyof.c    1970-01-01 01:00:00.000000000 +0100
93667
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/tst-anyof.c     2009-01-06 00:15:52.000000000 +0100
93668
 
@@ -0,0 +1,83 @@
93669
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
93670
 
+ */
93671
 
+
93672
 
+#include "sieve-common.h"
93673
 
+#include "sieve-commands.h"
93674
 
+#include "sieve-generator.h"
93675
 
+#include "sieve-validator.h"
93676
 
+#include "sieve-binary.h"
93677
 
+#include "sieve-code.h"
93678
 
+#include "sieve-binary.h"
93679
 
+
93680
 
+/* 
93681
 
+ * Anyof test 
93682
 
+ *
93683
 
+ * Syntax 
93684
 
+ *   anyof <tests: test-list>   
93685
 
+ */
93686
 
+
93687
 
+static bool tst_anyof_generate 
93688
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx,
93689
 
+               struct sieve_jumplist *jumps, bool jump_true);
93690
 
+
93691
 
+const struct sieve_command tst_anyof = { 
93692
 
+       "anyof", 
93693
 
+       SCT_TEST, 
93694
 
+       0, 2, FALSE, FALSE,
93695
 
+       NULL, NULL, NULL, NULL, 
93696
 
+       tst_anyof_generate 
93697
 
+};
93698
 
+
93699
 
+/* 
93700
 
+ * Code generation 
93701
 
+ */
93702
 
+
93703
 
+static bool tst_anyof_generate 
93704
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx,
93705
 
+               struct sieve_jumplist *jumps, bool jump_true)
93706
 
+{
93707
 
+       struct sieve_binary *sbin = cgenv->sbin;
93708
 
+       struct sieve_ast_node *test;
93709
 
+       struct sieve_jumplist true_jumps;
93710
 
+
93711
 
+       if ( sieve_ast_test_count(ctx->ast_node) > 1 ) {        
93712
 
+               if ( !jump_true ) {
93713
 
+                       /* Prepare jumplist */
93714
 
+                       sieve_jumplist_init_temp(&true_jumps, sbin);
93715
 
+               }
93716
 
+       
93717
 
+               test = sieve_ast_test_first(ctx->ast_node);
93718
 
+               while ( test != NULL ) {        
93719
 
+                       bool result;
93720
 
+
93721
 
+                       /* If this test list must jump on true, all sub-tests can simply add their jumps
93722
 
+                        * to the caller's jump list, otherwise this test redirects all true jumps to the 
93723
 
+                        * end of the currently generated code. This is just after a final jump to the false
93724
 
+                        * case 
93725
 
+                        */
93726
 
+                       if ( !jump_true ) 
93727
 
+                               result = sieve_generate_test(cgenv, test, &true_jumps, TRUE);
93728
 
+                       else
93729
 
+                               result = sieve_generate_test(cgenv, test, jumps, TRUE);
93730
 
+
93731
 
+                       if ( !result ) return FALSE;
93732
 
+               
93733
 
+                       test = sieve_ast_test_next(test);
93734
 
+               }       
93735
 
+       
93736
 
+               if ( !jump_true ) {
93737
 
+                       /* All tests failed, jump to case FALSE */
93738
 
+                       sieve_operation_emit_code(sbin, &sieve_jmp_operation);
93739
 
+                       sieve_jumplist_add(jumps, sieve_binary_emit_offset(sbin, 0));
93740
 
+                       
93741
 
+                       /* All true exits jump here */
93742
 
+                       sieve_jumplist_resolve(&true_jumps);
93743
 
+               }
93744
 
+       } else {
93745
 
+               /* Script author is being inefficient; we can optimize the allof test away */
93746
 
+        test = sieve_ast_test_first(ctx->ast_node);
93747
 
+        sieve_generate_test(cgenv, test, jumps, jump_true);
93748
 
+    }          
93749
 
+               
93750
 
+       return TRUE;
93751
 
+}
93752
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/tst-exists.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/tst-exists.c
93753
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/tst-exists.c   1970-01-01 01:00:00.000000000 +0100
93754
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/tst-exists.c    2009-01-06 00:15:52.000000000 +0100
93755
 
@@ -0,0 +1,145 @@
93756
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
93757
 
+ */
93758
 
+
93759
 
+#include "sieve-common.h"
93760
 
+#include "sieve-commands.h"
93761
 
+#include "sieve-code.h"
93762
 
+#include "sieve-validator.h"
93763
 
+#include "sieve-generator.h"
93764
 
+#include "sieve-interpreter.h"
93765
 
+#include "sieve-code-dumper.h"
93766
 
+
93767
 
+/* 
93768
 
+ * Exists test
93769
 
+ *  
93770
 
+ * Syntax:
93771
 
+ *    exists <header-names: string-list>
93772
 
+ */
93773
 
+
93774
 
+static bool tst_exists_validate
93775
 
+       (struct sieve_validator *valdtr, struct sieve_command_context *tst);
93776
 
+static bool tst_exists_generate
93777
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx);
93778
 
+
93779
 
+const struct sieve_command tst_exists = { 
93780
 
+       "exists", 
93781
 
+       SCT_TEST, 
93782
 
+       1, 0, FALSE, FALSE,
93783
 
+       NULL, 
93784
 
+       NULL,
93785
 
+       tst_exists_validate, 
93786
 
+       tst_exists_generate, 
93787
 
+       NULL 
93788
 
+};
93789
 
+
93790
 
+/* 
93791
 
+ * Exists operation 
93792
 
+ */
93793
 
+
93794
 
+static bool tst_exists_operation_dump
93795
 
+       (const struct sieve_operation *op, 
93796
 
+               const struct sieve_dumptime_env *denv, sieve_size_t *address);
93797
 
+static int tst_exists_operation_execute
93798
 
+       (const struct sieve_operation *op, 
93799
 
+               const struct sieve_runtime_env *renv, sieve_size_t *address);
93800
 
+
93801
 
+const struct sieve_operation tst_exists_operation = { 
93802
 
+       "EXISTS",
93803
 
+       NULL,
93804
 
+       SIEVE_OPERATION_EXISTS,
93805
 
+       tst_exists_operation_dump, 
93806
 
+       tst_exists_operation_execute 
93807
 
+};
93808
 
+
93809
 
+/* 
93810
 
+ * Validation 
93811
 
+ */
93812
 
+
93813
 
+static bool tst_exists_validate
93814
 
+  (struct sieve_validator *valdtr, struct sieve_command_context *tst) 
93815
 
+{
93816
 
+       struct sieve_ast_argument *arg = tst->first_positional;
93817
 
+               
93818
 
+       if ( !sieve_validate_positional_argument
93819
 
+               (valdtr, tst, arg, "header names", 1, SAAT_STRING_LIST) ) {
93820
 
+               return FALSE;
93821
 
+       }
93822
 
+       
93823
 
+       if ( !sieve_validator_argument_activate(valdtr, tst, arg, FALSE) )
93824
 
+               return FALSE;
93825
 
+
93826
 
+       return sieve_command_verify_headers_argument(valdtr, arg);
93827
 
+}
93828
 
+
93829
 
+/* 
93830
 
+ * Code generation 
93831
 
+ */
93832
 
+
93833
 
+static bool tst_exists_generate
93834
 
+(const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx) 
93835
 
+{
93836
 
+       sieve_operation_emit_code(cgenv->sbin, &tst_exists_operation);
93837
 
+
93838
 
+       /* Generate arguments */
93839
 
+    return sieve_generate_arguments(cgenv, ctx, NULL);
93840
 
+}
93841
 
+
93842
 
+/* 
93843
 
+ * Code dump 
93844
 
+ */
93845
 
+
93846
 
+static bool tst_exists_operation_dump
93847
 
+(const struct sieve_operation *op ATTR_UNUSED, 
93848
 
+       const struct sieve_dumptime_env *denv, sieve_size_t *address)
93849
 
+{
93850
 
+    sieve_code_dumpf(denv, "EXISTS");
93851
 
+       sieve_code_descend(denv);
93852
 
+
93853
 
+       return sieve_opr_stringlist_dump(denv, address, "header names");
93854
 
+}
93855
 
+
93856
 
+/* 
93857
 
+ * Code execution 
93858
 
+ */
93859
 
+
93860
 
+static int tst_exists_operation_execute
93861
 
+(const struct sieve_operation *op ATTR_UNUSED, 
93862
 
+       const struct sieve_runtime_env *renv, sieve_size_t *address)
93863
 
+{
93864
 
+       bool result = TRUE;
93865
 
+       struct sieve_coded_stringlist *hdr_list;
93866
 
+       string_t *hdr_item;
93867
 
+       bool matched;
93868
 
+       
93869
 
+       /* Read header-list */
93870
 
+       if ( (hdr_list=sieve_opr_stringlist_read(renv, address)) == NULL ) {
93871
 
+               sieve_runtime_trace_error(renv, "invalid header-list operand");
93872
 
+               return SIEVE_EXEC_BIN_CORRUPT;
93873
 
+       }
93874
 
+
93875
 
+       sieve_runtime_trace(renv, "EXISTS test");
93876
 
+               
93877
 
+       /* Iterate through all requested headers to match (must find all specified) */
93878
 
+       hdr_item = NULL;
93879
 
+       matched = TRUE;
93880
 
+       while ( matched &&
93881
 
+               (result=sieve_coded_stringlist_next_item(hdr_list, &hdr_item)) 
93882
 
+               && hdr_item != NULL ) {
93883
 
+               const char *const *headers;
93884
 
+                       
93885
 
+               if ( mail_get_headers
93886
 
+                       (renv->msgdata->mail, str_c(hdr_item), &headers) < 0 ||
93887
 
+                       headers[0] == NULL ) {  
93888
 
+                       matched = FALSE;                                 
93889
 
+               }
93890
 
+       }
93891
 
+       
93892
 
+       /* Set test result for subsequent conditional jump */
93893
 
+       if ( result ) {
93894
 
+               sieve_interpreter_set_test_result(renv->interp, matched);
93895
 
+               return SIEVE_EXEC_OK;
93896
 
+       }
93897
 
+       
93898
 
+       sieve_runtime_trace_error(renv, "invalid header-list item");
93899
 
+       return SIEVE_EXEC_BIN_CORRUPT;
93900
 
+}
93901
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/tst-header.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/tst-header.c
93902
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/tst-header.c   1970-01-01 01:00:00.000000000 +0100
93903
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/tst-header.c    2009-07-30 00:43:35.000000000 +0200
93904
 
@@ -0,0 +1,249 @@
93905
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
93906
 
+ */
93907
 
+
93908
 
+#include "sieve-common.h"
93909
 
+#include "sieve-commands.h"
93910
 
+#include "sieve-code.h"
93911
 
+#include "sieve-comparators.h"
93912
 
+#include "sieve-match-types.h"
93913
 
+#include "sieve-validator.h"
93914
 
+#include "sieve-generator.h"
93915
 
+#include "sieve-interpreter.h"
93916
 
+#include "sieve-dump.h"
93917
 
+#include "sieve-match.h"
93918
 
+
93919
 
+/* 
93920
 
+ * Header test 
93921
 
+ *
93922
 
+ * Syntax:
93923
 
+ *   header [COMPARATOR] [MATCH-TYPE]
93924
 
+ *     <header-names: string-list> <key-list: string-list>
93925
 
+ */
93926
 
+
93927
 
+static bool tst_header_registered
93928
 
+       (struct sieve_validator *valdtr, struct sieve_command_registration *cmd_reg);
93929
 
+static bool tst_header_validate
93930
 
+       (struct sieve_validator *valdtr, struct sieve_command_context *tst);
93931
 
+static bool tst_header_generate
93932
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx);
93933
 
+
93934
 
+const struct sieve_command tst_header = { 
93935
 
+       "header", 
93936
 
+       SCT_TEST, 
93937
 
+       2, 0, FALSE, FALSE,
93938
 
+       tst_header_registered, 
93939
 
+       NULL,
93940
 
+       tst_header_validate, 
93941
 
+       tst_header_generate, 
93942
 
+       NULL 
93943
 
+};
93944
 
+
93945
 
+/* 
93946
 
+ * Header operation 
93947
 
+ */
93948
 
+
93949
 
+static bool tst_header_operation_dump
93950
 
+       (const struct sieve_operation *op, 
93951
 
+               const struct sieve_dumptime_env *denv, sieve_size_t *address);
93952
 
+static int tst_header_operation_execute
93953
 
+       (const struct sieve_operation *op, 
93954
 
+               const struct sieve_runtime_env *renv, sieve_size_t *address);
93955
 
+
93956
 
+const struct sieve_operation tst_header_operation = { 
93957
 
+       "HEADER",
93958
 
+       NULL,
93959
 
+       SIEVE_OPERATION_HEADER,
93960
 
+       tst_header_operation_dump, 
93961
 
+       tst_header_operation_execute 
93962
 
+};
93963
 
+
93964
 
+/* 
93965
 
+ * Test registration 
93966
 
+ */
93967
 
+
93968
 
+static bool tst_header_registered
93969
 
+       (struct sieve_validator *valdtr, struct sieve_command_registration *cmd_reg) 
93970
 
+{
93971
 
+       /* The order of these is not significant */
93972
 
+       sieve_comparators_link_tag(valdtr, cmd_reg, SIEVE_MATCH_OPT_COMPARATOR);
93973
 
+       sieve_match_types_link_tags(valdtr, cmd_reg, SIEVE_MATCH_OPT_MATCH_TYPE);
93974
 
+
93975
 
+       return TRUE;
93976
 
+}
93977
 
+
93978
 
+/* 
93979
 
+ * Validation 
93980
 
+ */
93981
 
93982
 
+static bool tst_header_validate
93983
 
+       (struct sieve_validator *valdtr, struct sieve_command_context *tst) 
93984
 
+{              
93985
 
+       struct sieve_ast_argument *arg = tst->first_positional;
93986
 
+       
93987
 
+       if ( !sieve_validate_positional_argument
93988
 
+               (valdtr, tst, arg, "header names", 1, SAAT_STRING_LIST) ) {
93989
 
+               return FALSE;
93990
 
+       }
93991
 
+       
93992
 
+       if ( !sieve_validator_argument_activate(valdtr, tst, arg, FALSE) )
93993
 
+               return FALSE;
93994
 
+
93995
 
+       if ( !sieve_command_verify_headers_argument(valdtr, arg) )
93996
 
+               return FALSE;
93997
 
+       
93998
 
+       arg = sieve_ast_argument_next(arg);
93999
 
+
94000
 
+       if ( !sieve_validate_positional_argument
94001
 
+               (valdtr, tst, arg, "key list", 2, SAAT_STRING_LIST) ) {
94002
 
+               return FALSE;
94003
 
+       }
94004
 
+       
94005
 
+       if ( !sieve_validator_argument_activate(valdtr, tst, arg, FALSE) )
94006
 
+               return FALSE;
94007
 
+
94008
 
+       /* Validate the key argument to a specified match type */
94009
 
+       return sieve_match_type_validate
94010
 
+               (valdtr, tst, arg, &is_match_type, &i_ascii_casemap_comparator);
94011
 
+}
94012
 
+
94013
 
+/*
94014
 
+ * Code generation 
94015
 
+ */
94016
 
+
94017
 
+static bool tst_header_generate
94018
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx) 
94019
 
+{
94020
 
+       sieve_operation_emit_code(cgenv->sbin, &tst_header_operation);
94021
 
+
94022
 
+       /* Generate arguments */
94023
 
+       return sieve_generate_arguments(cgenv, ctx, NULL);
94024
 
+}
94025
 
+
94026
 
+/* 
94027
 
+ * Code dump 
94028
 
+ */
94029
 
+
94030
 
+static bool tst_header_operation_dump
94031
 
+(const struct sieve_operation *op ATTR_UNUSED,
94032
 
+       const struct sieve_dumptime_env *denv, sieve_size_t *address)
94033
 
+{
94034
 
+       int opt_code = 0;
94035
 
+
94036
 
+       sieve_code_dumpf(denv, "HEADER");
94037
 
+       sieve_code_descend(denv);
94038
 
+
94039
 
+       /* Handle any optional arguments */
94040
 
+       if ( !sieve_match_dump_optional_operands(denv, address, &opt_code) )
94041
 
+               return FALSE;
94042
 
+
94043
 
+       if ( opt_code != SIEVE_MATCH_OPT_END )
94044
 
+               return FALSE;
94045
 
+       
94046
 
+       return
94047
 
+               sieve_opr_stringlist_dump(denv, address, "header names") &&
94048
 
+               sieve_opr_stringlist_dump(denv, address, "key list");
94049
 
+}
94050
 
+
94051
 
+/* 
94052
 
+ * Code execution 
94053
 
+ */
94054
 
+
94055
 
+static inline string_t *_header_right_trim(const char *raw) 
94056
 
+{
94057
 
+       string_t *result;
94058
 
+       int i;
94059
 
+       
94060
 
+       for ( i = strlen(raw)-1; i >= 0; i-- ) {
94061
 
+               if ( raw[i] != ' ' && raw[i] != '\t' ) break;
94062
 
+       }
94063
 
+       
94064
 
+       result = t_str_new(i+1);
94065
 
+       str_append_n(result, raw, i + 1);
94066
 
+       return result;
94067
 
+}
94068
 
+
94069
 
+static int tst_header_operation_execute
94070
 
+(const struct sieve_operation *op ATTR_UNUSED, 
94071
 
+       const struct sieve_runtime_env *renv, sieve_size_t *address)
94072
 
+{
94073
 
+       bool result = TRUE;
94074
 
+       int opt_code = 0;
94075
 
+       const struct sieve_comparator *cmp = &i_ascii_casemap_comparator;
94076
 
+       const struct sieve_match_type *mtch = &is_match_type;
94077
 
+       struct sieve_match_context *mctx;
94078
 
+       struct sieve_coded_stringlist *hdr_list;
94079
 
+       struct sieve_coded_stringlist *key_list;
94080
 
+       string_t *hdr_item;
94081
 
+       bool matched;
94082
 
+       int ret;
94083
 
+       
94084
 
+       /* Handle match-type and comparator operands */
94085
 
+       if ( (ret=sieve_match_read_optional_operands
94086
 
+               (renv, address, &opt_code, &cmp, &mtch)) <= 0 )
94087
 
+               return ret;
94088
 
+       
94089
 
+       /* Check whether we neatly finished the list of optional operands*/
94090
 
+       if ( opt_code != SIEVE_MATCH_OPT_END) {
94091
 
+               sieve_runtime_trace_error(renv, "invalid optional operand");
94092
 
+               return SIEVE_EXEC_BIN_CORRUPT;
94093
 
+       }
94094
 
+               
94095
 
+       /* Read header-list */
94096
 
+       if ( (hdr_list=sieve_opr_stringlist_read(renv, address)) == NULL ) {
94097
 
+               sieve_runtime_trace_error(renv, "invalid header-list operand");
94098
 
+               return SIEVE_EXEC_BIN_CORRUPT;
94099
 
+       }
94100
 
+       
94101
 
+       /* Read key-list */
94102
 
+       if ( (key_list=sieve_opr_stringlist_read(renv, address)) == NULL ) {
94103
 
+               sieve_runtime_trace_error(renv, "invalid key-list operand");
94104
 
+               return SIEVE_EXEC_BIN_CORRUPT;
94105
 
+       }
94106
 
+
94107
 
+       sieve_runtime_trace(renv, "HEADER test");
94108
 
+
94109
 
+       /* Initialize match */
94110
 
+       mctx = sieve_match_begin(renv->interp, mtch, cmp, NULL, key_list);      
94111
 
+
94112
 
+       /* Iterate through all requested headers to match */
94113
 
+       hdr_item = NULL;
94114
 
+       matched = FALSE;
94115
 
+       while ( result && !matched && 
94116
 
+               (result=sieve_coded_stringlist_next_item(hdr_list, &hdr_item)) 
94117
 
+               && hdr_item != NULL ) {
94118
 
+               const char *const *headers;
94119
 
+                       
94120
 
+               if ( mail_get_headers_utf8
94121
 
+                       (renv->msgdata->mail, str_c(hdr_item), &headers) >= 0 ) {       
94122
 
+                       int i;
94123
 
+
94124
 
+                       for ( i = 0; !matched && headers[i] != NULL; i++ ) {
94125
 
+                               string_t *theader = _header_right_trim(headers[i]);
94126
 
+                       
94127
 
+                               if ( (ret=sieve_match_value(mctx, str_c(theader), str_len(theader))) 
94128
 
+                                       < 0 ) 
94129
 
+                               {
94130
 
+                                       result = FALSE;
94131
 
+                                       break;
94132
 
+                               }
94133
 
+
94134
 
+                               matched = ret > 0;                              
94135
 
+                       } 
94136
 
+               }
94137
 
+       }
94138
 
+
94139
 
+       /* Finish match */
94140
 
+       if ( (ret=sieve_match_end(&mctx)) < 0 ) 
94141
 
+               result = FALSE;
94142
 
+       else
94143
 
+               matched = ( ret > 0 || matched );
94144
 
+       
94145
 
+       /* Set test result for subsequent conditional jump */
94146
 
+       if ( result ) {
94147
 
+               sieve_interpreter_set_test_result(renv->interp, matched);
94148
 
+               return SIEVE_EXEC_OK;
94149
 
+       }       
94150
 
+
94151
 
+       sieve_runtime_trace_error(renv, "invalid string-list item");
94152
 
+       return SIEVE_EXEC_BIN_CORRUPT;
94153
 
+}
94154
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/tst-not.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/tst-not.c
94155
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/tst-not.c      1970-01-01 01:00:00.000000000 +0100
94156
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/tst-not.c       2009-01-06 00:15:52.000000000 +0100
94157
 
@@ -0,0 +1,43 @@
94158
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
94159
 
+ */
94160
 
+
94161
 
+#include "sieve-common.h"
94162
 
+#include "sieve-commands.h"
94163
 
+#include "sieve-validator.h"
94164
 
+#include "sieve-generator.h"
94165
 
+
94166
 
+/* 
94167
 
+ * Not test 
94168
 
+ *
94169
 
+ * Syntax:
94170
 
+ *   not <tests: test-list>   
94171
 
+ */
94172
 
+
94173
 
+static bool tst_not_generate
94174
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx,
94175
 
+               struct sieve_jumplist *jumps, bool jump_true);
94176
 
+
94177
 
+const struct sieve_command tst_not = { 
94178
 
+       "not", 
94179
 
+       SCT_TEST, 
94180
 
+       0, 1, FALSE, FALSE,
94181
 
+       NULL, NULL, NULL, NULL, 
94182
 
+       tst_not_generate 
94183
 
+};
94184
 
+
94185
 
+/* 
94186
 
+ * Code generation 
94187
 
+ */
94188
 
+
94189
 
+static bool tst_not_generate
94190
 
+(const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx,
94191
 
+       struct sieve_jumplist *jumps, bool jump_true)
94192
 
+{
94193
 
+       struct sieve_ast_node *test;
94194
 
+       
94195
 
+       /* Validator verified the existance of the single test already */
94196
 
+       test = sieve_ast_test_first(ctx->ast_node); 
94197
 
+       
94198
 
+       return sieve_generate_test(cgenv, test, jumps, !jump_true);
94199
 
+}
94200
 
+
94201
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/tst-size.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/tst-size.c
94202
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/tst-size.c     1970-01-01 01:00:00.000000000 +0100
94203
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/tst-size.c      2009-02-11 21:38:58.000000000 +0100
94204
 
@@ -0,0 +1,276 @@
94205
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
94206
 
+ */
94207
 
+
94208
 
+#include "lib.h"
94209
 
+
94210
 
+#include "sieve-common.h"
94211
 
+#include "sieve-code.h"
94212
 
+#include "sieve-commands.h"
94213
 
+#include "sieve-validator.h"
94214
 
+#include "sieve-generator.h"
94215
 
+#include "sieve-interpreter.h"
94216
 
+#include "sieve-code-dumper.h"
94217
 
+
94218
 
+/* 
94219
 
+ * Size test 
94220
 
+ *
94221
 
+ * Syntax:
94222
 
+ *    size <":over" / ":under"> <limit: number>
94223
 
+ */
94224
 
+
94225
 
+static bool tst_size_registered
94226
 
+       (struct sieve_validator *validator, 
94227
 
+               struct sieve_command_registration *cmd_reg);
94228
 
+static bool tst_size_pre_validate
94229
 
+       (struct sieve_validator *validator, struct sieve_command_context *tst);
94230
 
+static bool tst_size_validate
94231
 
+       (struct sieve_validator *validator, struct sieve_command_context *tst);
94232
 
+static bool tst_size_generate
94233
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx); 
94234
 
+
94235
 
+const struct sieve_command tst_size = { 
94236
 
+       "size", 
94237
 
+       SCT_TEST, 
94238
 
+       1, 0, FALSE, FALSE,
94239
 
+       tst_size_registered, 
94240
 
+       tst_size_pre_validate,
94241
 
+       tst_size_validate, 
94242
 
+       tst_size_generate, 
94243
 
+       NULL 
94244
 
+};
94245
 
+
94246
 
+/* 
94247
 
+ * Size operations 
94248
 
+ */
94249
 
+
94250
 
+static bool tst_size_operation_dump
94251
 
+       (const struct sieve_operation *op, 
94252
 
+               const struct sieve_dumptime_env *denv, sieve_size_t *address);
94253
 
+static int tst_size_operation_execute
94254
 
+       (const struct sieve_operation *op, 
94255
 
+               const struct sieve_runtime_env *renv, sieve_size_t *address);
94256
 
+
94257
 
+const struct sieve_operation tst_size_over_operation = { 
94258
 
+       "SIZE-OVER",
94259
 
+       NULL, 
94260
 
+       SIEVE_OPERATION_SIZE_OVER,
94261
 
+       tst_size_operation_dump, 
94262
 
+       tst_size_operation_execute 
94263
 
+};
94264
 
+
94265
 
+const struct sieve_operation tst_size_under_operation = {
94266
 
+       "SIZE-UNDER",
94267
 
+       NULL, 
94268
 
+       SIEVE_OPERATION_SIZE_UNDER,
94269
 
+       tst_size_operation_dump, 
94270
 
+       tst_size_operation_execute 
94271
 
+};
94272
 
+
94273
 
+/* 
94274
 
+ * Context data
94275
 
+ */
94276
 
+
94277
 
+struct tst_size_context_data {
94278
 
+       enum { SIZE_UNASSIGNED, SIZE_UNDER, SIZE_OVER } type;
94279
 
+};
94280
 
+
94281
 
+#define TST_SIZE_ERROR_DUP_TAG \
94282
 
+       "exactly one of the ':under' or ':over' tags must be specified " \
94283
 
+       "for the size test, but more were found"
94284
 
+
94285
 
+/* 
94286
 
+ * Tag validation 
94287
 
+ */
94288
 
+
94289
 
+static bool tst_size_validate_over_tag
94290
 
+(struct sieve_validator *validator, struct sieve_ast_argument **arg, 
94291
 
+       struct sieve_command_context *tst)
94292
 
+{
94293
 
+       struct tst_size_context_data *ctx_data = 
94294
 
+               (struct tst_size_context_data *) tst->data;     
94295
 
+       
94296
 
+       if ( ctx_data->type != SIZE_UNASSIGNED ) {
94297
 
+               sieve_argument_validate_error(validator, *arg, TST_SIZE_ERROR_DUP_TAG);
94298
 
+               return FALSE;           
94299
 
+       }
94300
 
+       
94301
 
+       ctx_data->type = SIZE_OVER;
94302
 
+       
94303
 
+       /* Delete this tag */
94304
 
+       *arg = sieve_ast_arguments_detach(*arg, 1);
94305
 
+       
94306
 
+       return TRUE;
94307
 
+}
94308
 
+
94309
 
+static bool tst_size_validate_under_tag
94310
 
+(struct sieve_validator *validator, struct sieve_ast_argument **arg ATTR_UNUSED, 
94311
 
+       struct sieve_command_context *tst)
94312
 
+{
94313
 
+       struct tst_size_context_data *ctx_data = 
94314
 
+               (struct tst_size_context_data *) tst->data;     
94315
 
+       
94316
 
+       if ( ctx_data->type != SIZE_UNASSIGNED ) {
94317
 
+               sieve_argument_validate_error(validator, *arg, TST_SIZE_ERROR_DUP_TAG);
94318
 
+               return FALSE;           
94319
 
+       }
94320
 
+       
94321
 
+       ctx_data->type = SIZE_UNDER;
94322
 
+       
94323
 
+       /* Delete this tag */
94324
 
+       *arg = sieve_ast_arguments_detach(*arg, 1);
94325
 
+               
94326
 
+       return TRUE;
94327
 
+}
94328
 
+
94329
 
+/* 
94330
 
+ * Test registration 
94331
 
+ */
94332
 
+
94333
 
+static const struct sieve_argument size_over_tag = { 
94334
 
+       "over", 
94335
 
+       NULL, NULL,
94336
 
+       tst_size_validate_over_tag, 
94337
 
+       NULL, NULL 
94338
 
+};
94339
 
+
94340
 
+static const struct sieve_argument size_under_tag = { 
94341
 
+       "under", 
94342
 
+       NULL, NULL, 
94343
 
+       tst_size_validate_under_tag, 
94344
 
+       NULL, NULL 
94345
 
+};
94346
 
+
94347
 
+static bool tst_size_registered
94348
 
+(struct sieve_validator *validator, struct sieve_command_registration *cmd_reg) 
94349
 
+{
94350
 
+       /* Register our tags */
94351
 
+       sieve_validator_register_tag(validator, cmd_reg, &size_over_tag, 0);    
94352
 
+       sieve_validator_register_tag(validator, cmd_reg, &size_under_tag, 0);   
94353
 
+
94354
 
+       return TRUE;
94355
 
+}
94356
 
+
94357
 
+/* 
94358
 
+ * Test validation 
94359
 
+ */
94360
 
+
94361
 
+static bool tst_size_pre_validate
94362
 
+(struct sieve_validator *validator ATTR_UNUSED, 
94363
 
+       struct sieve_command_context *tst) 
94364
 
+{
94365
 
+       struct tst_size_context_data *ctx_data;
94366
 
+       
94367
 
+       /* Assign context */
94368
 
+       ctx_data = p_new(sieve_command_pool(tst), struct tst_size_context_data, 1);
94369
 
+       ctx_data->type = SIZE_UNASSIGNED;
94370
 
+       tst->data = ctx_data;
94371
 
+
94372
 
+       return TRUE;
94373
 
+}
94374
 
+
94375
 
+static bool tst_size_validate
94376
 
+       (struct sieve_validator *validator, struct sieve_command_context *tst) 
94377
 
+{
94378
 
+       struct tst_size_context_data *ctx_data = 
94379
 
+               (struct tst_size_context_data *) tst->data;
94380
 
+       struct sieve_ast_argument *arg = tst->first_positional;
94381
 
+       
94382
 
+       if ( ctx_data->type == SIZE_UNASSIGNED ) {
94383
 
+               sieve_command_validate_error(validator, tst, 
94384
 
+                       "the size test requires either the :under or the :over tag "
94385
 
+                       "to be specified");
94386
 
+               return FALSE;           
94387
 
+       }
94388
 
+               
94389
 
+       if ( !sieve_validate_positional_argument
94390
 
+               (validator, tst, arg, "limit", 1, SAAT_NUMBER) ) {
94391
 
+               return FALSE;
94392
 
+       }
94393
 
+       
94394
 
+       return sieve_validator_argument_activate(validator, tst, arg, FALSE);
94395
 
+}
94396
 
+
94397
 
+/* 
94398
 
+ * Code generation 
94399
 
+ */
94400
 
+
94401
 
+bool tst_size_generate
94402
 
+(const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx) 
94403
 
+{
94404
 
+       struct tst_size_context_data *ctx_data = 
94405
 
+               (struct tst_size_context_data *) ctx->data;
94406
 
+
94407
 
+       if ( ctx_data->type == SIZE_OVER ) 
94408
 
+               sieve_operation_emit_code(cgenv->sbin, &tst_size_over_operation);
94409
 
+       else
94410
 
+               sieve_operation_emit_code(cgenv->sbin, &tst_size_under_operation);
94411
 
+
94412
 
+       /* Generate arguments */
94413
 
+       if ( !sieve_generate_arguments(cgenv, ctx, NULL) )
94414
 
+               return FALSE;
94415
 
+         
94416
 
+       return TRUE;
94417
 
+}
94418
 
+
94419
 
+/* 
94420
 
+ * Code dump 
94421
 
+ */
94422
 
+
94423
 
+static bool tst_size_operation_dump
94424
 
+(const struct sieve_operation *op,
94425
 
+       const struct sieve_dumptime_env *denv, sieve_size_t *address)
94426
 
+{
94427
 
+    sieve_code_dumpf(denv, "%s", op->mnemonic);
94428
 
+       sieve_code_descend(denv);
94429
 
+       
94430
 
+       return 
94431
 
+               sieve_opr_number_dump(denv, address, "limit");
94432
 
+}
94433
 
+
94434
 
+/* 
94435
 
+ * Code execution 
94436
 
+ */
94437
 
+
94438
 
+static inline bool tst_size_get
94439
 
+(const struct sieve_runtime_env *renv, sieve_number_t *size) 
94440
 
+{
94441
 
+       uoff_t psize;
94442
 
+
94443
 
+       if ( mail_get_physical_size(renv->msgdata->mail, &psize) < 0 )
94444
 
+               return FALSE;
94445
 
+
94446
 
+       *size = psize;
94447
 
+  
94448
 
+       return TRUE;
94449
 
+}
94450
 
+
94451
 
+static int tst_size_operation_execute
94452
 
+(const struct sieve_operation *op,
94453
 
+       const struct sieve_runtime_env *renv, sieve_size_t *address)
94454
 
+{
94455
 
+       sieve_number_t mail_size, limit;
94456
 
+               
94457
 
+       /* Read size limit */
94458
 
+       if ( !sieve_opr_number_read(renv, address, &limit) ) {
94459
 
+               sieve_runtime_trace_error(renv, "invalid limit operand");
94460
 
+               return SIEVE_EXEC_BIN_CORRUPT;  
94461
 
+       }
94462
 
+
94463
 
+       sieve_runtime_trace(renv, "%s test", op->mnemonic);
94464
 
+       
94465
 
+       /* Get the size of the message */
94466
 
+       if ( !tst_size_get(renv, &mail_size) ) {
94467
 
+               /* FIXME: improve this error */
94468
 
+               sieve_sys_error("failed to assess message size");
94469
 
+               return SIEVE_EXEC_FAILURE;
94470
 
+       }
94471
 
+       
94472
 
+       /* Perform the test */
94473
 
+       if ( op == &tst_size_over_operation )
94474
 
+               sieve_interpreter_set_test_result(renv->interp, (mail_size > limit));
94475
 
+       else
94476
 
+               sieve_interpreter_set_test_result(renv->interp, (mail_size < limit));
94477
 
+
94478
 
+       return SIEVE_EXEC_OK;
94479
 
+}
94480
 
+
94481
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/tst-truefalse.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/tst-truefalse.c
94482
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve/tst-truefalse.c        1970-01-01 01:00:00.000000000 +0100
94483
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve/tst-truefalse.c 2009-01-06 00:15:52.000000000 +0100
94484
 
@@ -0,0 +1,65 @@
94485
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
94486
 
+ */
94487
 
+
94488
 
+#include "sieve-ast.h"
94489
 
+#include "sieve-validator.h"
94490
 
+#include "sieve-generator.h"
94491
 
+#include "sieve-binary.h"
94492
 
+
94493
 
+#include "sieve-commands.h"
94494
 
+#include "sieve-code.h"
94495
 
+#include "sieve-interpreter.h"
94496
 
+
94497
 
+/*
94498
 
+ * True/False test command
94499
 
+ */
94500
 
+
94501
 
+static bool tst_false_generate
94502
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_command_context *cmd,
94503
 
+               struct sieve_jumplist *jumps, bool jump_true);
94504
 
+static bool tst_true_generate
94505
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_command_context *cmd,
94506
 
+               struct sieve_jumplist *jumps, bool jump_true);
94507
 
+
94508
 
+const struct sieve_command tst_false = { 
94509
 
+       "false", 
94510
 
+       SCT_TEST, 
94511
 
+       0, 0, FALSE, FALSE,
94512
 
+       NULL, NULL, NULL, NULL, 
94513
 
+       tst_false_generate 
94514
 
+};
94515
 
+
94516
 
+const struct sieve_command tst_true = { 
94517
 
+       "true", 
94518
 
+       SCT_TEST, 
94519
 
+       0, 0, FALSE, FALSE,
94520
 
+       NULL, NULL, NULL, NULL, 
94521
 
+       tst_true_generate 
94522
 
+};
94523
 
+
94524
 
+static bool tst_false_generate
94525
 
+(const struct sieve_codegen_env *cgenv, 
94526
 
+       struct sieve_command_context *cmd ATTR_UNUSED,
94527
 
+       struct sieve_jumplist *jumps, bool jump_true)
94528
 
+{
94529
 
+       if ( !jump_true ) {
94530
 
+               sieve_operation_emit_code(cgenv->sbin, &sieve_jmp_operation);
94531
 
+               sieve_jumplist_add(jumps, sieve_binary_emit_offset(cgenv->sbin, 0));
94532
 
+       }
94533
 
+       
94534
 
+       return TRUE;
94535
 
+}
94536
 
+
94537
 
+static bool tst_true_generate
94538
 
+(const struct sieve_codegen_env *cgenv,        
94539
 
+       struct sieve_command_context *cmd ATTR_UNUSED,
94540
 
+       struct sieve_jumplist *jumps, bool jump_true)
94541
 
+{
94542
 
+       if ( jump_true ) {
94543
 
+               sieve_operation_emit_code(cgenv->sbin, &sieve_jmp_operation);
94544
 
+               sieve_jumplist_add(jumps, sieve_binary_emit_offset(cgenv->sbin, 0));
94545
 
+       }
94546
 
+       
94547
 
+       return TRUE;
94548
 
+}
94549
 
+
94550
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve-tool/mail-raw.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve-tool/mail-raw.c
94551
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve-tool/mail-raw.c        1970-01-01 01:00:00.000000000 +0100
94552
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve-tool/mail-raw.c 2009-05-29 22:29:27.000000000 +0200
94553
 
@@ -0,0 +1,284 @@
94554
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
94555
 
+ */
94556
 
+
94557
 
+/* FIXME: This file was gratefully stolen from dovecot/src/deliver/deliver.c and 
94558
 
+ * altered to suit our needs. So, this contains lots and lots of duplicated 
94559
 
+ * code. 
94560
 
+ */
94561
 
+
94562
 
+#include "lib.h"
94563
 
+#include "istream.h"
94564
 
+#include "istream-seekable.h"
94565
 
+#include "fd-set-nonblock.h"
94566
 
+#include "str.h"
94567
 
+#include "str-sanitize.h"
94568
 
+#include "strescape.h"
94569
 
+#include "safe-mkstemp.h"
94570
 
+#include "close-keep-errno.h"
94571
 
+#include "mkdir-parents.h"
94572
 
+#include "message-address.h"
94573
 
+#include "mbox-from.h"
94574
 
+#include "raw-storage.h"
94575
 
+#include "mail-namespace.h"
94576
 
+
94577
 
+#include "mail-raw.h"
94578
 
+
94579
 
+#include <stdio.h>
94580
 
+#include <stdlib.h>
94581
 
+#include <unistd.h>
94582
 
+#include <fcntl.h>
94583
 
+#include <pwd.h>
94584
 
+
94585
 
+/*
94586
 
+ * Configuration
94587
 
+ */
94588
 
+
94589
 
+#define DEFAULT_ENVELOPE_SENDER "MAILER-DAEMON"
94590
 
+
94591
 
+/* After buffer grows larger than this, create a temporary file to /tmp
94592
 
+   where to read the mail. */
94593
 
+#define MAIL_MAX_MEMORY_BUFFER (1024*128)
94594
 
+
94595
 
+static const char *wanted_headers[] = {
94596
 
+       "From", "Message-ID", "Subject", "Return-Path",
94597
 
+       NULL
94598
 
+};
94599
 
+
94600
 
+/*
94601
 
+ * Global data
94602
 
+ */
94603
 
+
94604
 
+static struct mail_namespace *raw_ns;
94605
 
+static struct mail_user *raw_mail_user;
94606
 
+
94607
 
+/*
94608
 
+ * Raw mail implementation
94609
 
+ */
94610
 
+
94611
 
+static int seekable_fd_callback
94612
 
+(const char **path_r, void *context ATTR_UNUSED)
94613
 
+{
94614
 
+       const char *dir, *p;
94615
 
+       string_t *path;
94616
 
+       int fd;
94617
 
+
94618
 
+       path = t_str_new(128);
94619
 
+       str_append(path, "/tmp/dovecot.sieve-tool.");
94620
 
+       fd = safe_mkstemp(path, 0600, (uid_t)-1, (gid_t)-1);
94621
 
+       if (fd == -1 && errno == ENOENT) {
94622
 
+               dir = str_c(path);
94623
 
+               p = strrchr(dir, '/');
94624
 
+               if (p != NULL) {
94625
 
+                       dir = t_strdup_until(dir, p);
94626
 
+                       if ( mkdir_parents(dir, 0600) < 0 ) {
94627
 
+                               i_error("mkdir_parents(%s) failed: %m", dir);
94628
 
+                               return -1;
94629
 
+                       }
94630
 
+                       fd = safe_mkstemp(path, 0600, (uid_t)-1, (gid_t)-1);
94631
 
+               }
94632
 
+       }
94633
 
+
94634
 
+       if (fd == -1) {
94635
 
+               i_error("safe_mkstemp(%s) failed: %m", str_c(path));
94636
 
+               return -1;
94637
 
+       }
94638
 
+
94639
 
+       /* we just want the fd, unlink it */
94640
 
+       if (unlink(str_c(path)) < 0) {
94641
 
+               /* shouldn't happen.. */
94642
 
+               i_error("unlink(%s) failed: %m", str_c(path));
94643
 
+               close_keep_errno(fd);
94644
 
+               return -1;
94645
 
+       }
94646
 
+
94647
 
+       *path_r = str_c(path);
94648
 
+       return fd;
94649
 
+}
94650
 
+
94651
 
+static struct istream *create_raw_stream
94652
 
+(int fd, time_t *mtime_r, const char **sender)
94653
 
+{
94654
 
+       struct istream *input, *input2, *input_list[2];
94655
 
+       const unsigned char *data;
94656
 
+       size_t i, size;
94657
 
+       int ret, tz;
94658
 
+       char *env_sender;
94659
 
+
94660
 
+       *mtime_r = (time_t)-1;
94661
 
+       fd_set_nonblock(fd, FALSE);
94662
 
+
94663
 
+       input = i_stream_create_fd(fd, 4096, FALSE);
94664
 
+       input->blocking = TRUE;
94665
 
+       /* If input begins with a From-line, drop it */
94666
 
+       ret = i_stream_read_data(input, &data, &size, 5);
94667
 
+       if (ret > 0 && size >= 5 && memcmp(data, "From ", 5) == 0) {
94668
 
+               /* skip until the first LF */
94669
 
+               i_stream_skip(input, 5);
94670
 
+               while ((ret = i_stream_read_data(input, &data, &size, 0)) > 0) {
94671
 
+                       for (i = 0; i < size; i++) {
94672
 
+                               if (data[i] == '\n')
94673
 
+                                       break;
94674
 
+                       }
94675
 
+                       if (i != size) {
94676
 
+                               (void)mbox_from_parse(data, i, mtime_r, &tz, &env_sender);
94677
 
+                               i_stream_skip(input, i + 1);
94678
 
+                               break;
94679
 
+                       }
94680
 
+                       i_stream_skip(input, size);
94681
 
+               }
94682
 
+       }
94683
 
+
94684
 
+       if (sender != NULL) {
94685
 
+               *sender = t_strdup(env_sender);
94686
 
+       }
94687
 
+       i_free(env_sender);
94688
 
+
94689
 
+       if (input->v_offset == 0) {
94690
 
+               input2 = input;
94691
 
+               i_stream_ref(input2);
94692
 
+       } else {
94693
 
+               input2 = i_stream_create_limit(input, (uoff_t)-1);
94694
 
+       }
94695
 
+       i_stream_unref(&input);
94696
 
+
94697
 
+    input_list[0] = input2; input_list[1] = NULL;
94698
 
+    input = i_stream_create_seekable(input_list, MAIL_MAX_MEMORY_BUFFER,
94699
 
+                     seekable_fd_callback, raw_mail_user);
94700
 
+    i_stream_unref(&input2);
94701
 
+    return input;
94702
 
+
94703
 
+}
94704
 
+
94705
 
+/*
94706
 
+ * Init/Deinit
94707
 
+ */
94708
 
+
94709
 
+void mail_raw_init(const char *user) 
94710
 
+{
94711
 
+       const char *error;
94712
 
+
94713
 
+       raw_mail_user = mail_user_init(user);
94714
 
+       mail_user_set_home(raw_mail_user, NULL);
94715
 
+       raw_ns = mail_namespaces_init_empty(raw_mail_user);
94716
 
+       raw_ns->flags |= NAMESPACE_FLAG_NOQUOTA | NAMESPACE_FLAG_NOACL;
94717
 
+       
94718
 
+       if ( mail_storage_create(raw_ns, "raw", "/tmp",
94719
 
+               MAIL_STORAGE_FLAG_FULL_FS_ACCESS,
94720
 
+               FILE_LOCK_METHOD_FCNTL, &error) < 0 ) {
94721
 
+               i_fatal("Couldn't create internal raw storage: %s", error);
94722
 
+       }
94723
 
+}
94724
 
+
94725
 
+void mail_raw_deinit(void)
94726
 
+{
94727
 
+       mail_user_unref(&raw_mail_user);
94728
 
+}
94729
 
+
94730
 
+
94731
 
+/*
94732
 
+ * Open raw mail data
94733
 
+ */
94734
 
+
94735
 
+static struct mail_raw *mail_raw_create
94736
 
+(struct istream *input, const char *mailfile, const char *sender,
94737
 
+       time_t mtime)
94738
 
+{
94739
 
+       pool_t pool;
94740
 
+       struct raw_mailbox *raw_box;
94741
 
+       struct mail_raw *mailr;
94742
 
+       enum mail_error error;
94743
 
+
94744
 
+       if ( mailfile != NULL ) {
94745
 
+               if ( *mailfile != '/') {
94746
 
+                       char cwd[PATH_MAX];
94747
 
+
94748
 
+                       /* Expand relative paths */
94749
 
+                       if (getcwd(cwd, sizeof(cwd)) == NULL)
94750
 
+                               i_fatal("getcwd() failed: %m");
94751
 
+
94752
 
+                       mailfile = t_strconcat(cwd, "/", mailfile, NULL);               
94753
 
+               } 
94754
 
+       }
94755
 
+
94756
 
+       pool = pool_alloconly_create("mail_raw", 1024);
94757
 
+       mailr = p_new(pool, struct mail_raw, 1);
94758
 
+       mailr->pool = pool;
94759
 
+
94760
 
+       if ( mailfile == NULL ) {
94761
 
+               mailr->box = mailbox_open(&raw_ns->storage, "Dovecot Raw Mail",
94762
 
+                                  input, MAILBOX_OPEN_NO_INDEX_FILES);
94763
 
+       } else {
94764
 
+               mtime = (time_t)-1;
94765
 
+               mailr->box = mailbox_open(&raw_ns->storage, mailfile, NULL,
94766
 
+                                  MAILBOX_OPEN_NO_INDEX_FILES);
94767
 
+       }
94768
 
+
94769
 
+       if ( mailr->box == NULL ) {
94770
 
+               i_fatal("Can't open mail stream as raw: %s",
94771
 
+                       mail_storage_get_last_error(raw_ns->storage, &error));
94772
 
+       }
94773
 
+
94774
 
+       if ( mailbox_sync(mailr->box, 0, 0, NULL ) < 0) {
94775
 
+               enum mail_error error;
94776
 
+
94777
 
+               i_fatal("Can't sync delivery mail: %s",
94778
 
+                       mail_storage_get_last_error(raw_ns->storage, &error));
94779
 
+       }
94780
 
+
94781
 
+       raw_box = (struct raw_mailbox *)mailr->box;
94782
 
+       raw_box->envelope_sender = sender != NULL ? sender : DEFAULT_ENVELOPE_SENDER;
94783
 
+       raw_box->mtime = mtime;
94784
 
+
94785
 
+       mailr->trans = mailbox_transaction_begin(mailr->box, 0);
94786
 
+       mailr->headers_ctx = mailbox_header_lookup_init(mailr->box, wanted_headers);
94787
 
+       mailr->mail = mail_alloc(mailr->trans, 0, mailr->headers_ctx);
94788
 
+       mail_set_seq(mailr->mail, 1);
94789
 
+
94790
 
+       return mailr;
94791
 
+}
94792
 
+
94793
 
+struct mail_raw *mail_raw_open_data(string_t *mail_data)
94794
 
+{
94795
 
+       struct mail_raw *mailr;
94796
 
+       struct istream *input;
94797
 
+
94798
 
+       input = i_stream_create_from_data(str_data(mail_data), str_len(mail_data));
94799
 
+       
94800
 
+       mailr = mail_raw_create(input, NULL, NULL, (time_t)-1);
94801
 
+
94802
 
+       i_stream_unref(&input);
94803
 
+
94804
 
+       return mailr;
94805
 
+}
94806
 
+       
94807
 
+struct mail_raw *mail_raw_open_file(const char *path)
94808
 
+{
94809
 
+       struct mail_raw *mailr;
94810
 
+       struct istream *input = NULL;
94811
 
+       time_t mtime;
94812
 
+       const char *sender = NULL;
94813
 
+       
94814
 
+       if ( path == NULL || strcmp(path, "-") == 0 ) {
94815
 
+               path = NULL;
94816
 
+               input = create_raw_stream(0, &mtime, &sender);
94817
 
+       }
94818
 
+
94819
 
+       mailr = mail_raw_create(input, path, sender, mtime);
94820
 
+
94821
 
+       if ( input != NULL )
94822
 
+               i_stream_unref(&input);
94823
 
+
94824
 
+       return mailr;
94825
 
+}
94826
 
+
94827
 
+void mail_raw_close(struct mail_raw *mailr) 
94828
 
+{
94829
 
+       mailbox_header_lookup_unref(&mailr->headers_ctx);
94830
 
+
94831
 
+       mail_free(&mailr->mail);
94832
 
+       mailbox_transaction_rollback(&mailr->trans);
94833
 
+       mailbox_close(&mailr->box);
94834
 
+
94835
 
+       pool_unref(&mailr->pool);
94836
 
+}
94837
 
+
94838
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve-tool/mail-raw.h dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve-tool/mail-raw.h
94839
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve-tool/mail-raw.h        1970-01-01 01:00:00.000000000 +0100
94840
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve-tool/mail-raw.h 2009-01-06 00:15:52.000000000 +0100
94841
 
@@ -0,0 +1,24 @@
94842
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
94843
 
+ */
94844
 
+
94845
 
+#ifndef __MAIL_RAW_H
94846
 
+#define __MAIL_RAW_H
94847
 
+
94848
 
+struct mail_raw {
94849
 
+       pool_t pool;
94850
 
+       struct mail *mail;
94851
 
+
94852
 
+       struct mailbox *box;
94853
 
+       struct mailbox_header_lookup_ctx *headers_ctx;
94854
 
+       struct mailbox_transaction_context *trans;
94855
 
+};
94856
 
+
94857
 
+void mail_raw_init(const char *user);
94858
 
+void mail_raw_deinit(void);
94859
 
+
94860
 
+struct mail_raw *mail_raw_open_file(const char *path);
94861
 
+struct mail_raw *mail_raw_open_data(string_t *mail_data);
94862
 
+void mail_raw_close(struct mail_raw *mailr);
94863
 
+
94864
 
+
94865
 
+#endif /* __MAIL_RAW_H */
94866
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve-tool/Makefile.am dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve-tool/Makefile.am
94867
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve-tool/Makefile.am       1970-01-01 01:00:00.000000000 +0100
94868
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve-tool/Makefile.am        2008-11-05 15:33:35.000000000 +0100
94869
 
@@ -0,0 +1,19 @@
94870
 
+noinst_LTLIBRARIES = libsieve-tool.la
94871
 
+
94872
 
+AM_CPPFLAGS = \
94873
 
+       -I$(top_srcdir)/src/lib-sieve \
94874
 
+       -I$(dovecot_incdir) \
94875
 
+       -I$(dovecot_incdir)/src/lib \
94876
 
+       -I$(dovecot_incdir)/src/lib-mail \
94877
 
+       -I$(dovecot_incdir)/src/lib-index \
94878
 
+       -I$(dovecot_incdir)/src/lib-storage \
94879
 
+       -I$(dovecot_incdir)/src/lib-storage/index \
94880
 
+       -I$(dovecot_incdir)/src/lib-storage/index/raw
94881
 
+
94882
 
+libsieve_tool_la_SOURCES = \
94883
 
+       sieve-tool.c \
94884
 
+       mail-raw.c
94885
 
+
94886
 
+noinst_HEADERS = \
94887
 
+       sieve-tool.h \
94888
 
+       mail-raw.h
94889
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve-tool/Makefile.in dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve-tool/Makefile.in
94890
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve-tool/Makefile.in       1970-01-01 01:00:00.000000000 +0100
94891
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve-tool/Makefile.in        2009-08-21 00:55:42.000000000 +0200
94892
 
@@ -0,0 +1,465 @@
94893
 
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
94894
 
+# @configure_input@
94895
 
+
94896
 
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
94897
 
+# 2003, 2004, 2005, 2006, 2007, 2008  Free Software Foundation, Inc.
94898
 
+# This Makefile.in is free software; the Free Software Foundation
94899
 
+# gives unlimited permission to copy and/or distribute it,
94900
 
+# with or without modifications, as long as this notice is preserved.
94901
 
+
94902
 
+# This program is distributed in the hope that it will be useful,
94903
 
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
94904
 
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
94905
 
+# PARTICULAR PURPOSE.
94906
 
+
94907
 
+@SET_MAKE@
94908
 
+
94909
 
+
94910
 
+VPATH = @srcdir@
94911
 
+pkgdatadir = $(datadir)/@PACKAGE@
94912
 
+pkglibdir = $(libdir)/@PACKAGE@
94913
 
+pkgincludedir = $(includedir)/@PACKAGE@
94914
 
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
94915
 
+install_sh_DATA = $(install_sh) -c -m 644
94916
 
+install_sh_PROGRAM = $(install_sh) -c
94917
 
+install_sh_SCRIPT = $(install_sh) -c
94918
 
+INSTALL_HEADER = $(INSTALL_DATA)
94919
 
+transform = $(program_transform_name)
94920
 
+NORMAL_INSTALL = :
94921
 
+PRE_INSTALL = :
94922
 
+POST_INSTALL = :
94923
 
+NORMAL_UNINSTALL = :
94924
 
+PRE_UNINSTALL = :
94925
 
+POST_UNINSTALL = :
94926
 
+build_triplet = @build@
94927
 
+host_triplet = @host@
94928
 
+subdir = src/lib-sieve-tool
94929
 
+DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
94930
 
+       $(srcdir)/Makefile.in
94931
 
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
94932
 
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
94933
 
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
94934
 
+       $(ACLOCAL_M4)
94935
 
+mkinstalldirs = $(install_sh) -d
94936
 
+CONFIG_HEADER = $(top_builddir)/dummy-config.h \
94937
 
+       $(top_builddir)/dsieve-config.h
94938
 
+CONFIG_CLEAN_FILES =
94939
 
+LTLIBRARIES = $(noinst_LTLIBRARIES)
94940
 
+libsieve_tool_la_LIBADD =
94941
 
+am_libsieve_tool_la_OBJECTS = sieve-tool.lo mail-raw.lo
94942
 
+libsieve_tool_la_OBJECTS = $(am_libsieve_tool_la_OBJECTS)
94943
 
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
94944
 
+depcomp = $(SHELL) $(top_srcdir)/depcomp
94945
 
+am__depfiles_maybe = depfiles
94946
 
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
94947
 
+       $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
94948
 
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
94949
 
+       --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
94950
 
+       $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
94951
 
+CCLD = $(CC)
94952
 
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
94953
 
+       --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
94954
 
+       $(LDFLAGS) -o $@
94955
 
+SOURCES = $(libsieve_tool_la_SOURCES)
94956
 
+DIST_SOURCES = $(libsieve_tool_la_SOURCES)
94957
 
+HEADERS = $(noinst_HEADERS)
94958
 
+ETAGS = etags
94959
 
+CTAGS = ctags
94960
 
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
94961
 
+ACLOCAL = @ACLOCAL@
94962
 
+AMTAR = @AMTAR@
94963
 
+AR = @AR@
94964
 
+AUTOCONF = @AUTOCONF@
94965
 
+AUTOHEADER = @AUTOHEADER@
94966
 
+AUTOMAKE = @AUTOMAKE@
94967
 
+AWK = @AWK@
94968
 
+CC = @CC@
94969
 
+CCDEPMODE = @CCDEPMODE@
94970
 
+CFLAGS = @CFLAGS@
94971
 
+CPP = @CPP@
94972
 
+CPPFLAGS = @CPPFLAGS@
94973
 
+CYGPATH_W = @CYGPATH_W@
94974
 
+DEFS = @DEFS@
94975
 
+DEPDIR = @DEPDIR@
94976
 
+DSYMUTIL = @DSYMUTIL@
94977
 
+DUMPBIN = @DUMPBIN@
94978
 
+ECHO_C = @ECHO_C@
94979
 
+ECHO_N = @ECHO_N@
94980
 
+ECHO_T = @ECHO_T@
94981
 
+EGREP = @EGREP@
94982
 
+EXEEXT = @EXEEXT@
94983
 
+FGREP = @FGREP@
94984
 
+GREP = @GREP@
94985
 
+INSTALL = @INSTALL@
94986
 
+INSTALL_DATA = @INSTALL_DATA@
94987
 
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
94988
 
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
94989
 
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
94990
 
+LD = @LD@
94991
 
+LDFLAGS = @LDFLAGS@
94992
 
+LIBICONV = @LIBICONV@
94993
 
+LIBOBJS = @LIBOBJS@
94994
 
+LIBS = @LIBS@
94995
 
+LIBTOOL = @LIBTOOL@
94996
 
+LIPO = @LIPO@
94997
 
+LN_S = @LN_S@
94998
 
+LTLIBOBJS = @LTLIBOBJS@
94999
 
+MAINT = @MAINT@
95000
 
+MAKEINFO = @MAKEINFO@
95001
 
+MKDIR_P = @MKDIR_P@
95002
 
+MODULE_LIBS = @MODULE_LIBS@
95003
 
+NM = @NM@
95004
 
+NMEDIT = @NMEDIT@
95005
 
+OBJDUMP = @OBJDUMP@
95006
 
+OBJEXT = @OBJEXT@
95007
 
+OTOOL = @OTOOL@
95008
 
+OTOOL64 = @OTOOL64@
95009
 
+PACKAGE = @PACKAGE@
95010
 
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
95011
 
+PACKAGE_NAME = @PACKAGE_NAME@
95012
 
+PACKAGE_STRING = @PACKAGE_STRING@
95013
 
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
95014
 
+PACKAGE_URL = @PACKAGE_URL@
95015
 
+PACKAGE_VERSION = @PACKAGE_VERSION@
95016
 
+PATH_SEPARATOR = @PATH_SEPARATOR@
95017
 
+RAND_LIBS = @RAND_LIBS@
95018
 
+RANLIB = @RANLIB@
95019
 
+SED = @SED@
95020
 
+SET_MAKE = @SET_MAKE@
95021
 
+SHELL = @SHELL@
95022
 
+STORAGE_LIBS = @STORAGE_LIBS@
95023
 
+STRIP = @STRIP@
95024
 
+VERSION = @VERSION@
95025
 
+abs_builddir = @abs_builddir@
95026
 
+abs_srcdir = @abs_srcdir@
95027
 
+abs_top_builddir = @abs_top_builddir@
95028
 
+abs_top_srcdir = @abs_top_srcdir@
95029
 
+ac_ct_CC = @ac_ct_CC@
95030
 
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
95031
 
+am__include = @am__include@
95032
 
+am__leading_dot = @am__leading_dot@
95033
 
+am__quote = @am__quote@
95034
 
+am__tar = @am__tar@
95035
 
+am__untar = @am__untar@
95036
 
+bindir = @bindir@
95037
 
+build = @build@
95038
 
+build_alias = @build_alias@
95039
 
+build_cpu = @build_cpu@
95040
 
+build_os = @build_os@
95041
 
+build_vendor = @build_vendor@
95042
 
+builddir = @builddir@
95043
 
+datadir = @datadir@
95044
 
+datarootdir = @datarootdir@
95045
 
+docdir = @docdir@
95046
 
+dovecot_incdir = @dovecot_incdir@
95047
 
+dovecotdir = @dovecotdir@
95048
 
+dvidir = @dvidir@
95049
 
+exec_prefix = @exec_prefix@
95050
 
+host = @host@
95051
 
+host_alias = @host_alias@
95052
 
+host_cpu = @host_cpu@
95053
 
+host_os = @host_os@
95054
 
+host_vendor = @host_vendor@
95055
 
+htmldir = @htmldir@
95056
 
+includedir = @includedir@
95057
 
+infodir = @infodir@
95058
 
+install_sh = @install_sh@
95059
 
+libdir = @libdir@
95060
 
+libexecdir = @libexecdir@
95061
 
+localedir = @localedir@
95062
 
+localstatedir = @localstatedir@
95063
 
+lt_ECHO = @lt_ECHO@
95064
 
+mandir = @mandir@
95065
 
+mkdir_p = @mkdir_p@
95066
 
+moduledir = @moduledir@
95067
 
+oldincludedir = @oldincludedir@
95068
 
+pdfdir = @pdfdir@
95069
 
+prefix = @prefix@
95070
 
+program_transform_name = @program_transform_name@
95071
 
+psdir = @psdir@
95072
 
+sbindir = @sbindir@
95073
 
+sharedstatedir = @sharedstatedir@
95074
 
+srcdir = @srcdir@
95075
 
+sysconfdir = @sysconfdir@
95076
 
+target_alias = @target_alias@
95077
 
+top_build_prefix = @top_build_prefix@
95078
 
+top_builddir = @top_builddir@
95079
 
+top_srcdir = @top_srcdir@
95080
 
+noinst_LTLIBRARIES = libsieve-tool.la
95081
 
+AM_CPPFLAGS = \
95082
 
+       -I$(top_srcdir)/src/lib-sieve \
95083
 
+       -I$(dovecot_incdir) \
95084
 
+       -I$(dovecot_incdir)/src/lib \
95085
 
+       -I$(dovecot_incdir)/src/lib-mail \
95086
 
+       -I$(dovecot_incdir)/src/lib-index \
95087
 
+       -I$(dovecot_incdir)/src/lib-storage \
95088
 
+       -I$(dovecot_incdir)/src/lib-storage/index \
95089
 
+       -I$(dovecot_incdir)/src/lib-storage/index/raw
95090
 
+
95091
 
+libsieve_tool_la_SOURCES = \
95092
 
+       sieve-tool.c \
95093
 
+       mail-raw.c
95094
 
+
95095
 
+noinst_HEADERS = \
95096
 
+       sieve-tool.h \
95097
 
+       mail-raw.h
95098
 
+
95099
 
+all: all-am
95100
 
+
95101
 
+.SUFFIXES:
95102
 
+.SUFFIXES: .c .lo .o .obj
95103
 
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
95104
 
+       @for dep in $?; do \
95105
 
+         case '$(am__configure_deps)' in \
95106
 
+           *$$dep*) \
95107
 
+             ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
95108
 
+               && { if test -f $@; then exit 0; else break; fi; }; \
95109
 
+             exit 1;; \
95110
 
+         esac; \
95111
 
+       done; \
95112
 
+       echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign  src/lib-sieve-tool/Makefile'; \
95113
 
+       cd $(top_srcdir) && \
95114
 
+         $(AUTOMAKE) --foreign  src/lib-sieve-tool/Makefile
95115
 
+.PRECIOUS: Makefile
95116
 
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
95117
 
+       @case '$?' in \
95118
 
+         *config.status*) \
95119
 
+           cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
95120
 
+         *) \
95121
 
+           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
95122
 
+           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
95123
 
+       esac;
95124
 
+
95125
 
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
95126
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
95127
 
+
95128
 
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
95129
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
95130
 
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
95131
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
95132
 
+
95133
 
+clean-noinstLTLIBRARIES:
95134
 
+       -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
95135
 
+       @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
95136
 
+         dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
95137
 
+         test "$$dir" != "$$p" || dir=.; \
95138
 
+         echo "rm -f \"$${dir}/so_locations\""; \
95139
 
+         rm -f "$${dir}/so_locations"; \
95140
 
+       done
95141
 
+libsieve-tool.la: $(libsieve_tool_la_OBJECTS) $(libsieve_tool_la_DEPENDENCIES) 
95142
 
+       $(LINK)  $(libsieve_tool_la_OBJECTS) $(libsieve_tool_la_LIBADD) $(LIBS)
95143
 
+
95144
 
+mostlyclean-compile:
95145
 
+       -rm -f *.$(OBJEXT)
95146
 
+
95147
 
+distclean-compile:
95148
 
+       -rm -f *.tab.c
95149
 
+
95150
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mail-raw.Plo@am__quote@
95151
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-tool.Plo@am__quote@
95152
 
+
95153
 
+.c.o:
95154
 
+@am__fastdepCC_TRUE@   $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
95155
 
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
95156
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
95157
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
95158
 
+@am__fastdepCC_FALSE@  $(COMPILE) -c $<
95159
 
+
95160
 
+.c.obj:
95161
 
+@am__fastdepCC_TRUE@   $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
95162
 
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
95163
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
95164
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
95165
 
+@am__fastdepCC_FALSE@  $(COMPILE) -c `$(CYGPATH_W) '$<'`
95166
 
+
95167
 
+.c.lo:
95168
 
+@am__fastdepCC_TRUE@   $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
95169
 
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
95170
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
95171
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
95172
 
+@am__fastdepCC_FALSE@  $(LTCOMPILE) -c -o $@ $<
95173
 
+
95174
 
+mostlyclean-libtool:
95175
 
+       -rm -f *.lo
95176
 
+
95177
 
+clean-libtool:
95178
 
+       -rm -rf .libs _libs
95179
 
+
95180
 
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
95181
 
+       list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
95182
 
+       unique=`for i in $$list; do \
95183
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
95184
 
+         done | \
95185
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
95186
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
95187
 
+       mkid -fID $$unique
95188
 
+tags: TAGS
95189
 
+
95190
 
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
95191
 
+               $(TAGS_FILES) $(LISP)
95192
 
+       tags=; \
95193
 
+       here=`pwd`; \
95194
 
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
95195
 
+       unique=`for i in $$list; do \
95196
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
95197
 
+         done | \
95198
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
95199
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
95200
 
+       if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
95201
 
+         test -n "$$unique" || unique=$$empty_fix; \
95202
 
+         $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
95203
 
+           $$tags $$unique; \
95204
 
+       fi
95205
 
+ctags: CTAGS
95206
 
+CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
95207
 
+               $(TAGS_FILES) $(LISP)
95208
 
+       tags=; \
95209
 
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
95210
 
+       unique=`for i in $$list; do \
95211
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
95212
 
+         done | \
95213
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
95214
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
95215
 
+       test -z "$(CTAGS_ARGS)$$tags$$unique" \
95216
 
+         || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
95217
 
+            $$tags $$unique
95218
 
+
95219
 
+GTAGS:
95220
 
+       here=`$(am__cd) $(top_builddir) && pwd` \
95221
 
+         && cd $(top_srcdir) \
95222
 
+         && gtags -i $(GTAGS_ARGS) $$here
95223
 
+
95224
 
+distclean-tags:
95225
 
+       -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
95226
 
+
95227
 
+distdir: $(DISTFILES)
95228
 
+       @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
95229
 
+       topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
95230
 
+       list='$(DISTFILES)'; \
95231
 
+         dist_files=`for file in $$list; do echo $$file; done | \
95232
 
+         sed -e "s|^$$srcdirstrip/||;t" \
95233
 
+             -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
95234
 
+       case $$dist_files in \
95235
 
+         */*) $(MKDIR_P) `echo "$$dist_files" | \
95236
 
+                          sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
95237
 
+                          sort -u` ;; \
95238
 
+       esac; \
95239
 
+       for file in $$dist_files; do \
95240
 
+         if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
95241
 
+         if test -d $$d/$$file; then \
95242
 
+           dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
95243
 
+           if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
95244
 
+             cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
95245
 
+           fi; \
95246
 
+           cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
95247
 
+         else \
95248
 
+           test -f $(distdir)/$$file \
95249
 
+           || cp -p $$d/$$file $(distdir)/$$file \
95250
 
+           || exit 1; \
95251
 
+         fi; \
95252
 
+       done
95253
 
+check-am: all-am
95254
 
+check: check-am
95255
 
+all-am: Makefile $(LTLIBRARIES) $(HEADERS)
95256
 
+installdirs:
95257
 
+install: install-am
95258
 
+install-exec: install-exec-am
95259
 
+install-data: install-data-am
95260
 
+uninstall: uninstall-am
95261
 
+
95262
 
+install-am: all-am
95263
 
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
95264
 
+
95265
 
+installcheck: installcheck-am
95266
 
+install-strip:
95267
 
+       $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
95268
 
+         install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
95269
 
+         `test -z '$(STRIP)' || \
95270
 
+           echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
95271
 
+mostlyclean-generic:
95272
 
+
95273
 
+clean-generic:
95274
 
+
95275
 
+distclean-generic:
95276
 
+       -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
95277
 
+
95278
 
+maintainer-clean-generic:
95279
 
+       @echo "This command is intended for maintainers to use"
95280
 
+       @echo "it deletes files that may require special tools to rebuild."
95281
 
+clean: clean-am
95282
 
+
95283
 
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
95284
 
+       mostlyclean-am
95285
 
+
95286
 
+distclean: distclean-am
95287
 
+       -rm -rf ./$(DEPDIR)
95288
 
+       -rm -f Makefile
95289
 
+distclean-am: clean-am distclean-compile distclean-generic \
95290
 
+       distclean-tags
95291
 
+
95292
 
+dvi: dvi-am
95293
 
+
95294
 
+dvi-am:
95295
 
+
95296
 
+html: html-am
95297
 
+
95298
 
+info: info-am
95299
 
+
95300
 
+info-am:
95301
 
+
95302
 
+install-data-am:
95303
 
+
95304
 
+install-dvi: install-dvi-am
95305
 
+
95306
 
+install-exec-am:
95307
 
+
95308
 
+install-html: install-html-am
95309
 
+
95310
 
+install-info: install-info-am
95311
 
+
95312
 
+install-man:
95313
 
+
95314
 
+install-pdf: install-pdf-am
95315
 
+
95316
 
+install-ps: install-ps-am
95317
 
+
95318
 
+installcheck-am:
95319
 
+
95320
 
+maintainer-clean: maintainer-clean-am
95321
 
+       -rm -rf ./$(DEPDIR)
95322
 
+       -rm -f Makefile
95323
 
+maintainer-clean-am: distclean-am maintainer-clean-generic
95324
 
+
95325
 
+mostlyclean: mostlyclean-am
95326
 
+
95327
 
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
95328
 
+       mostlyclean-libtool
95329
 
+
95330
 
+pdf: pdf-am
95331
 
+
95332
 
+pdf-am:
95333
 
+
95334
 
+ps: ps-am
95335
 
+
95336
 
+ps-am:
95337
 
+
95338
 
+uninstall-am:
95339
 
+
95340
 
+.MAKE: install-am install-strip
95341
 
+
95342
 
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
95343
 
+       clean-libtool clean-noinstLTLIBRARIES ctags distclean \
95344
 
+       distclean-compile distclean-generic distclean-libtool \
95345
 
+       distclean-tags distdir dvi dvi-am html html-am info info-am \
95346
 
+       install install-am install-data install-data-am install-dvi \
95347
 
+       install-dvi-am install-exec install-exec-am install-html \
95348
 
+       install-html-am install-info install-info-am install-man \
95349
 
+       install-pdf install-pdf-am install-ps install-ps-am \
95350
 
+       install-strip installcheck installcheck-am installdirs \
95351
 
+       maintainer-clean maintainer-clean-generic mostlyclean \
95352
 
+       mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
95353
 
+       pdf pdf-am ps ps-am tags uninstall uninstall-am
95354
 
+
95355
 
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
95356
 
+# Otherwise a system limit (for SysV at least) may be exceeded.
95357
 
+.NOEXPORT:
95358
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve-tool/sieve-tool.c dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve-tool/sieve-tool.c
95359
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve-tool/sieve-tool.c      1970-01-01 01:00:00.000000000 +0100
95360
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve-tool/sieve-tool.c       2009-04-08 18:41:46.000000000 +0200
95361
 
@@ -0,0 +1,190 @@
95362
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
95363
 
+ */
95364
 
+
95365
 
+#include "lib.h"
95366
 
+#include "lib-signals.h"
95367
 
+#include "ioloop.h"
95368
 
+#include "ostream.h"
95369
 
+#include "hostpid.h"
95370
 
+#include "mail-storage.h"
95371
 
+
95372
 
+#include "sieve.h"
95373
 
+#include "sieve-tool.h"
95374
 
+
95375
 
+#include <stdio.h>
95376
 
+#include <stdlib.h>
95377
 
+#include <unistd.h>
95378
 
+#include <fcntl.h>
95379
 
+#include <pwd.h>
95380
 
+
95381
 
+/*
95382
 
+ * Global state
95383
 
+ */
95384
 
+
95385
 
+static struct ioloop *ioloop;
95386
 
+
95387
 
+/*
95388
 
+ * Signal handlers
95389
 
+ */
95390
 
+
95391
 
+static void sig_die(const siginfo_t *si, void *context ATTR_UNUSED)
95392
 
+{
95393
 
+       /* warn about being killed because of some signal, except SIGINT (^C)
95394
 
+        * which is too common at least while testing :) 
95395
 
+        */
95396
 
+        if (si->si_signo != SIGINT) {
95397
 
+               /* FIMXE: strange error for a command line tool */
95398
 
+               i_warning("Killed with signal %d (by pid=%s uid=%s code=%s)",
95399
 
+                       si->si_signo, dec2str(si->si_pid),
95400
 
+                       dec2str(si->si_uid),
95401
 
+                       lib_signal_code_to_str(si->si_signo, si->si_code));
95402
 
+        }
95403
 
+        io_loop_stop(current_ioloop);
95404
 
+}
95405
 
+
95406
 
+/*
95407
 
+ * Initialization
95408
 
+ */
95409
 
+
95410
 
+void sieve_tool_init(void) 
95411
 
+{
95412
 
+       lib_init();
95413
 
+
95414
 
+       ioloop = io_loop_create();
95415
 
+
95416
 
+       lib_signals_init();
95417
 
+       lib_signals_set_handler(SIGINT, TRUE, sig_die, NULL);
95418
 
+       lib_signals_set_handler(SIGTERM, TRUE, sig_die, NULL);
95419
 
+       lib_signals_ignore(SIGPIPE, TRUE);
95420
 
+       lib_signals_ignore(SIGALRM, FALSE);
95421
 
+
95422
 
+       if ( !sieve_init() ) 
95423
 
+               i_fatal("failed to initialize sieve implementation\n");
95424
 
+}
95425
 
+
95426
 
+void sieve_tool_deinit(void)
95427
 
+{
95428
 
+       sieve_deinit();
95429
 
+       
95430
 
+       lib_signals_deinit();
95431
 
+
95432
 
+       io_loop_destroy(&ioloop);
95433
 
+       lib_deinit();
95434
 
+}
95435
 
+
95436
 
+/*
95437
 
+ * Commonly needed functionality
95438
 
+ */
95439
 
+
95440
 
+const char *sieve_tool_get_user(void)
95441
 
+{
95442
 
+       const char *user;
95443
 
+       uid_t process_euid;
95444
 
+       struct passwd *pw;
95445
 
+
95446
 
+       user = getenv("USER");
95447
 
+
95448
 
+       if ( user == NULL || *user == '\0' ) {
95449
 
+               process_euid = geteuid();
95450
 
+
95451
 
+               if ((pw = getpwuid(process_euid)) != NULL) {
95452
 
+                       user = t_strdup(pw->pw_name);
95453
 
+               }
95454
 
+
95455
 
+               if ( user == NULL || *user == '\0' ) {
95456
 
+                       i_fatal("couldn't lookup our username (uid=%s)", dec2str(process_euid));
95457
 
+               }
95458
 
+       }
95459
 
+       
95460
 
+       return user;
95461
 
+}
95462
 
+
95463
 
+void sieve_tool_get_envelope_data
95464
 
+       (struct mail *mail, const char **recipient, const char **sender)
95465
 
+{
95466
 
+       /* Get recipient address */
95467
 
+       if ( *recipient == NULL ) 
95468
 
+               (void)mail_get_first_header(mail, "Envelope-To", recipient);
95469
 
+       if ( *recipient == NULL ) 
95470
 
+               (void)mail_get_first_header(mail, "To", recipient);
95471
 
+       if ( *recipient == NULL ) 
95472
 
+               *recipient = "recipient@example.com";
95473
 
+       
95474
 
+       /* Get sender address */
95475
 
+       if ( *sender == NULL ) 
95476
 
+               (void)mail_get_first_header(mail, "Return-path", sender);
95477
 
+       if ( *sender == NULL ) 
95478
 
+               (void)mail_get_first_header(mail, "Sender", sender);
95479
 
+       if ( *sender == NULL ) 
95480
 
+               (void)mail_get_first_header(mail, "From", sender);
95481
 
+       if ( *sender == NULL ) 
95482
 
+               *sender = "sender@example.com";
95483
 
+}
95484
 
+
95485
 
+/*
95486
 
+ * Sieve script handling
95487
 
+ */
95488
 
+
95489
 
+struct sieve_binary *sieve_tool_script_compile
95490
 
+(const char *filename, const char *name)
95491
 
+{
95492
 
+       struct sieve_error_handler *ehandler;
95493
 
+       struct sieve_binary *sbin;
95494
 
+       
95495
 
+       ehandler = sieve_stderr_ehandler_create(0);
95496
 
+       sieve_error_handler_accept_infolog(ehandler, TRUE);
95497
 
+
95498
 
+       if ( (sbin = sieve_compile(filename, name, ehandler)) == NULL )
95499
 
+               i_error("failed to compile sieve script '%s'\n", filename);
95500
 
+
95501
 
+       sieve_error_handler_unref(&ehandler);
95502
 
+               
95503
 
+       return sbin;
95504
 
+}
95505
 
+       
95506
 
+struct sieve_binary *sieve_tool_script_open(const char *filename)
95507
 
+{
95508
 
+       struct sieve_error_handler *ehandler;
95509
 
+       struct sieve_binary *sbin;
95510
 
+       
95511
 
+       ehandler = sieve_stderr_ehandler_create(0);
95512
 
+       sieve_error_handler_accept_infolog(ehandler, TRUE);
95513
 
+
95514
 
+       if ( (sbin = sieve_open(filename, NULL, ehandler, NULL)) == NULL ) {
95515
 
+               sieve_error_handler_unref(&ehandler);
95516
 
+               i_fatal("Failed to compile sieve script\n");
95517
 
+       }
95518
 
+
95519
 
+       sieve_error_handler_unref(&ehandler);
95520
 
+               
95521
 
+       return sbin;
95522
 
+}
95523
 
+       
95524
 
+void sieve_tool_dump_binary_to(struct sieve_binary *sbin, const char *filename)        
95525
 
+{
95526
 
+       int dfd = -1;
95527
 
+       struct ostream *dumpstream;
95528
 
+       
95529
 
+       if ( filename == NULL ) return;
95530
 
+       
95531
 
+       if ( strcmp(filename, "-") == 0 ) 
95532
 
+               dumpstream = o_stream_create_fd(1, 0, FALSE);
95533
 
+       else {
95534
 
+               if ( (dfd = open(filename, O_WRONLY | O_TRUNC | O_CREAT, 0600)) < 0 ) {
95535
 
+                       i_fatal("failed to open dump-file for writing: %m");
95536
 
+               }
95537
 
+               
95538
 
+               dumpstream = o_stream_create_fd(dfd, 0, FALSE);
95539
 
+       }
95540
 
+       
95541
 
+       if ( dumpstream != NULL ) {
95542
 
+               (void) sieve_dump(sbin, dumpstream);
95543
 
+               o_stream_destroy(&dumpstream);
95544
 
+       } else {
95545
 
+               i_fatal("Failed to create stream for sieve code dump.");
95546
 
+       }
95547
 
+       
95548
 
+       if ( dfd != -1 )
95549
 
+               close(dfd);
95550
 
+}
95551
 
+
95552
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/lib-sieve-tool/sieve-tool.h dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve-tool/sieve-tool.h
95553
 
--- dovecot-1.2.4/dovecot-libsieve/src/lib-sieve-tool/sieve-tool.h      1970-01-01 01:00:00.000000000 +0100
95554
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/lib-sieve-tool/sieve-tool.h       2009-01-10 20:32:19.000000000 +0100
95555
 
@@ -0,0 +1,34 @@
95556
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
95557
 
+ */
95558
 
+
95559
 
+#ifndef __SIEVE_TOOL_H
95560
 
+#define __SIEVE_TOOL_H
95561
 
+
95562
 
+/* Functionality common to all Sieve command line tools. */
95563
 
+
95564
 
+/*
95565
 
+ * Initialization
95566
 
+ */
95567
 
+
95568
 
+void sieve_tool_init(void);
95569
 
+void sieve_tool_deinit(void);
95570
 
+
95571
 
+/*
95572
 
+ * Commonly needed functionality
95573
 
+ */
95574
 
+
95575
 
+const char *sieve_tool_get_user(void);
95576
 
+
95577
 
+void sieve_tool_get_envelope_data
95578
 
+       (struct mail *mail, const char **recipient, const char **sender);
95579
 
+
95580
 
+/*
95581
 
+ * Sieve script handling
95582
 
+ */
95583
 
+
95584
 
+struct sieve_binary *sieve_tool_script_compile
95585
 
+       (const char *filename, const char *name);
95586
 
+struct sieve_binary *sieve_tool_script_open(const char *filename);
95587
 
+void sieve_tool_dump_binary_to(struct sieve_binary *sbin, const char *filename);
95588
 
+
95589
 
+#endif /* __SIEVE_TOOL_H */
95590
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/Makefile.am dovecot-1.2.4.debian/dovecot-libsieve/src/Makefile.am
95591
 
--- dovecot-1.2.4/dovecot-libsieve/src/Makefile.am      1970-01-01 01:00:00.000000000 +0100
95592
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/Makefile.am       2008-11-12 15:08:08.000000000 +0100
95593
 
@@ -0,0 +1,6 @@
95594
 
+if HAVE_DOVECOT_LIBS
95595
 
+LIB_DEPEND_DIRS=lib-sieve-tool sieve-tools testsuite
95596
 
+endif
95597
 
+
95598
 
+SUBDIRS = lib-sieve plugins $(LIB_DEPEND_DIRS)
95599
 
+
95600
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/Makefile.in dovecot-1.2.4.debian/dovecot-libsieve/src/Makefile.in
95601
 
--- dovecot-1.2.4/dovecot-libsieve/src/Makefile.in      1970-01-01 01:00:00.000000000 +0100
95602
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/Makefile.in       2009-08-21 00:55:42.000000000 +0200
95603
 
@@ -0,0 +1,494 @@
95604
 
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
95605
 
+# @configure_input@
95606
 
+
95607
 
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
95608
 
+# 2003, 2004, 2005, 2006, 2007, 2008  Free Software Foundation, Inc.
95609
 
+# This Makefile.in is free software; the Free Software Foundation
95610
 
+# gives unlimited permission to copy and/or distribute it,
95611
 
+# with or without modifications, as long as this notice is preserved.
95612
 
+
95613
 
+# This program is distributed in the hope that it will be useful,
95614
 
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
95615
 
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
95616
 
+# PARTICULAR PURPOSE.
95617
 
+
95618
 
+@SET_MAKE@
95619
 
+VPATH = @srcdir@
95620
 
+pkgdatadir = $(datadir)/@PACKAGE@
95621
 
+pkglibdir = $(libdir)/@PACKAGE@
95622
 
+pkgincludedir = $(includedir)/@PACKAGE@
95623
 
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
95624
 
+install_sh_DATA = $(install_sh) -c -m 644
95625
 
+install_sh_PROGRAM = $(install_sh) -c
95626
 
+install_sh_SCRIPT = $(install_sh) -c
95627
 
+INSTALL_HEADER = $(INSTALL_DATA)
95628
 
+transform = $(program_transform_name)
95629
 
+NORMAL_INSTALL = :
95630
 
+PRE_INSTALL = :
95631
 
+POST_INSTALL = :
95632
 
+NORMAL_UNINSTALL = :
95633
 
+PRE_UNINSTALL = :
95634
 
+POST_UNINSTALL = :
95635
 
+build_triplet = @build@
95636
 
+host_triplet = @host@
95637
 
+subdir = src
95638
 
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
95639
 
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
95640
 
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
95641
 
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
95642
 
+       $(ACLOCAL_M4)
95643
 
+mkinstalldirs = $(install_sh) -d
95644
 
+CONFIG_HEADER = $(top_builddir)/dummy-config.h \
95645
 
+       $(top_builddir)/dsieve-config.h
95646
 
+CONFIG_CLEAN_FILES =
95647
 
+SOURCES =
95648
 
+DIST_SOURCES =
95649
 
+RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
95650
 
+       html-recursive info-recursive install-data-recursive \
95651
 
+       install-dvi-recursive install-exec-recursive \
95652
 
+       install-html-recursive install-info-recursive \
95653
 
+       install-pdf-recursive install-ps-recursive install-recursive \
95654
 
+       installcheck-recursive installdirs-recursive pdf-recursive \
95655
 
+       ps-recursive uninstall-recursive
95656
 
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive        \
95657
 
+  distclean-recursive maintainer-clean-recursive
95658
 
+ETAGS = etags
95659
 
+CTAGS = ctags
95660
 
+DIST_SUBDIRS = lib-sieve plugins lib-sieve-tool sieve-tools testsuite
95661
 
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
95662
 
+ACLOCAL = @ACLOCAL@
95663
 
+AMTAR = @AMTAR@
95664
 
+AR = @AR@
95665
 
+AUTOCONF = @AUTOCONF@
95666
 
+AUTOHEADER = @AUTOHEADER@
95667
 
+AUTOMAKE = @AUTOMAKE@
95668
 
+AWK = @AWK@
95669
 
+CC = @CC@
95670
 
+CCDEPMODE = @CCDEPMODE@
95671
 
+CFLAGS = @CFLAGS@
95672
 
+CPP = @CPP@
95673
 
+CPPFLAGS = @CPPFLAGS@
95674
 
+CYGPATH_W = @CYGPATH_W@
95675
 
+DEFS = @DEFS@
95676
 
+DEPDIR = @DEPDIR@
95677
 
+DSYMUTIL = @DSYMUTIL@
95678
 
+DUMPBIN = @DUMPBIN@
95679
 
+ECHO_C = @ECHO_C@
95680
 
+ECHO_N = @ECHO_N@
95681
 
+ECHO_T = @ECHO_T@
95682
 
+EGREP = @EGREP@
95683
 
+EXEEXT = @EXEEXT@
95684
 
+FGREP = @FGREP@
95685
 
+GREP = @GREP@
95686
 
+INSTALL = @INSTALL@
95687
 
+INSTALL_DATA = @INSTALL_DATA@
95688
 
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
95689
 
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
95690
 
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
95691
 
+LD = @LD@
95692
 
+LDFLAGS = @LDFLAGS@
95693
 
+LIBICONV = @LIBICONV@
95694
 
+LIBOBJS = @LIBOBJS@
95695
 
+LIBS = @LIBS@
95696
 
+LIBTOOL = @LIBTOOL@
95697
 
+LIPO = @LIPO@
95698
 
+LN_S = @LN_S@
95699
 
+LTLIBOBJS = @LTLIBOBJS@
95700
 
+MAINT = @MAINT@
95701
 
+MAKEINFO = @MAKEINFO@
95702
 
+MKDIR_P = @MKDIR_P@
95703
 
+MODULE_LIBS = @MODULE_LIBS@
95704
 
+NM = @NM@
95705
 
+NMEDIT = @NMEDIT@
95706
 
+OBJDUMP = @OBJDUMP@
95707
 
+OBJEXT = @OBJEXT@
95708
 
+OTOOL = @OTOOL@
95709
 
+OTOOL64 = @OTOOL64@
95710
 
+PACKAGE = @PACKAGE@
95711
 
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
95712
 
+PACKAGE_NAME = @PACKAGE_NAME@
95713
 
+PACKAGE_STRING = @PACKAGE_STRING@
95714
 
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
95715
 
+PACKAGE_URL = @PACKAGE_URL@
95716
 
+PACKAGE_VERSION = @PACKAGE_VERSION@
95717
 
+PATH_SEPARATOR = @PATH_SEPARATOR@
95718
 
+RAND_LIBS = @RAND_LIBS@
95719
 
+RANLIB = @RANLIB@
95720
 
+SED = @SED@
95721
 
+SET_MAKE = @SET_MAKE@
95722
 
+SHELL = @SHELL@
95723
 
+STORAGE_LIBS = @STORAGE_LIBS@
95724
 
+STRIP = @STRIP@
95725
 
+VERSION = @VERSION@
95726
 
+abs_builddir = @abs_builddir@
95727
 
+abs_srcdir = @abs_srcdir@
95728
 
+abs_top_builddir = @abs_top_builddir@
95729
 
+abs_top_srcdir = @abs_top_srcdir@
95730
 
+ac_ct_CC = @ac_ct_CC@
95731
 
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
95732
 
+am__include = @am__include@
95733
 
+am__leading_dot = @am__leading_dot@
95734
 
+am__quote = @am__quote@
95735
 
+am__tar = @am__tar@
95736
 
+am__untar = @am__untar@
95737
 
+bindir = @bindir@
95738
 
+build = @build@
95739
 
+build_alias = @build_alias@
95740
 
+build_cpu = @build_cpu@
95741
 
+build_os = @build_os@
95742
 
+build_vendor = @build_vendor@
95743
 
+builddir = @builddir@
95744
 
+datadir = @datadir@
95745
 
+datarootdir = @datarootdir@
95746
 
+docdir = @docdir@
95747
 
+dovecot_incdir = @dovecot_incdir@
95748
 
+dovecotdir = @dovecotdir@
95749
 
+dvidir = @dvidir@
95750
 
+exec_prefix = @exec_prefix@
95751
 
+host = @host@
95752
 
+host_alias = @host_alias@
95753
 
+host_cpu = @host_cpu@
95754
 
+host_os = @host_os@
95755
 
+host_vendor = @host_vendor@
95756
 
+htmldir = @htmldir@
95757
 
+includedir = @includedir@
95758
 
+infodir = @infodir@
95759
 
+install_sh = @install_sh@
95760
 
+libdir = @libdir@
95761
 
+libexecdir = @libexecdir@
95762
 
+localedir = @localedir@
95763
 
+localstatedir = @localstatedir@
95764
 
+lt_ECHO = @lt_ECHO@
95765
 
+mandir = @mandir@
95766
 
+mkdir_p = @mkdir_p@
95767
 
+moduledir = @moduledir@
95768
 
+oldincludedir = @oldincludedir@
95769
 
+pdfdir = @pdfdir@
95770
 
+prefix = @prefix@
95771
 
+program_transform_name = @program_transform_name@
95772
 
+psdir = @psdir@
95773
 
+sbindir = @sbindir@
95774
 
+sharedstatedir = @sharedstatedir@
95775
 
+srcdir = @srcdir@
95776
 
+sysconfdir = @sysconfdir@
95777
 
+target_alias = @target_alias@
95778
 
+top_build_prefix = @top_build_prefix@
95779
 
+top_builddir = @top_builddir@
95780
 
+top_srcdir = @top_srcdir@
95781
 
+@HAVE_DOVECOT_LIBS_TRUE@LIB_DEPEND_DIRS = lib-sieve-tool sieve-tools testsuite
95782
 
+SUBDIRS = lib-sieve plugins $(LIB_DEPEND_DIRS)
95783
 
+all: all-recursive
95784
 
+
95785
 
+.SUFFIXES:
95786
 
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
95787
 
+       @for dep in $?; do \
95788
 
+         case '$(am__configure_deps)' in \
95789
 
+           *$$dep*) \
95790
 
+             ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
95791
 
+               && { if test -f $@; then exit 0; else break; fi; }; \
95792
 
+             exit 1;; \
95793
 
+         esac; \
95794
 
+       done; \
95795
 
+       echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign  src/Makefile'; \
95796
 
+       cd $(top_srcdir) && \
95797
 
+         $(AUTOMAKE) --foreign  src/Makefile
95798
 
+.PRECIOUS: Makefile
95799
 
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
95800
 
+       @case '$?' in \
95801
 
+         *config.status*) \
95802
 
+           cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
95803
 
+         *) \
95804
 
+           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
95805
 
+           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
95806
 
+       esac;
95807
 
+
95808
 
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
95809
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
95810
 
+
95811
 
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
95812
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
95813
 
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
95814
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
95815
 
+
95816
 
+mostlyclean-libtool:
95817
 
+       -rm -f *.lo
95818
 
+
95819
 
+clean-libtool:
95820
 
+       -rm -rf .libs _libs
95821
 
+
95822
 
+# This directory's subdirectories are mostly independent; you can cd
95823
 
+# into them and run `make' without going through this Makefile.
95824
 
+# To change the values of `make' variables: instead of editing Makefiles,
95825
 
+# (1) if the variable is set in `config.status', edit `config.status'
95826
 
+#     (which will cause the Makefiles to be regenerated when you run `make');
95827
 
+# (2) otherwise, pass the desired values on the `make' command line.
95828
 
+$(RECURSIVE_TARGETS):
95829
 
+       @failcom='exit 1'; \
95830
 
+       for f in x $$MAKEFLAGS; do \
95831
 
+         case $$f in \
95832
 
+           *=* | --[!k]*);; \
95833
 
+           *k*) failcom='fail=yes';; \
95834
 
+         esac; \
95835
 
+       done; \
95836
 
+       dot_seen=no; \
95837
 
+       target=`echo $@ | sed s/-recursive//`; \
95838
 
+       list='$(SUBDIRS)'; for subdir in $$list; do \
95839
 
+         echo "Making $$target in $$subdir"; \
95840
 
+         if test "$$subdir" = "."; then \
95841
 
+           dot_seen=yes; \
95842
 
+           local_target="$$target-am"; \
95843
 
+         else \
95844
 
+           local_target="$$target"; \
95845
 
+         fi; \
95846
 
+         (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
95847
 
+         || eval $$failcom; \
95848
 
+       done; \
95849
 
+       if test "$$dot_seen" = "no"; then \
95850
 
+         $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
95851
 
+       fi; test -z "$$fail"
95852
 
+
95853
 
+$(RECURSIVE_CLEAN_TARGETS):
95854
 
+       @failcom='exit 1'; \
95855
 
+       for f in x $$MAKEFLAGS; do \
95856
 
+         case $$f in \
95857
 
+           *=* | --[!k]*);; \
95858
 
+           *k*) failcom='fail=yes';; \
95859
 
+         esac; \
95860
 
+       done; \
95861
 
+       dot_seen=no; \
95862
 
+       case "$@" in \
95863
 
+         distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
95864
 
+         *) list='$(SUBDIRS)' ;; \
95865
 
+       esac; \
95866
 
+       rev=''; for subdir in $$list; do \
95867
 
+         if test "$$subdir" = "."; then :; else \
95868
 
+           rev="$$subdir $$rev"; \
95869
 
+         fi; \
95870
 
+       done; \
95871
 
+       rev="$$rev ."; \
95872
 
+       target=`echo $@ | sed s/-recursive//`; \
95873
 
+       for subdir in $$rev; do \
95874
 
+         echo "Making $$target in $$subdir"; \
95875
 
+         if test "$$subdir" = "."; then \
95876
 
+           local_target="$$target-am"; \
95877
 
+         else \
95878
 
+           local_target="$$target"; \
95879
 
+         fi; \
95880
 
+         (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
95881
 
+         || eval $$failcom; \
95882
 
+       done && test -z "$$fail"
95883
 
+tags-recursive:
95884
 
+       list='$(SUBDIRS)'; for subdir in $$list; do \
95885
 
+         test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
95886
 
+       done
95887
 
+ctags-recursive:
95888
 
+       list='$(SUBDIRS)'; for subdir in $$list; do \
95889
 
+         test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
95890
 
+       done
95891
 
+
95892
 
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
95893
 
+       list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
95894
 
+       unique=`for i in $$list; do \
95895
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
95896
 
+         done | \
95897
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
95898
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
95899
 
+       mkid -fID $$unique
95900
 
+tags: TAGS
95901
 
+
95902
 
+TAGS: tags-recursive $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
95903
 
+               $(TAGS_FILES) $(LISP)
95904
 
+       tags=; \
95905
 
+       here=`pwd`; \
95906
 
+       if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
95907
 
+         include_option=--etags-include; \
95908
 
+         empty_fix=.; \
95909
 
+       else \
95910
 
+         include_option=--include; \
95911
 
+         empty_fix=; \
95912
 
+       fi; \
95913
 
+       list='$(SUBDIRS)'; for subdir in $$list; do \
95914
 
+         if test "$$subdir" = .; then :; else \
95915
 
+           test ! -f $$subdir/TAGS || \
95916
 
+             tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \
95917
 
+         fi; \
95918
 
+       done; \
95919
 
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
95920
 
+       unique=`for i in $$list; do \
95921
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
95922
 
+         done | \
95923
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
95924
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
95925
 
+       if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
95926
 
+         test -n "$$unique" || unique=$$empty_fix; \
95927
 
+         $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
95928
 
+           $$tags $$unique; \
95929
 
+       fi
95930
 
+ctags: CTAGS
95931
 
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
95932
 
+               $(TAGS_FILES) $(LISP)
95933
 
+       tags=; \
95934
 
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
95935
 
+       unique=`for i in $$list; do \
95936
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
95937
 
+         done | \
95938
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
95939
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
95940
 
+       test -z "$(CTAGS_ARGS)$$tags$$unique" \
95941
 
+         || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
95942
 
+            $$tags $$unique
95943
 
+
95944
 
+GTAGS:
95945
 
+       here=`$(am__cd) $(top_builddir) && pwd` \
95946
 
+         && cd $(top_srcdir) \
95947
 
+         && gtags -i $(GTAGS_ARGS) $$here
95948
 
+
95949
 
+distclean-tags:
95950
 
+       -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
95951
 
+
95952
 
+distdir: $(DISTFILES)
95953
 
+       @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
95954
 
+       topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
95955
 
+       list='$(DISTFILES)'; \
95956
 
+         dist_files=`for file in $$list; do echo $$file; done | \
95957
 
+         sed -e "s|^$$srcdirstrip/||;t" \
95958
 
+             -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
95959
 
+       case $$dist_files in \
95960
 
+         */*) $(MKDIR_P) `echo "$$dist_files" | \
95961
 
+                          sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
95962
 
+                          sort -u` ;; \
95963
 
+       esac; \
95964
 
+       for file in $$dist_files; do \
95965
 
+         if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
95966
 
+         if test -d $$d/$$file; then \
95967
 
+           dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
95968
 
+           if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
95969
 
+             cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
95970
 
+           fi; \
95971
 
+           cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
95972
 
+         else \
95973
 
+           test -f $(distdir)/$$file \
95974
 
+           || cp -p $$d/$$file $(distdir)/$$file \
95975
 
+           || exit 1; \
95976
 
+         fi; \
95977
 
+       done
95978
 
+       list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
95979
 
+         if test "$$subdir" = .; then :; else \
95980
 
+           test -d "$(distdir)/$$subdir" \
95981
 
+           || $(MKDIR_P) "$(distdir)/$$subdir" \
95982
 
+           || exit 1; \
95983
 
+           distdir=`$(am__cd) $(distdir) && pwd`; \
95984
 
+           top_distdir=`$(am__cd) $(top_distdir) && pwd`; \
95985
 
+           (cd $$subdir && \
95986
 
+             $(MAKE) $(AM_MAKEFLAGS) \
95987
 
+               top_distdir="$$top_distdir" \
95988
 
+               distdir="$$distdir/$$subdir" \
95989
 
+               am__remove_distdir=: \
95990
 
+               am__skip_length_check=: \
95991
 
+               distdir) \
95992
 
+             || exit 1; \
95993
 
+         fi; \
95994
 
+       done
95995
 
+check-am: all-am
95996
 
+check: check-recursive
95997
 
+all-am: Makefile
95998
 
+installdirs: installdirs-recursive
95999
 
+installdirs-am:
96000
 
+install: install-recursive
96001
 
+install-exec: install-exec-recursive
96002
 
+install-data: install-data-recursive
96003
 
+uninstall: uninstall-recursive
96004
 
+
96005
 
+install-am: all-am
96006
 
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
96007
 
+
96008
 
+installcheck: installcheck-recursive
96009
 
+install-strip:
96010
 
+       $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
96011
 
+         install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
96012
 
+         `test -z '$(STRIP)' || \
96013
 
+           echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
96014
 
+mostlyclean-generic:
96015
 
+
96016
 
+clean-generic:
96017
 
+
96018
 
+distclean-generic:
96019
 
+       -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
96020
 
+
96021
 
+maintainer-clean-generic:
96022
 
+       @echo "This command is intended for maintainers to use"
96023
 
+       @echo "it deletes files that may require special tools to rebuild."
96024
 
+clean: clean-recursive
96025
 
+
96026
 
+clean-am: clean-generic clean-libtool mostlyclean-am
96027
 
+
96028
 
+distclean: distclean-recursive
96029
 
+       -rm -f Makefile
96030
 
+distclean-am: clean-am distclean-generic distclean-tags
96031
 
+
96032
 
+dvi: dvi-recursive
96033
 
+
96034
 
+dvi-am:
96035
 
+
96036
 
+html: html-recursive
96037
 
+
96038
 
+info: info-recursive
96039
 
+
96040
 
+info-am:
96041
 
+
96042
 
+install-data-am:
96043
 
+
96044
 
+install-dvi: install-dvi-recursive
96045
 
+
96046
 
+install-exec-am:
96047
 
+
96048
 
+install-html: install-html-recursive
96049
 
+
96050
 
+install-info: install-info-recursive
96051
 
+
96052
 
+install-man:
96053
 
+
96054
 
+install-pdf: install-pdf-recursive
96055
 
+
96056
 
+install-ps: install-ps-recursive
96057
 
+
96058
 
+installcheck-am:
96059
 
+
96060
 
+maintainer-clean: maintainer-clean-recursive
96061
 
+       -rm -f Makefile
96062
 
+maintainer-clean-am: distclean-am maintainer-clean-generic
96063
 
+
96064
 
+mostlyclean: mostlyclean-recursive
96065
 
+
96066
 
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
96067
 
+
96068
 
+pdf: pdf-recursive
96069
 
+
96070
 
+pdf-am:
96071
 
+
96072
 
+ps: ps-recursive
96073
 
+
96074
 
+ps-am:
96075
 
+
96076
 
+uninstall-am:
96077
 
+
96078
 
+.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) install-am \
96079
 
+       install-strip
96080
 
+
96081
 
+.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
96082
 
+       all all-am check check-am clean clean-generic clean-libtool \
96083
 
+       ctags ctags-recursive distclean distclean-generic \
96084
 
+       distclean-libtool distclean-tags distdir dvi dvi-am html \
96085
 
+       html-am info info-am install install-am install-data \
96086
 
+       install-data-am install-dvi install-dvi-am install-exec \
96087
 
+       install-exec-am install-html install-html-am install-info \
96088
 
+       install-info-am install-man install-pdf install-pdf-am \
96089
 
+       install-ps install-ps-am install-strip installcheck \
96090
 
+       installcheck-am installdirs installdirs-am maintainer-clean \
96091
 
+       maintainer-clean-generic mostlyclean mostlyclean-generic \
96092
 
+       mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \
96093
 
+       uninstall uninstall-am
96094
 
+
96095
 
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
96096
 
+# Otherwise a system limit (for SysV at least) may be exceeded.
96097
 
+.NOEXPORT:
96098
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/plugins/lda-sieve/lda-sieve-plugin.c dovecot-1.2.4.debian/dovecot-libsieve/src/plugins/lda-sieve/lda-sieve-plugin.c
96099
 
--- dovecot-1.2.4/dovecot-libsieve/src/plugins/lda-sieve/lda-sieve-plugin.c     1970-01-01 01:00:00.000000000 +0100
96100
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/plugins/lda-sieve/lda-sieve-plugin.c      2009-08-04 18:46:26.000000000 +0200
96101
 
@@ -0,0 +1,665 @@
96102
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file 
96103
 
+ */
96104
 
+
96105
 
+#include "lib.h"
96106
 
+#include "array.h"
96107
 
+#include "home-expand.h"
96108
 
+#include "deliver.h"
96109
 
+#include "duplicate.h"
96110
 
+#include "smtp-client.h"
96111
 
+
96112
 
+#include "sieve.h"
96113
 
+
96114
 
+#include "lda-sieve-plugin.h"
96115
 
+
96116
 
+#include <stdlib.h>
96117
 
+#include <sys/stat.h>
96118
 
+#include <dirent.h>
96119
 
+
96120
 
+/*
96121
 
+ * Configuration
96122
 
+ */
96123
 
+
96124
 
+#define SIEVE_SCRIPT_PATH "~/.dovecot.sieve"
96125
 
+
96126
 
+#define LDA_SIEVE_MAX_USER_ERRORS 10
96127
 
+#define LDA_SIEVE_MAX_SYSTEM_ERRORS 100
96128
 
+
96129
 
+/*
96130
 
+ * Global variables 
96131
 
+ */
96132
 
+
96133
 
+static deliver_mail_func_t *next_deliver_mail;
96134
 
+
96135
 
+static bool lda_sieve_debug = FALSE;
96136
 
+
96137
 
+/*
96138
 
+ * Mail transmission
96139
 
+ */
96140
 
+
96141
 
+static void *lda_sieve_smtp_open(const char *destination,
96142
 
+       const char *return_path, FILE **file_r)
96143
 
+{
96144
 
+       return (void *) smtp_client_open(destination, return_path, file_r);
96145
 
+}
96146
 
+
96147
 
+static bool lda_sieve_smtp_close(void *handle)
96148
 
+{
96149
 
+       struct smtp_client *smtp_client = (struct smtp_client *) handle;
96150
 
+
96151
 
+       return ( smtp_client_close(smtp_client) == 0 );
96152
 
+}
96153
 
+
96154
 
+/*
96155
 
+ * Plugin implementation
96156
 
+ */
96157
 
+
96158
 
+struct lda_sieve_run_context {
96159
 
+       const char *const *script_files;
96160
 
+       unsigned int script_count;
96161
 
+
96162
 
+       const char *user_script;
96163
 
+       const char *main_script;
96164
 
+
96165
 
+       const struct sieve_message_data *msgdata;
96166
 
+       const struct sieve_script_env *scriptenv;
96167
 
+
96168
 
+       struct sieve_error_handler *user_ehandler;
96169
 
+       struct sieve_error_handler *master_ehandler;
96170
 
+       const char *userlog;
96171
 
+};
96172
 
+
96173
 
+static const char *lda_sieve_get_personal_path(void)
96174
 
+{
96175
 
+       const char *script_path, *home;
96176
 
+
96177
 
+       home = getenv("HOME");
96178
 
+
96179
 
+       /* userdb may specify Sieve path */
96180
 
+       script_path = getenv("SIEVE");
96181
 
+       if (script_path != NULL) {
96182
 
+               if (*script_path == '\0') {
96183
 
+                       /* disabled */
96184
 
+                       if ( lda_sieve_debug )
96185
 
+                               sieve_sys_info("empty script path, disabled");
96186
 
+                       return NULL;
96187
 
+               }
96188
 
+
96189
 
+               script_path = home_expand(script_path);
96190
 
+
96191
 
+               if (*script_path != '/' && *script_path != '\0') {
96192
 
+                       /* relative path. change to absolute. */
96193
 
+                       script_path = t_strconcat(getenv("HOME"), "/",
96194
 
+                                                 script_path, NULL);
96195
 
+               }
96196
 
+       } else {
96197
 
+               if (home == NULL) {
96198
 
+                       sieve_sys_error(
96199
 
+                               "path to user's main active personal script is unknown. "
96200
 
+                               "See http://wiki.dovecot.org/LDA/Sieve/Dovecot#configuration");
96201
 
+                       return NULL;
96202
 
+               }
96203
 
+
96204
 
+               script_path = home_expand(SIEVE_SCRIPT_PATH);
96205
 
+       }
96206
 
+
96207
 
+       return script_path;
96208
 
+}
96209
 
+
96210
 
+static const char *lda_sieve_get_default_path(void)
96211
 
+{
96212
 
+       const char *script_path;
96213
 
+
96214
 
+       /* Use global script path, if one exists */
96215
 
+       script_path = getenv("SIEVE_GLOBAL_PATH");
96216
 
+       if (script_path == NULL) {
96217
 
+               /* For backwards compatibility */
96218
 
+               script_path = getenv("GLOBAL_SCRIPT_PATH");
96219
 
+       }
96220
 
+
96221
 
+       return script_path;
96222
 
+}
96223
 
+
96224
 
+static void lda_sieve_multiscript_get_scriptfiles
96225
 
+(const char *script_path, ARRAY_TYPE(const_string) *scriptfiles)
96226
 
+{
96227
 
+       struct sieve_directory *sdir = sieve_directory_open(script_path);
96228
 
+
96229
 
+       if ( sdir != NULL ) {
96230
 
+               const char *file;
96231
 
+
96232
 
+               while ( (file=sieve_directory_get_scriptfile(sdir)) != NULL ) {
96233
 
+                       const char *const *scripts;
96234
 
+                       unsigned int count, i;
96235
 
+
96236
 
+                       /* Insert into sorted array */
96237
 
+
96238
 
+                       scripts = array_get(scriptfiles, &count);
96239
 
+                       for ( i = 0; i < count; i++ ) {
96240
 
+                               if ( strcmp(file, scripts[i]) < 0 )
96241
 
+                                       break;                  
96242
 
+                       }
96243
 
+       
96244
 
+                       if ( i == count ) 
96245
 
+                               array_append(scriptfiles, &file, 1);
96246
 
+                       else
96247
 
+                               array_insert(scriptfiles, i, &file, 1);
96248
 
+               }
96249
 
+
96250
 
+               sieve_directory_close(&sdir);
96251
 
+       } 
96252
 
+}
96253
 
+
96254
 
+static int lda_sieve_open
96255
 
+(struct lda_sieve_run_context *srctx, unsigned int script_index,
96256
 
+       struct sieve_binary **sbin)
96257
 
+{
96258
 
+       const char *script_path = srctx->script_files[script_index];
96259
 
+       const char *script_name = 
96260
 
+               ( script_path == srctx->main_script ? "main_script" : NULL );
96261
 
+       struct sieve_error_handler *ehandler;
96262
 
+       bool exists = TRUE;
96263
 
+       int ret = 0;
96264
 
+
96265
 
+       if ( script_path == srctx->user_script )
96266
 
+               ehandler = srctx->user_ehandler;
96267
 
+       else
96268
 
+               ehandler = srctx->master_ehandler;
96269
 
+
96270
 
+       if ( lda_sieve_debug )
96271
 
+               sieve_sys_info("opening script %s", script_path);               
96272
 
+
96273
 
+       sieve_error_handler_reset(ehandler);
96274
 
+
96275
 
+       if ( (*sbin=sieve_open(script_path, script_name, ehandler, &exists)) 
96276
 
+               == NULL ) {
96277
 
+
96278
 
+               ret = sieve_get_errors(ehandler) > 0 ? -1 : 0;
96279
 
+
96280
 
+               if ( !exists && ret == 0 ) {
96281
 
+                       if ( lda_sieve_debug )
96282
 
+                               sieve_sys_info("script file %s is missing", script_path);
96283
 
+               } else {
96284
 
+                       if ( script_path == srctx->user_script && srctx->userlog != NULL ) {
96285
 
+                               sieve_sys_error
96286
 
+                                       ("failed to open script %s "
96287
 
+                                               "(view logfile %s for more information)", 
96288
 
+                                               script_path, srctx->userlog);
96289
 
+                       } else {
96290
 
+                               sieve_sys_error
96291
 
+                                       ("failed to open script %s", 
96292
 
+                                               script_path);
96293
 
+                       }
96294
 
+               }
96295
 
+
96296
 
+               return ret;
96297
 
+       }
96298
 
+
96299
 
+       return 1;
96300
 
+}
96301
 
+
96302
 
+static struct sieve_binary *lda_sieve_recompile
96303
 
+(struct lda_sieve_run_context *srctx, unsigned int script_index)
96304
 
+{
96305
 
+       const char *script_path = srctx->script_files[script_index];
96306
 
+    const char *script_name = 
96307
 
+               ( script_path == srctx->main_script ? "main_script" : NULL );
96308
 
+    struct sieve_error_handler *ehandler;
96309
 
+       struct sieve_binary *sbin;
96310
 
+
96311
 
+       /* Warn */
96312
 
+
96313
 
+       sieve_sys_warning("encountered corrupt binary: recompiling script %s", 
96314
 
+               script_path);
96315
 
+
96316
 
+       /* Recompile */ 
96317
 
+
96318
 
+       if ( script_path == srctx->user_script )
96319
 
+               ehandler = srctx->user_ehandler;
96320
 
+       else
96321
 
+               ehandler = srctx->master_ehandler;
96322
 
+
96323
 
+       if ( (sbin=sieve_compile(script_path, script_name, ehandler)) == NULL ) {
96324
 
+
96325
 
+               if ( script_path == srctx->user_script && srctx->userlog != NULL ) {
96326
 
+                       sieve_sys_error
96327
 
+                               ("failed to re-compile script %s "
96328
 
+                                       "(view logfile %s for more information)",
96329
 
+                                       script_path, srctx->userlog);
96330
 
+               } else {
96331
 
+                       sieve_sys_error
96332
 
+                               ("failed to re-compile script %s", script_path);
96333
 
+               }
96334
 
+
96335
 
+               return NULL;
96336
 
+       }
96337
 
+
96338
 
+       return sbin;
96339
 
+}
96340
 
+
96341
 
+static int lda_sieve_handle_exec_status(const char *script_path, int status)
96342
 
+{
96343
 
+       int ret; 
96344
 
+
96345
 
+       switch ( status ) {
96346
 
+       case SIEVE_EXEC_FAILURE:
96347
 
+               sieve_sys_error
96348
 
+                       ("execution of script %s failed, but implicit keep was successful", 
96349
 
+                               script_path);
96350
 
+               ret = 1;
96351
 
+               break;
96352
 
+       case SIEVE_EXEC_BIN_CORRUPT:            
96353
 
+               sieve_sys_error
96354
 
+                       ("!!BUG!!: binary compiled from %s is still corrupt; "
96355
 
+                               "bailing out and reverting to default delivery", 
96356
 
+                               script_path);
96357
 
+               ret = -1;
96358
 
+               break;
96359
 
+       case SIEVE_EXEC_KEEP_FAILED:
96360
 
+               sieve_sys_error
96361
 
+                       ("script %s failed with unsuccessful implicit keep", script_path);
96362
 
+               ret = -1;
96363
 
+               break;
96364
 
+       default:
96365
 
+               ret = status > 0 ? 1 : -1;
96366
 
+               break;
96367
 
+       }
96368
 
+
96369
 
+       return ret;
96370
 
+}
96371
 
+
96372
 
+static int lda_sieve_singlescript_execute
96373
 
+(struct lda_sieve_run_context *srctx)
96374
 
+{
96375
 
+       const char *script_file = srctx->script_files[0];
96376
 
+    bool user_script = ( script_file == srctx->user_script );
96377
 
+       struct sieve_error_handler *ehandler;
96378
 
+       struct sieve_binary *sbin;
96379
 
+       int ret;
96380
 
+
96381
 
+       /* Open the script */
96382
 
+
96383
 
+       if ( (ret=lda_sieve_open(srctx, 0, &sbin)) <= 0 )
96384
 
+               return ret;
96385
 
+
96386
 
+       /* Execute */
96387
 
+
96388
 
+       if ( lda_sieve_debug )
96389
 
+               sieve_sys_info("executing compiled script %s", script_file);
96390
 
+
96391
 
+       if ( user_script ) {
96392
 
+               ehandler = srctx->user_ehandler;
96393
 
+               sieve_error_handler_copy_masterlog(ehandler, TRUE);     
96394
 
+       } else {
96395
 
+               ehandler = srctx->master_ehandler;
96396
 
+       }
96397
 
+
96398
 
+       ret = sieve_execute(sbin, srctx->msgdata, srctx->scriptenv, ehandler, NULL);
96399
 
+
96400
 
+       sieve_error_handler_copy_masterlog(ehandler, FALSE);    
96401
 
+
96402
 
+       /* Recompile if corrupt binary */
96403
 
+
96404
 
+       if ( ret == SIEVE_EXEC_BIN_CORRUPT ) {
96405
 
+               /* Close corrupt script */
96406
 
+
96407
 
+               sieve_close(&sbin);
96408
 
+
96409
 
+               /* Recompile */
96410
 
+
96411
 
+               if ( (sbin=lda_sieve_recompile(srctx, 0)) == NULL ) {
96412
 
+                       return -1;
96413
 
+               }
96414
 
+
96415
 
+               /* Execute again */
96416
 
+
96417
 
+               if ( user_script )
96418
 
+               sieve_error_handler_copy_masterlog(ehandler, TRUE);
96419
 
+
96420
 
+               ret = sieve_execute(sbin, srctx->msgdata, srctx->scriptenv, ehandler, NULL);
96421
 
+
96422
 
+               sieve_error_handler_copy_masterlog(ehandler, FALSE);
96423
 
+
96424
 
+               /* Save new version */
96425
 
+
96426
 
+               if ( ret != SIEVE_EXEC_BIN_CORRUPT )
96427
 
+                       sieve_save(sbin, NULL);
96428
 
+       }
96429
 
+
96430
 
+       sieve_close(&sbin);
96431
 
+
96432
 
+       /* Report status */
96433
 
+       return lda_sieve_handle_exec_status(script_file, ret);
96434
 
+}
96435
 
+
96436
 
+static int lda_sieve_multiscript_execute
96437
 
+(struct lda_sieve_run_context *srctx)
96438
 
+{
96439
 
+       const char *const *scripts = srctx->script_files;
96440
 
+       unsigned int count = srctx->script_count;
96441
 
+       struct sieve_multiscript *mscript;
96442
 
+       struct sieve_error_handler *ehandler = srctx->master_ehandler;
96443
 
+       const char *last_script = NULL;
96444
 
+       bool user_script = FALSE;
96445
 
+       unsigned int i;
96446
 
+       int ret = 1; 
96447
 
+       bool more = TRUE;
96448
 
+
96449
 
+       /* Start execution */
96450
 
+
96451
 
+       mscript = sieve_multiscript_start_execute(srctx->msgdata, srctx->scriptenv);
96452
 
+
96453
 
+       /* Execute scripts before main script */
96454
 
+
96455
 
+       for ( i = 0; i < count && more; i++ ) {
96456
 
+               struct sieve_binary *sbin = NULL;
96457
 
+               const char *script_file = scripts[i];
96458
 
+               bool final = ( i == count - 1 );
96459
 
+
96460
 
+               user_script = ( script_file == srctx->user_script );
96461
 
+               last_script = script_file;              
96462
 
+
96463
 
+               if ( user_script )
96464
 
+                       ehandler = srctx->user_ehandler;
96465
 
+               else
96466
 
+                       ehandler = srctx->master_ehandler;
96467
 
+
96468
 
+               /* Open */
96469
 
+       
96470
 
+               if ( (ret=lda_sieve_open(srctx, i, &sbin)) <= 0 )
96471
 
+                       break;
96472
 
+
96473
 
+               /* Execute */
96474
 
+
96475
 
+               if ( user_script )      
96476
 
+                       sieve_error_handler_copy_masterlog(ehandler, TRUE);
96477
 
+
96478
 
+               more = sieve_multiscript_run(mscript, sbin, ehandler, final);
96479
 
+
96480
 
+               sieve_error_handler_copy_masterlog(ehandler, FALSE);
96481
 
+
96482
 
+               if ( !more ) {
96483
 
+                       if ( sieve_multiscript_status(mscript) == SIEVE_EXEC_BIN_CORRUPT ) {
96484
 
+                               /* Close corrupt script */
96485
 
+
96486
 
+                               sieve_close(&sbin);
96487
 
+
96488
 
+                               /* Recompile */
96489
 
+
96490
 
+                               if ( (sbin=lda_sieve_recompile(srctx, i))
96491
 
+                                       == NULL ) {
96492
 
+                                       ret = -1;
96493
 
+                                       break;
96494
 
+                               }
96495
 
+
96496
 
+                               /* Execute again */
96497
 
+
96498
 
+                               if ( user_script )
96499
 
+                                       sieve_error_handler_copy_masterlog(ehandler, TRUE);
96500
 
+
96501
 
+                               more = sieve_multiscript_run(mscript, sbin, ehandler, final);
96502
 
+
96503
 
+                               sieve_error_handler_copy_masterlog(ehandler, FALSE);
96504
 
+
96505
 
+                               /* Save new version */
96506
 
+
96507
 
+                               if ( more && 
96508
 
+                                       sieve_multiscript_status(mscript) != SIEVE_EXEC_BIN_CORRUPT )
96509
 
+                                       sieve_save(sbin, NULL);
96510
 
+                       }
96511
 
+               }
96512
 
+
96513
 
+               sieve_close(&sbin);
96514
 
+       }
96515
 
+
96516
 
+       /* Finish execution */
96517
 
+
96518
 
+       if ( user_script )      
96519
 
+               sieve_error_handler_copy_masterlog(ehandler, TRUE);
96520
 
+
96521
 
+       ret = sieve_multiscript_finish(&mscript, ehandler, NULL);
96522
 
+
96523
 
+       sieve_error_handler_copy_masterlog(ehandler, FALSE);
96524
 
+
96525
 
+       return lda_sieve_handle_exec_status(last_script, ret);
96526
 
+}
96527
 
+
96528
 
+static int lda_sieve_run
96529
 
+(struct mail_namespace *namespaces, struct mail *mail, 
96530
 
+       const char *user_script, const char *default_script,
96531
 
+       const ARRAY_TYPE (const_string) *scripts_before, 
96532
 
+       const ARRAY_TYPE (const_string) *scripts_after, 
96533
 
+       const char *destaddr, const char *username, const char *mailbox, 
96534
 
+       struct mail_storage **storage_r)
96535
 
+{
96536
 
+       ARRAY_TYPE (const_string) scripts;
96537
 
+
96538
 
+       struct lda_sieve_run_context srctx;
96539
 
+       struct sieve_message_data msgdata;
96540
 
+       struct sieve_script_env scriptenv;
96541
 
+       struct sieve_exec_status estatus;
96542
 
+       int ret = 0;
96543
 
+
96544
 
+       *storage_r = NULL;
96545
 
+
96546
 
+       /* Initialize */
96547
 
+
96548
 
+       memset(&srctx, 0, sizeof(srctx));
96549
 
+
96550
 
+       /* Compose execution sequence */
96551
 
+
96552
 
+       t_array_init(&scripts, 32);
96553
 
+
96554
 
+       array_append_array(&scripts, scripts_before);
96555
 
+
96556
 
+       if ( user_script != NULL ) {
96557
 
+               array_append(&scripts, &user_script, 1);
96558
 
+               srctx.user_script = user_script;
96559
 
+               srctx.main_script = user_script;
96560
 
+       } else if ( default_script != NULL ) {
96561
 
+               array_append(&scripts, &default_script, 1);
96562
 
+               srctx.user_script = NULL;
96563
 
+               srctx.main_script = default_script;
96564
 
+       } else {
96565
 
+               srctx.user_script = NULL;
96566
 
+        srctx.main_script = NULL;
96567
 
+       }
96568
 
+
96569
 
+       array_append_array(&scripts, scripts_after);
96570
 
+
96571
 
+       /* Create error handlers */
96572
 
+
96573
 
+       if ( user_script != NULL ) {
96574
 
+               srctx.userlog = t_strconcat(user_script, ".log", NULL);
96575
 
+               srctx.user_ehandler = sieve_logfile_ehandler_create(srctx.userlog, LDA_SIEVE_MAX_USER_ERRORS);
96576
 
+       }
96577
 
+
96578
 
+       srctx.master_ehandler = sieve_master_ehandler_create(LDA_SIEVE_MAX_SYSTEM_ERRORS);
96579
 
+       sieve_error_handler_accept_infolog(srctx.master_ehandler, TRUE);
96580
 
+
96581
 
+       /* Collect necessary message data */
96582
 
+
96583
 
+       memset(&msgdata, 0, sizeof(msgdata));
96584
 
+
96585
 
+       msgdata.mail = mail;
96586
 
+       msgdata.return_path = deliver_get_return_address(mail);
96587
 
+       msgdata.to_address = destaddr;
96588
 
+       msgdata.auth_user = username;
96589
 
+       (void)mail_get_first_header(mail, "Message-ID", &msgdata.id);
96590
 
+
96591
 
+       srctx.msgdata = &msgdata;
96592
 
+
96593
 
+       /* Compose script execution environment */
96594
 
+
96595
 
+       memset(&scriptenv, 0, sizeof(scriptenv));
96596
 
+       memset(&estatus, 0, sizeof(estatus));
96597
 
+
96598
 
+       scriptenv.default_mailbox = mailbox;
96599
 
+       scriptenv.mailbox_autocreate = deliver_set->mailbox_autocreate;
96600
 
+       scriptenv.mailbox_autosubscribe = deliver_set->mailbox_autosubscribe;
96601
 
+       scriptenv.namespaces = namespaces;
96602
 
+       scriptenv.username = username;
96603
 
+       scriptenv.hostname = deliver_set->hostname;
96604
 
+       scriptenv.postmaster_address = deliver_set->postmaster_address;
96605
 
+       scriptenv.smtp_open = lda_sieve_smtp_open;
96606
 
+       scriptenv.smtp_close = lda_sieve_smtp_close;
96607
 
+       scriptenv.duplicate_mark = duplicate_mark;
96608
 
+       scriptenv.duplicate_check = duplicate_check;
96609
 
+       scriptenv.exec_status = &estatus;
96610
 
+
96611
 
+       srctx.scriptenv = &scriptenv;
96612
 
+
96613
 
+       /* Assign script sequence */
96614
 
+
96615
 
+       srctx.script_files = array_get(&scripts, &srctx.script_count);
96616
 
+
96617
 
+       /* Execute script(s) */
96618
 
+
96619
 
+       if ( srctx.script_count == 1 )
96620
 
+               ret = lda_sieve_singlescript_execute(&srctx);
96621
 
+       else
96622
 
+               ret = lda_sieve_multiscript_execute(&srctx);    
96623
 
+
96624
 
+       /* Record status */
96625
 
+
96626
 
+       tried_default_save = estatus.tried_default_save;
96627
 
+       *storage_r = estatus.last_storage;
96628
 
+
96629
 
+       /* Clean up */
96630
 
+
96631
 
+       if ( srctx.user_ehandler != NULL )
96632
 
+               sieve_error_handler_unref(&srctx.user_ehandler);
96633
 
+       sieve_error_handler_unref(&srctx.master_ehandler);
96634
 
+
96635
 
+       return ret;
96636
 
+}
96637
 
+
96638
 
+static int lda_sieve_deliver_mail
96639
 
+(struct mail_namespace *namespaces, struct mail_storage **storage_r, 
96640
 
+       struct mail *mail, const char *destaddr, const char *mailbox)
96641
 
+{
96642
 
+       const char *user_script, *default_script, *sieve_before, *sieve_after;
96643
 
+       ARRAY_TYPE (const_string) scripts_before;
96644
 
+       ARRAY_TYPE (const_string) scripts_after;
96645
 
+       int ret = 0;
96646
 
+
96647
 
+       *storage_r = NULL;
96648
 
+
96649
 
+       T_BEGIN { 
96650
 
+               struct stat st;
96651
 
+
96652
 
+               /* Find the personal script to execute */
96653
 
+       
96654
 
+               user_script = lda_sieve_get_personal_path();
96655
 
+               default_script = lda_sieve_get_default_path();
96656
 
+
96657
 
+               if ( stat(user_script, &st) < 0 ) {
96658
 
+                       if (errno != ENOENT)
96659
 
+                               sieve_sys_error("stat(%s) failed: %m "
96660
 
+                                       "(using global script path in stead)", user_script);
96661
 
+                       else if (getenv("DEBUG") != NULL)
96662
 
+                               sieve_sys_info("local script path %s doesn't exist "
96663
 
+                                       "(using global script path in stead)", user_script);
96664
 
+
96665
 
+                       user_script = NULL;
96666
 
+               }
96667
 
+
96668
 
+               if ( lda_sieve_debug ) {
96669
 
+                       const char *script = user_script == NULL ? default_script : user_script;
96670
 
+
96671
 
+                       if ( script == NULL )
96672
 
+                               sieve_sys_info("user has no valid personal script");
96673
 
+                       else
96674
 
+                               sieve_sys_info("using sieve path for user's script: %s", script);
96675
 
+               }
96676
 
+
96677
 
+               /* Check for multiscript */
96678
 
+
96679
 
+               t_array_init(&scripts_before, 16);
96680
 
+               t_array_init(&scripts_after, 16);
96681
 
+
96682
 
+               sieve_before = getenv("SIEVE_BEFORE");
96683
 
+               sieve_after = getenv("SIEVE_AFTER");
96684
 
+
96685
 
+               if ( sieve_before != NULL && *sieve_before != '\0' ) {
96686
 
+                       lda_sieve_multiscript_get_scriptfiles(sieve_before, &scripts_before);
96687
 
+               }
96688
 
+
96689
 
+               if ( sieve_after != NULL && *sieve_after != '\0' ) {
96690
 
+                       lda_sieve_multiscript_get_scriptfiles(sieve_after, &scripts_after);
96691
 
+               }
96692
 
+
96693
 
+               if ( lda_sieve_debug ) {
96694
 
+                       const char *const *scriptfiles;
96695
 
+                       unsigned int count, i;
96696
 
+
96697
 
+                       scriptfiles = array_get(&scripts_before, &count);
96698
 
+                       for ( i = 0; i < count; i ++ ) {
96699
 
+                               sieve_sys_info("executed before user's script(%d): %s", i+1, scriptfiles[i]);                           
96700
 
+                       }
96701
 
+
96702
 
+                       scriptfiles = array_get(&scripts_after, &count);
96703
 
+                       for ( i = 0; i < count; i ++ ) {
96704
 
+                               sieve_sys_info("executed after user's script(%d): %s", i+1, scriptfiles[i]);                            
96705
 
+                       }
96706
 
+               }
96707
 
+
96708
 
+               /* Check whether there are any scripts to execute */
96709
 
+
96710
 
+               if ( array_count(&scripts_before) == 0 && array_count(&scripts_after) == 0 &&
96711
 
+                       user_script == NULL && default_script == NULL ) {
96712
 
+                       if ( lda_sieve_debug )
96713
 
+                               sieve_sys_info("no scripts to execute: reverting to default delivery.");
96714
 
+
96715
 
+                       /* No error, but no delivery by this plugin either. A return value of <= 0 for a 
96716
 
+                        * deliver plugin is is considered a failure. In deliver itself, saved_mail and 
96717
 
+                        * tried_default_save remain unset, meaning that deliver will then attempt the 
96718
 
+                        * default delivery. We return 0 to signify the lack of a real error. 
96719
 
+                        */
96720
 
+                       ret = 0; 
96721
 
+               } else {
96722
 
+                       /* Run the script(s) */
96723
 
+                               
96724
 
+                       ret = lda_sieve_run
96725
 
+                               (namespaces, mail, user_script, default_script,
96726
 
+                                       &scripts_before, &scripts_after, 
96727
 
+                                       destaddr, getenv("USER"), mailbox, storage_r);
96728
 
+               }
96729
 
+
96730
 
+       } T_END;
96731
 
+
96732
 
+       return ret; 
96733
 
+}
96734
 
+
96735
 
+/*
96736
 
+ * Plugin interface
96737
 
+ */
96738
 
+
96739
 
+void sieve_plugin_init(void)
96740
 
+{
96741
 
+       const char *extensions = NULL;
96742
 
+
96743
 
+       /* Initialize Sieve engine */
96744
 
+       sieve_init();
96745
 
+
96746
 
+       extensions = getenv("SIEVE_EXTENSIONS");
96747
 
+       if ( extensions != NULL ) {
96748
 
+               sieve_set_extensions(extensions);
96749
 
+       }
96750
 
+
96751
 
+       /* Debug mode */
96752
 
+       lda_sieve_debug = getenv("DEBUG");
96753
 
+
96754
 
+       /* Hook into the delivery process */
96755
 
+       next_deliver_mail = deliver_mail;
96756
 
+       deliver_mail = lda_sieve_deliver_mail;
96757
 
+}
96758
 
+
96759
 
+void sieve_plugin_deinit(void)
96760
 
+{
96761
 
+       /* Remove hook */
96762
 
+       deliver_mail = next_deliver_mail;
96763
 
+
96764
 
+       /* Deinitialize Sieve engine */
96765
 
+       sieve_deinit();
96766
 
+}
96767
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/plugins/lda-sieve/lda-sieve-plugin.h dovecot-1.2.4.debian/dovecot-libsieve/src/plugins/lda-sieve/lda-sieve-plugin.h
96768
 
--- dovecot-1.2.4/dovecot-libsieve/src/plugins/lda-sieve/lda-sieve-plugin.h     1970-01-01 01:00:00.000000000 +0100
96769
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/plugins/lda-sieve/lda-sieve-plugin.h      2009-01-06 00:15:52.000000000 +0100
96770
 
@@ -0,0 +1,14 @@
96771
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
96772
 
+ */
96773
 
+
96774
 
+#ifndef __LDA_SIEVE_PLUGIN_H
96775
 
+#define __LDA_SIEVE_PLUGIN_H
96776
 
+
96777
 
+/*
96778
 
+ * Plugin interface
96779
 
+ */
96780
 
+
96781
 
+void sieve_plugin_init(void);
96782
 
+void sieve_plugin_deinit(void);
96783
 
+
96784
 
+#endif /* __LDA_SIEVE_PLUGIN_H */
96785
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/plugins/lda-sieve/Makefile.am dovecot-1.2.4.debian/dovecot-libsieve/src/plugins/lda-sieve/Makefile.am
96786
 
--- dovecot-1.2.4/dovecot-libsieve/src/plugins/lda-sieve/Makefile.am    1970-01-01 01:00:00.000000000 +0100
96787
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/plugins/lda-sieve/Makefile.am     2008-07-18 12:11:28.000000000 +0200
96788
 
@@ -0,0 +1,23 @@
96789
 
+AM_CPPFLAGS = \
96790
 
+       -I$(top_srcdir)/src/lib-sieve \
96791
 
+       -I$(dovecot_incdir) \
96792
 
+       -I$(dovecot_incdir)/src/lib \
96793
 
+       -I$(dovecot_incdir)/src/lib-dict \
96794
 
+       -I$(dovecot_incdir)/src/lib-mail \
96795
 
+       -I$(dovecot_incdir)/src/lib-storage \
96796
 
+       -I$(dovecot_incdir)/src/deliver
96797
 
+
96798
 
+lda_moduledir = $(moduledir)/lda
96799
 
+
96800
 
+lib90_sieve_plugin_la_LDFLAGS = -module -avoid-version
96801
 
+
96802
 
+lda_module_LTLIBRARIES = lib90_sieve_plugin.la
96803
 
+
96804
 
+lib90_sieve_plugin_la_LIBADD = \
96805
 
+       $(top_srcdir)/src/lib-sieve/libsieve.la
96806
 
+
96807
 
+lib90_sieve_plugin_la_SOURCES = \
96808
 
+       lda-sieve-plugin.c 
96809
 
+
96810
 
+noinst_HEADERS = \
96811
 
+       lda-sieve-plugin.h
96812
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/plugins/lda-sieve/Makefile.in dovecot-1.2.4.debian/dovecot-libsieve/src/plugins/lda-sieve/Makefile.in
96813
 
--- dovecot-1.2.4/dovecot-libsieve/src/plugins/lda-sieve/Makefile.in    1970-01-01 01:00:00.000000000 +0100
96814
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/plugins/lda-sieve/Makefile.in     2009-08-21 00:55:44.000000000 +0200
96815
 
@@ -0,0 +1,500 @@
96816
 
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
96817
 
+# @configure_input@
96818
 
+
96819
 
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
96820
 
+# 2003, 2004, 2005, 2006, 2007, 2008  Free Software Foundation, Inc.
96821
 
+# This Makefile.in is free software; the Free Software Foundation
96822
 
+# gives unlimited permission to copy and/or distribute it,
96823
 
+# with or without modifications, as long as this notice is preserved.
96824
 
+
96825
 
+# This program is distributed in the hope that it will be useful,
96826
 
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
96827
 
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
96828
 
+# PARTICULAR PURPOSE.
96829
 
+
96830
 
+@SET_MAKE@
96831
 
+
96832
 
+
96833
 
+VPATH = @srcdir@
96834
 
+pkgdatadir = $(datadir)/@PACKAGE@
96835
 
+pkglibdir = $(libdir)/@PACKAGE@
96836
 
+pkgincludedir = $(includedir)/@PACKAGE@
96837
 
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
96838
 
+install_sh_DATA = $(install_sh) -c -m 644
96839
 
+install_sh_PROGRAM = $(install_sh) -c
96840
 
+install_sh_SCRIPT = $(install_sh) -c
96841
 
+INSTALL_HEADER = $(INSTALL_DATA)
96842
 
+transform = $(program_transform_name)
96843
 
+NORMAL_INSTALL = :
96844
 
+PRE_INSTALL = :
96845
 
+POST_INSTALL = :
96846
 
+NORMAL_UNINSTALL = :
96847
 
+PRE_UNINSTALL = :
96848
 
+POST_UNINSTALL = :
96849
 
+build_triplet = @build@
96850
 
+host_triplet = @host@
96851
 
+subdir = src/plugins/lda-sieve
96852
 
+DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
96853
 
+       $(srcdir)/Makefile.in
96854
 
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
96855
 
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
96856
 
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
96857
 
+       $(ACLOCAL_M4)
96858
 
+mkinstalldirs = $(install_sh) -d
96859
 
+CONFIG_HEADER = $(top_builddir)/dummy-config.h \
96860
 
+       $(top_builddir)/dsieve-config.h
96861
 
+CONFIG_CLEAN_FILES =
96862
 
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
96863
 
+am__vpath_adj = case $$p in \
96864
 
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
96865
 
+    *) f=$$p;; \
96866
 
+  esac;
96867
 
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
96868
 
+am__installdirs = "$(DESTDIR)$(lda_moduledir)"
96869
 
+lda_moduleLTLIBRARIES_INSTALL = $(INSTALL)
96870
 
+LTLIBRARIES = $(lda_module_LTLIBRARIES)
96871
 
+lib90_sieve_plugin_la_DEPENDENCIES =  \
96872
 
+       $(top_srcdir)/src/lib-sieve/libsieve.la
96873
 
+am_lib90_sieve_plugin_la_OBJECTS = lda-sieve-plugin.lo
96874
 
+lib90_sieve_plugin_la_OBJECTS = $(am_lib90_sieve_plugin_la_OBJECTS)
96875
 
+lib90_sieve_plugin_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
96876
 
+       $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
96877
 
+       $(lib90_sieve_plugin_la_LDFLAGS) $(LDFLAGS) -o $@
96878
 
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
96879
 
+depcomp = $(SHELL) $(top_srcdir)/depcomp
96880
 
+am__depfiles_maybe = depfiles
96881
 
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
96882
 
+       $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
96883
 
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
96884
 
+       --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
96885
 
+       $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
96886
 
+CCLD = $(CC)
96887
 
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
96888
 
+       --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
96889
 
+       $(LDFLAGS) -o $@
96890
 
+SOURCES = $(lib90_sieve_plugin_la_SOURCES)
96891
 
+DIST_SOURCES = $(lib90_sieve_plugin_la_SOURCES)
96892
 
+HEADERS = $(noinst_HEADERS)
96893
 
+ETAGS = etags
96894
 
+CTAGS = ctags
96895
 
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
96896
 
+ACLOCAL = @ACLOCAL@
96897
 
+AMTAR = @AMTAR@
96898
 
+AR = @AR@
96899
 
+AUTOCONF = @AUTOCONF@
96900
 
+AUTOHEADER = @AUTOHEADER@
96901
 
+AUTOMAKE = @AUTOMAKE@
96902
 
+AWK = @AWK@
96903
 
+CC = @CC@
96904
 
+CCDEPMODE = @CCDEPMODE@
96905
 
+CFLAGS = @CFLAGS@
96906
 
+CPP = @CPP@
96907
 
+CPPFLAGS = @CPPFLAGS@
96908
 
+CYGPATH_W = @CYGPATH_W@
96909
 
+DEFS = @DEFS@
96910
 
+DEPDIR = @DEPDIR@
96911
 
+DSYMUTIL = @DSYMUTIL@
96912
 
+DUMPBIN = @DUMPBIN@
96913
 
+ECHO_C = @ECHO_C@
96914
 
+ECHO_N = @ECHO_N@
96915
 
+ECHO_T = @ECHO_T@
96916
 
+EGREP = @EGREP@
96917
 
+EXEEXT = @EXEEXT@
96918
 
+FGREP = @FGREP@
96919
 
+GREP = @GREP@
96920
 
+INSTALL = @INSTALL@
96921
 
+INSTALL_DATA = @INSTALL_DATA@
96922
 
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
96923
 
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
96924
 
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
96925
 
+LD = @LD@
96926
 
+LDFLAGS = @LDFLAGS@
96927
 
+LIBICONV = @LIBICONV@
96928
 
+LIBOBJS = @LIBOBJS@
96929
 
+LIBS = @LIBS@
96930
 
+LIBTOOL = @LIBTOOL@
96931
 
+LIPO = @LIPO@
96932
 
+LN_S = @LN_S@
96933
 
+LTLIBOBJS = @LTLIBOBJS@
96934
 
+MAINT = @MAINT@
96935
 
+MAKEINFO = @MAKEINFO@
96936
 
+MKDIR_P = @MKDIR_P@
96937
 
+MODULE_LIBS = @MODULE_LIBS@
96938
 
+NM = @NM@
96939
 
+NMEDIT = @NMEDIT@
96940
 
+OBJDUMP = @OBJDUMP@
96941
 
+OBJEXT = @OBJEXT@
96942
 
+OTOOL = @OTOOL@
96943
 
+OTOOL64 = @OTOOL64@
96944
 
+PACKAGE = @PACKAGE@
96945
 
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
96946
 
+PACKAGE_NAME = @PACKAGE_NAME@
96947
 
+PACKAGE_STRING = @PACKAGE_STRING@
96948
 
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
96949
 
+PACKAGE_URL = @PACKAGE_URL@
96950
 
+PACKAGE_VERSION = @PACKAGE_VERSION@
96951
 
+PATH_SEPARATOR = @PATH_SEPARATOR@
96952
 
+RAND_LIBS = @RAND_LIBS@
96953
 
+RANLIB = @RANLIB@
96954
 
+SED = @SED@
96955
 
+SET_MAKE = @SET_MAKE@
96956
 
+SHELL = @SHELL@
96957
 
+STORAGE_LIBS = @STORAGE_LIBS@
96958
 
+STRIP = @STRIP@
96959
 
+VERSION = @VERSION@
96960
 
+abs_builddir = @abs_builddir@
96961
 
+abs_srcdir = @abs_srcdir@
96962
 
+abs_top_builddir = @abs_top_builddir@
96963
 
+abs_top_srcdir = @abs_top_srcdir@
96964
 
+ac_ct_CC = @ac_ct_CC@
96965
 
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
96966
 
+am__include = @am__include@
96967
 
+am__leading_dot = @am__leading_dot@
96968
 
+am__quote = @am__quote@
96969
 
+am__tar = @am__tar@
96970
 
+am__untar = @am__untar@
96971
 
+bindir = @bindir@
96972
 
+build = @build@
96973
 
+build_alias = @build_alias@
96974
 
+build_cpu = @build_cpu@
96975
 
+build_os = @build_os@
96976
 
+build_vendor = @build_vendor@
96977
 
+builddir = @builddir@
96978
 
+datadir = @datadir@
96979
 
+datarootdir = @datarootdir@
96980
 
+docdir = @docdir@
96981
 
+dovecot_incdir = @dovecot_incdir@
96982
 
+dovecotdir = @dovecotdir@
96983
 
+dvidir = @dvidir@
96984
 
+exec_prefix = @exec_prefix@
96985
 
+host = @host@
96986
 
+host_alias = @host_alias@
96987
 
+host_cpu = @host_cpu@
96988
 
+host_os = @host_os@
96989
 
+host_vendor = @host_vendor@
96990
 
+htmldir = @htmldir@
96991
 
+includedir = @includedir@
96992
 
+infodir = @infodir@
96993
 
+install_sh = @install_sh@
96994
 
+libdir = @libdir@
96995
 
+libexecdir = @libexecdir@
96996
 
+localedir = @localedir@
96997
 
+localstatedir = @localstatedir@
96998
 
+lt_ECHO = @lt_ECHO@
96999
 
+mandir = @mandir@
97000
 
+mkdir_p = @mkdir_p@
97001
 
+moduledir = @moduledir@
97002
 
+oldincludedir = @oldincludedir@
97003
 
+pdfdir = @pdfdir@
97004
 
+prefix = @prefix@
97005
 
+program_transform_name = @program_transform_name@
97006
 
+psdir = @psdir@
97007
 
+sbindir = @sbindir@
97008
 
+sharedstatedir = @sharedstatedir@
97009
 
+srcdir = @srcdir@
97010
 
+sysconfdir = @sysconfdir@
97011
 
+target_alias = @target_alias@
97012
 
+top_build_prefix = @top_build_prefix@
97013
 
+top_builddir = @top_builddir@
97014
 
+top_srcdir = @top_srcdir@
97015
 
+AM_CPPFLAGS = \
97016
 
+       -I$(top_srcdir)/src/lib-sieve \
97017
 
+       -I$(dovecot_incdir) \
97018
 
+       -I$(dovecot_incdir)/src/lib \
97019
 
+       -I$(dovecot_incdir)/src/lib-dict \
97020
 
+       -I$(dovecot_incdir)/src/lib-mail \
97021
 
+       -I$(dovecot_incdir)/src/lib-storage \
97022
 
+       -I$(dovecot_incdir)/src/deliver
97023
 
+
97024
 
+lda_moduledir = $(moduledir)/lda
97025
 
+lib90_sieve_plugin_la_LDFLAGS = -module -avoid-version
97026
 
+lda_module_LTLIBRARIES = lib90_sieve_plugin.la
97027
 
+lib90_sieve_plugin_la_LIBADD = \
97028
 
+       $(top_srcdir)/src/lib-sieve/libsieve.la
97029
 
+
97030
 
+lib90_sieve_plugin_la_SOURCES = \
97031
 
+       lda-sieve-plugin.c 
97032
 
+
97033
 
+noinst_HEADERS = \
97034
 
+       lda-sieve-plugin.h
97035
 
+
97036
 
+all: all-am
97037
 
+
97038
 
+.SUFFIXES:
97039
 
+.SUFFIXES: .c .lo .o .obj
97040
 
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
97041
 
+       @for dep in $?; do \
97042
 
+         case '$(am__configure_deps)' in \
97043
 
+           *$$dep*) \
97044
 
+             ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
97045
 
+               && { if test -f $@; then exit 0; else break; fi; }; \
97046
 
+             exit 1;; \
97047
 
+         esac; \
97048
 
+       done; \
97049
 
+       echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign  src/plugins/lda-sieve/Makefile'; \
97050
 
+       cd $(top_srcdir) && \
97051
 
+         $(AUTOMAKE) --foreign  src/plugins/lda-sieve/Makefile
97052
 
+.PRECIOUS: Makefile
97053
 
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
97054
 
+       @case '$?' in \
97055
 
+         *config.status*) \
97056
 
+           cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
97057
 
+         *) \
97058
 
+           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
97059
 
+           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
97060
 
+       esac;
97061
 
+
97062
 
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
97063
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
97064
 
+
97065
 
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
97066
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
97067
 
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
97068
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
97069
 
+install-lda_moduleLTLIBRARIES: $(lda_module_LTLIBRARIES)
97070
 
+       @$(NORMAL_INSTALL)
97071
 
+       test -z "$(lda_moduledir)" || $(MKDIR_P) "$(DESTDIR)$(lda_moduledir)"
97072
 
+       @list='$(lda_module_LTLIBRARIES)'; for p in $$list; do \
97073
 
+         if test -f $$p; then \
97074
 
+           f=$(am__strip_dir) \
97075
 
+           echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(lda_moduleLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(lda_moduledir)/$$f'"; \
97076
 
+           $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(lda_moduleLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(lda_moduledir)/$$f"; \
97077
 
+         else :; fi; \
97078
 
+       done
97079
 
+
97080
 
+uninstall-lda_moduleLTLIBRARIES:
97081
 
+       @$(NORMAL_UNINSTALL)
97082
 
+       @list='$(lda_module_LTLIBRARIES)'; for p in $$list; do \
97083
 
+         p=$(am__strip_dir) \
97084
 
+         echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(lda_moduledir)/$$p'"; \
97085
 
+         $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(lda_moduledir)/$$p"; \
97086
 
+       done
97087
 
+
97088
 
+clean-lda_moduleLTLIBRARIES:
97089
 
+       -test -z "$(lda_module_LTLIBRARIES)" || rm -f $(lda_module_LTLIBRARIES)
97090
 
+       @list='$(lda_module_LTLIBRARIES)'; for p in $$list; do \
97091
 
+         dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
97092
 
+         test "$$dir" != "$$p" || dir=.; \
97093
 
+         echo "rm -f \"$${dir}/so_locations\""; \
97094
 
+         rm -f "$${dir}/so_locations"; \
97095
 
+       done
97096
 
+lib90_sieve_plugin.la: $(lib90_sieve_plugin_la_OBJECTS) $(lib90_sieve_plugin_la_DEPENDENCIES) 
97097
 
+       $(lib90_sieve_plugin_la_LINK) -rpath $(lda_moduledir) $(lib90_sieve_plugin_la_OBJECTS) $(lib90_sieve_plugin_la_LIBADD) $(LIBS)
97098
 
+
97099
 
+mostlyclean-compile:
97100
 
+       -rm -f *.$(OBJEXT)
97101
 
+
97102
 
+distclean-compile:
97103
 
+       -rm -f *.tab.c
97104
 
+
97105
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lda-sieve-plugin.Plo@am__quote@
97106
 
+
97107
 
+.c.o:
97108
 
+@am__fastdepCC_TRUE@   $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
97109
 
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
97110
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
97111
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
97112
 
+@am__fastdepCC_FALSE@  $(COMPILE) -c $<
97113
 
+
97114
 
+.c.obj:
97115
 
+@am__fastdepCC_TRUE@   $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
97116
 
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
97117
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
97118
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
97119
 
+@am__fastdepCC_FALSE@  $(COMPILE) -c `$(CYGPATH_W) '$<'`
97120
 
+
97121
 
+.c.lo:
97122
 
+@am__fastdepCC_TRUE@   $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
97123
 
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
97124
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
97125
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
97126
 
+@am__fastdepCC_FALSE@  $(LTCOMPILE) -c -o $@ $<
97127
 
+
97128
 
+mostlyclean-libtool:
97129
 
+       -rm -f *.lo
97130
 
+
97131
 
+clean-libtool:
97132
 
+       -rm -rf .libs _libs
97133
 
+
97134
 
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
97135
 
+       list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
97136
 
+       unique=`for i in $$list; do \
97137
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
97138
 
+         done | \
97139
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
97140
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
97141
 
+       mkid -fID $$unique
97142
 
+tags: TAGS
97143
 
+
97144
 
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
97145
 
+               $(TAGS_FILES) $(LISP)
97146
 
+       tags=; \
97147
 
+       here=`pwd`; \
97148
 
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
97149
 
+       unique=`for i in $$list; do \
97150
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
97151
 
+         done | \
97152
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
97153
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
97154
 
+       if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
97155
 
+         test -n "$$unique" || unique=$$empty_fix; \
97156
 
+         $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
97157
 
+           $$tags $$unique; \
97158
 
+       fi
97159
 
+ctags: CTAGS
97160
 
+CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
97161
 
+               $(TAGS_FILES) $(LISP)
97162
 
+       tags=; \
97163
 
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
97164
 
+       unique=`for i in $$list; do \
97165
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
97166
 
+         done | \
97167
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
97168
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
97169
 
+       test -z "$(CTAGS_ARGS)$$tags$$unique" \
97170
 
+         || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
97171
 
+            $$tags $$unique
97172
 
+
97173
 
+GTAGS:
97174
 
+       here=`$(am__cd) $(top_builddir) && pwd` \
97175
 
+         && cd $(top_srcdir) \
97176
 
+         && gtags -i $(GTAGS_ARGS) $$here
97177
 
+
97178
 
+distclean-tags:
97179
 
+       -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
97180
 
+
97181
 
+distdir: $(DISTFILES)
97182
 
+       @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
97183
 
+       topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
97184
 
+       list='$(DISTFILES)'; \
97185
 
+         dist_files=`for file in $$list; do echo $$file; done | \
97186
 
+         sed -e "s|^$$srcdirstrip/||;t" \
97187
 
+             -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
97188
 
+       case $$dist_files in \
97189
 
+         */*) $(MKDIR_P) `echo "$$dist_files" | \
97190
 
+                          sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
97191
 
+                          sort -u` ;; \
97192
 
+       esac; \
97193
 
+       for file in $$dist_files; do \
97194
 
+         if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
97195
 
+         if test -d $$d/$$file; then \
97196
 
+           dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
97197
 
+           if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
97198
 
+             cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
97199
 
+           fi; \
97200
 
+           cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
97201
 
+         else \
97202
 
+           test -f $(distdir)/$$file \
97203
 
+           || cp -p $$d/$$file $(distdir)/$$file \
97204
 
+           || exit 1; \
97205
 
+         fi; \
97206
 
+       done
97207
 
+check-am: all-am
97208
 
+check: check-am
97209
 
+all-am: Makefile $(LTLIBRARIES) $(HEADERS)
97210
 
+installdirs:
97211
 
+       for dir in "$(DESTDIR)$(lda_moduledir)"; do \
97212
 
+         test -z "$$dir" || $(MKDIR_P) "$$dir"; \
97213
 
+       done
97214
 
+install: install-am
97215
 
+install-exec: install-exec-am
97216
 
+install-data: install-data-am
97217
 
+uninstall: uninstall-am
97218
 
+
97219
 
+install-am: all-am
97220
 
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
97221
 
+
97222
 
+installcheck: installcheck-am
97223
 
+install-strip:
97224
 
+       $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
97225
 
+         install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
97226
 
+         `test -z '$(STRIP)' || \
97227
 
+           echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
97228
 
+mostlyclean-generic:
97229
 
+
97230
 
+clean-generic:
97231
 
+
97232
 
+distclean-generic:
97233
 
+       -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
97234
 
+
97235
 
+maintainer-clean-generic:
97236
 
+       @echo "This command is intended for maintainers to use"
97237
 
+       @echo "it deletes files that may require special tools to rebuild."
97238
 
+clean: clean-am
97239
 
+
97240
 
+clean-am: clean-generic clean-lda_moduleLTLIBRARIES clean-libtool \
97241
 
+       mostlyclean-am
97242
 
+
97243
 
+distclean: distclean-am
97244
 
+       -rm -rf ./$(DEPDIR)
97245
 
+       -rm -f Makefile
97246
 
+distclean-am: clean-am distclean-compile distclean-generic \
97247
 
+       distclean-tags
97248
 
+
97249
 
+dvi: dvi-am
97250
 
+
97251
 
+dvi-am:
97252
 
+
97253
 
+html: html-am
97254
 
+
97255
 
+info: info-am
97256
 
+
97257
 
+info-am:
97258
 
+
97259
 
+install-data-am: install-lda_moduleLTLIBRARIES
97260
 
+
97261
 
+install-dvi: install-dvi-am
97262
 
+
97263
 
+install-exec-am:
97264
 
+
97265
 
+install-html: install-html-am
97266
 
+
97267
 
+install-info: install-info-am
97268
 
+
97269
 
+install-man:
97270
 
+
97271
 
+install-pdf: install-pdf-am
97272
 
+
97273
 
+install-ps: install-ps-am
97274
 
+
97275
 
+installcheck-am:
97276
 
+
97277
 
+maintainer-clean: maintainer-clean-am
97278
 
+       -rm -rf ./$(DEPDIR)
97279
 
+       -rm -f Makefile
97280
 
+maintainer-clean-am: distclean-am maintainer-clean-generic
97281
 
+
97282
 
+mostlyclean: mostlyclean-am
97283
 
+
97284
 
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
97285
 
+       mostlyclean-libtool
97286
 
+
97287
 
+pdf: pdf-am
97288
 
+
97289
 
+pdf-am:
97290
 
+
97291
 
+ps: ps-am
97292
 
+
97293
 
+ps-am:
97294
 
+
97295
 
+uninstall-am: uninstall-lda_moduleLTLIBRARIES
97296
 
+
97297
 
+.MAKE: install-am install-strip
97298
 
+
97299
 
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
97300
 
+       clean-lda_moduleLTLIBRARIES clean-libtool ctags distclean \
97301
 
+       distclean-compile distclean-generic distclean-libtool \
97302
 
+       distclean-tags distdir dvi dvi-am html html-am info info-am \
97303
 
+       install install-am install-data install-data-am install-dvi \
97304
 
+       install-dvi-am install-exec install-exec-am install-html \
97305
 
+       install-html-am install-info install-info-am \
97306
 
+       install-lda_moduleLTLIBRARIES install-man install-pdf \
97307
 
+       install-pdf-am install-ps install-ps-am install-strip \
97308
 
+       installcheck installcheck-am installdirs maintainer-clean \
97309
 
+       maintainer-clean-generic mostlyclean mostlyclean-compile \
97310
 
+       mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
97311
 
+       tags uninstall uninstall-am uninstall-lda_moduleLTLIBRARIES
97312
 
+
97313
 
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
97314
 
+# Otherwise a system limit (for SysV at least) may be exceeded.
97315
 
+.NOEXPORT:
97316
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/plugins/Makefile.am dovecot-1.2.4.debian/dovecot-libsieve/src/plugins/Makefile.am
97317
 
--- dovecot-1.2.4/dovecot-libsieve/src/plugins/Makefile.am      1970-01-01 01:00:00.000000000 +0100
97318
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/plugins/Makefile.am       2008-07-18 12:11:28.000000000 +0200
97319
 
@@ -0,0 +1 @@
97320
 
+SUBDIRS = lda-sieve
97321
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/plugins/Makefile.in dovecot-1.2.4.debian/dovecot-libsieve/src/plugins/Makefile.in
97322
 
--- dovecot-1.2.4/dovecot-libsieve/src/plugins/Makefile.in      1970-01-01 01:00:00.000000000 +0100
97323
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/plugins/Makefile.in       2009-08-21 00:55:44.000000000 +0200
97324
 
@@ -0,0 +1,493 @@
97325
 
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
97326
 
+# @configure_input@
97327
 
+
97328
 
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
97329
 
+# 2003, 2004, 2005, 2006, 2007, 2008  Free Software Foundation, Inc.
97330
 
+# This Makefile.in is free software; the Free Software Foundation
97331
 
+# gives unlimited permission to copy and/or distribute it,
97332
 
+# with or without modifications, as long as this notice is preserved.
97333
 
+
97334
 
+# This program is distributed in the hope that it will be useful,
97335
 
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
97336
 
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
97337
 
+# PARTICULAR PURPOSE.
97338
 
+
97339
 
+@SET_MAKE@
97340
 
+VPATH = @srcdir@
97341
 
+pkgdatadir = $(datadir)/@PACKAGE@
97342
 
+pkglibdir = $(libdir)/@PACKAGE@
97343
 
+pkgincludedir = $(includedir)/@PACKAGE@
97344
 
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
97345
 
+install_sh_DATA = $(install_sh) -c -m 644
97346
 
+install_sh_PROGRAM = $(install_sh) -c
97347
 
+install_sh_SCRIPT = $(install_sh) -c
97348
 
+INSTALL_HEADER = $(INSTALL_DATA)
97349
 
+transform = $(program_transform_name)
97350
 
+NORMAL_INSTALL = :
97351
 
+PRE_INSTALL = :
97352
 
+POST_INSTALL = :
97353
 
+NORMAL_UNINSTALL = :
97354
 
+PRE_UNINSTALL = :
97355
 
+POST_UNINSTALL = :
97356
 
+build_triplet = @build@
97357
 
+host_triplet = @host@
97358
 
+subdir = src/plugins
97359
 
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
97360
 
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
97361
 
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
97362
 
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
97363
 
+       $(ACLOCAL_M4)
97364
 
+mkinstalldirs = $(install_sh) -d
97365
 
+CONFIG_HEADER = $(top_builddir)/dummy-config.h \
97366
 
+       $(top_builddir)/dsieve-config.h
97367
 
+CONFIG_CLEAN_FILES =
97368
 
+SOURCES =
97369
 
+DIST_SOURCES =
97370
 
+RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
97371
 
+       html-recursive info-recursive install-data-recursive \
97372
 
+       install-dvi-recursive install-exec-recursive \
97373
 
+       install-html-recursive install-info-recursive \
97374
 
+       install-pdf-recursive install-ps-recursive install-recursive \
97375
 
+       installcheck-recursive installdirs-recursive pdf-recursive \
97376
 
+       ps-recursive uninstall-recursive
97377
 
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive        \
97378
 
+  distclean-recursive maintainer-clean-recursive
97379
 
+ETAGS = etags
97380
 
+CTAGS = ctags
97381
 
+DIST_SUBDIRS = $(SUBDIRS)
97382
 
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
97383
 
+ACLOCAL = @ACLOCAL@
97384
 
+AMTAR = @AMTAR@
97385
 
+AR = @AR@
97386
 
+AUTOCONF = @AUTOCONF@
97387
 
+AUTOHEADER = @AUTOHEADER@
97388
 
+AUTOMAKE = @AUTOMAKE@
97389
 
+AWK = @AWK@
97390
 
+CC = @CC@
97391
 
+CCDEPMODE = @CCDEPMODE@
97392
 
+CFLAGS = @CFLAGS@
97393
 
+CPP = @CPP@
97394
 
+CPPFLAGS = @CPPFLAGS@
97395
 
+CYGPATH_W = @CYGPATH_W@
97396
 
+DEFS = @DEFS@
97397
 
+DEPDIR = @DEPDIR@
97398
 
+DSYMUTIL = @DSYMUTIL@
97399
 
+DUMPBIN = @DUMPBIN@
97400
 
+ECHO_C = @ECHO_C@
97401
 
+ECHO_N = @ECHO_N@
97402
 
+ECHO_T = @ECHO_T@
97403
 
+EGREP = @EGREP@
97404
 
+EXEEXT = @EXEEXT@
97405
 
+FGREP = @FGREP@
97406
 
+GREP = @GREP@
97407
 
+INSTALL = @INSTALL@
97408
 
+INSTALL_DATA = @INSTALL_DATA@
97409
 
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
97410
 
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
97411
 
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
97412
 
+LD = @LD@
97413
 
+LDFLAGS = @LDFLAGS@
97414
 
+LIBICONV = @LIBICONV@
97415
 
+LIBOBJS = @LIBOBJS@
97416
 
+LIBS = @LIBS@
97417
 
+LIBTOOL = @LIBTOOL@
97418
 
+LIPO = @LIPO@
97419
 
+LN_S = @LN_S@
97420
 
+LTLIBOBJS = @LTLIBOBJS@
97421
 
+MAINT = @MAINT@
97422
 
+MAKEINFO = @MAKEINFO@
97423
 
+MKDIR_P = @MKDIR_P@
97424
 
+MODULE_LIBS = @MODULE_LIBS@
97425
 
+NM = @NM@
97426
 
+NMEDIT = @NMEDIT@
97427
 
+OBJDUMP = @OBJDUMP@
97428
 
+OBJEXT = @OBJEXT@
97429
 
+OTOOL = @OTOOL@
97430
 
+OTOOL64 = @OTOOL64@
97431
 
+PACKAGE = @PACKAGE@
97432
 
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
97433
 
+PACKAGE_NAME = @PACKAGE_NAME@
97434
 
+PACKAGE_STRING = @PACKAGE_STRING@
97435
 
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
97436
 
+PACKAGE_URL = @PACKAGE_URL@
97437
 
+PACKAGE_VERSION = @PACKAGE_VERSION@
97438
 
+PATH_SEPARATOR = @PATH_SEPARATOR@
97439
 
+RAND_LIBS = @RAND_LIBS@
97440
 
+RANLIB = @RANLIB@
97441
 
+SED = @SED@
97442
 
+SET_MAKE = @SET_MAKE@
97443
 
+SHELL = @SHELL@
97444
 
+STORAGE_LIBS = @STORAGE_LIBS@
97445
 
+STRIP = @STRIP@
97446
 
+VERSION = @VERSION@
97447
 
+abs_builddir = @abs_builddir@
97448
 
+abs_srcdir = @abs_srcdir@
97449
 
+abs_top_builddir = @abs_top_builddir@
97450
 
+abs_top_srcdir = @abs_top_srcdir@
97451
 
+ac_ct_CC = @ac_ct_CC@
97452
 
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
97453
 
+am__include = @am__include@
97454
 
+am__leading_dot = @am__leading_dot@
97455
 
+am__quote = @am__quote@
97456
 
+am__tar = @am__tar@
97457
 
+am__untar = @am__untar@
97458
 
+bindir = @bindir@
97459
 
+build = @build@
97460
 
+build_alias = @build_alias@
97461
 
+build_cpu = @build_cpu@
97462
 
+build_os = @build_os@
97463
 
+build_vendor = @build_vendor@
97464
 
+builddir = @builddir@
97465
 
+datadir = @datadir@
97466
 
+datarootdir = @datarootdir@
97467
 
+docdir = @docdir@
97468
 
+dovecot_incdir = @dovecot_incdir@
97469
 
+dovecotdir = @dovecotdir@
97470
 
+dvidir = @dvidir@
97471
 
+exec_prefix = @exec_prefix@
97472
 
+host = @host@
97473
 
+host_alias = @host_alias@
97474
 
+host_cpu = @host_cpu@
97475
 
+host_os = @host_os@
97476
 
+host_vendor = @host_vendor@
97477
 
+htmldir = @htmldir@
97478
 
+includedir = @includedir@
97479
 
+infodir = @infodir@
97480
 
+install_sh = @install_sh@
97481
 
+libdir = @libdir@
97482
 
+libexecdir = @libexecdir@
97483
 
+localedir = @localedir@
97484
 
+localstatedir = @localstatedir@
97485
 
+lt_ECHO = @lt_ECHO@
97486
 
+mandir = @mandir@
97487
 
+mkdir_p = @mkdir_p@
97488
 
+moduledir = @moduledir@
97489
 
+oldincludedir = @oldincludedir@
97490
 
+pdfdir = @pdfdir@
97491
 
+prefix = @prefix@
97492
 
+program_transform_name = @program_transform_name@
97493
 
+psdir = @psdir@
97494
 
+sbindir = @sbindir@
97495
 
+sharedstatedir = @sharedstatedir@
97496
 
+srcdir = @srcdir@
97497
 
+sysconfdir = @sysconfdir@
97498
 
+target_alias = @target_alias@
97499
 
+top_build_prefix = @top_build_prefix@
97500
 
+top_builddir = @top_builddir@
97501
 
+top_srcdir = @top_srcdir@
97502
 
+SUBDIRS = lda-sieve
97503
 
+all: all-recursive
97504
 
+
97505
 
+.SUFFIXES:
97506
 
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
97507
 
+       @for dep in $?; do \
97508
 
+         case '$(am__configure_deps)' in \
97509
 
+           *$$dep*) \
97510
 
+             ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
97511
 
+               && { if test -f $@; then exit 0; else break; fi; }; \
97512
 
+             exit 1;; \
97513
 
+         esac; \
97514
 
+       done; \
97515
 
+       echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign  src/plugins/Makefile'; \
97516
 
+       cd $(top_srcdir) && \
97517
 
+         $(AUTOMAKE) --foreign  src/plugins/Makefile
97518
 
+.PRECIOUS: Makefile
97519
 
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
97520
 
+       @case '$?' in \
97521
 
+         *config.status*) \
97522
 
+           cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
97523
 
+         *) \
97524
 
+           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
97525
 
+           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
97526
 
+       esac;
97527
 
+
97528
 
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
97529
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
97530
 
+
97531
 
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
97532
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
97533
 
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
97534
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
97535
 
+
97536
 
+mostlyclean-libtool:
97537
 
+       -rm -f *.lo
97538
 
+
97539
 
+clean-libtool:
97540
 
+       -rm -rf .libs _libs
97541
 
+
97542
 
+# This directory's subdirectories are mostly independent; you can cd
97543
 
+# into them and run `make' without going through this Makefile.
97544
 
+# To change the values of `make' variables: instead of editing Makefiles,
97545
 
+# (1) if the variable is set in `config.status', edit `config.status'
97546
 
+#     (which will cause the Makefiles to be regenerated when you run `make');
97547
 
+# (2) otherwise, pass the desired values on the `make' command line.
97548
 
+$(RECURSIVE_TARGETS):
97549
 
+       @failcom='exit 1'; \
97550
 
+       for f in x $$MAKEFLAGS; do \
97551
 
+         case $$f in \
97552
 
+           *=* | --[!k]*);; \
97553
 
+           *k*) failcom='fail=yes';; \
97554
 
+         esac; \
97555
 
+       done; \
97556
 
+       dot_seen=no; \
97557
 
+       target=`echo $@ | sed s/-recursive//`; \
97558
 
+       list='$(SUBDIRS)'; for subdir in $$list; do \
97559
 
+         echo "Making $$target in $$subdir"; \
97560
 
+         if test "$$subdir" = "."; then \
97561
 
+           dot_seen=yes; \
97562
 
+           local_target="$$target-am"; \
97563
 
+         else \
97564
 
+           local_target="$$target"; \
97565
 
+         fi; \
97566
 
+         (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
97567
 
+         || eval $$failcom; \
97568
 
+       done; \
97569
 
+       if test "$$dot_seen" = "no"; then \
97570
 
+         $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
97571
 
+       fi; test -z "$$fail"
97572
 
+
97573
 
+$(RECURSIVE_CLEAN_TARGETS):
97574
 
+       @failcom='exit 1'; \
97575
 
+       for f in x $$MAKEFLAGS; do \
97576
 
+         case $$f in \
97577
 
+           *=* | --[!k]*);; \
97578
 
+           *k*) failcom='fail=yes';; \
97579
 
+         esac; \
97580
 
+       done; \
97581
 
+       dot_seen=no; \
97582
 
+       case "$@" in \
97583
 
+         distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
97584
 
+         *) list='$(SUBDIRS)' ;; \
97585
 
+       esac; \
97586
 
+       rev=''; for subdir in $$list; do \
97587
 
+         if test "$$subdir" = "."; then :; else \
97588
 
+           rev="$$subdir $$rev"; \
97589
 
+         fi; \
97590
 
+       done; \
97591
 
+       rev="$$rev ."; \
97592
 
+       target=`echo $@ | sed s/-recursive//`; \
97593
 
+       for subdir in $$rev; do \
97594
 
+         echo "Making $$target in $$subdir"; \
97595
 
+         if test "$$subdir" = "."; then \
97596
 
+           local_target="$$target-am"; \
97597
 
+         else \
97598
 
+           local_target="$$target"; \
97599
 
+         fi; \
97600
 
+         (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
97601
 
+         || eval $$failcom; \
97602
 
+       done && test -z "$$fail"
97603
 
+tags-recursive:
97604
 
+       list='$(SUBDIRS)'; for subdir in $$list; do \
97605
 
+         test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
97606
 
+       done
97607
 
+ctags-recursive:
97608
 
+       list='$(SUBDIRS)'; for subdir in $$list; do \
97609
 
+         test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
97610
 
+       done
97611
 
+
97612
 
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
97613
 
+       list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
97614
 
+       unique=`for i in $$list; do \
97615
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
97616
 
+         done | \
97617
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
97618
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
97619
 
+       mkid -fID $$unique
97620
 
+tags: TAGS
97621
 
+
97622
 
+TAGS: tags-recursive $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
97623
 
+               $(TAGS_FILES) $(LISP)
97624
 
+       tags=; \
97625
 
+       here=`pwd`; \
97626
 
+       if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
97627
 
+         include_option=--etags-include; \
97628
 
+         empty_fix=.; \
97629
 
+       else \
97630
 
+         include_option=--include; \
97631
 
+         empty_fix=; \
97632
 
+       fi; \
97633
 
+       list='$(SUBDIRS)'; for subdir in $$list; do \
97634
 
+         if test "$$subdir" = .; then :; else \
97635
 
+           test ! -f $$subdir/TAGS || \
97636
 
+             tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \
97637
 
+         fi; \
97638
 
+       done; \
97639
 
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
97640
 
+       unique=`for i in $$list; do \
97641
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
97642
 
+         done | \
97643
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
97644
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
97645
 
+       if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
97646
 
+         test -n "$$unique" || unique=$$empty_fix; \
97647
 
+         $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
97648
 
+           $$tags $$unique; \
97649
 
+       fi
97650
 
+ctags: CTAGS
97651
 
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
97652
 
+               $(TAGS_FILES) $(LISP)
97653
 
+       tags=; \
97654
 
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
97655
 
+       unique=`for i in $$list; do \
97656
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
97657
 
+         done | \
97658
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
97659
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
97660
 
+       test -z "$(CTAGS_ARGS)$$tags$$unique" \
97661
 
+         || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
97662
 
+            $$tags $$unique
97663
 
+
97664
 
+GTAGS:
97665
 
+       here=`$(am__cd) $(top_builddir) && pwd` \
97666
 
+         && cd $(top_srcdir) \
97667
 
+         && gtags -i $(GTAGS_ARGS) $$here
97668
 
+
97669
 
+distclean-tags:
97670
 
+       -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
97671
 
+
97672
 
+distdir: $(DISTFILES)
97673
 
+       @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
97674
 
+       topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
97675
 
+       list='$(DISTFILES)'; \
97676
 
+         dist_files=`for file in $$list; do echo $$file; done | \
97677
 
+         sed -e "s|^$$srcdirstrip/||;t" \
97678
 
+             -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
97679
 
+       case $$dist_files in \
97680
 
+         */*) $(MKDIR_P) `echo "$$dist_files" | \
97681
 
+                          sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
97682
 
+                          sort -u` ;; \
97683
 
+       esac; \
97684
 
+       for file in $$dist_files; do \
97685
 
+         if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
97686
 
+         if test -d $$d/$$file; then \
97687
 
+           dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
97688
 
+           if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
97689
 
+             cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
97690
 
+           fi; \
97691
 
+           cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
97692
 
+         else \
97693
 
+           test -f $(distdir)/$$file \
97694
 
+           || cp -p $$d/$$file $(distdir)/$$file \
97695
 
+           || exit 1; \
97696
 
+         fi; \
97697
 
+       done
97698
 
+       list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
97699
 
+         if test "$$subdir" = .; then :; else \
97700
 
+           test -d "$(distdir)/$$subdir" \
97701
 
+           || $(MKDIR_P) "$(distdir)/$$subdir" \
97702
 
+           || exit 1; \
97703
 
+           distdir=`$(am__cd) $(distdir) && pwd`; \
97704
 
+           top_distdir=`$(am__cd) $(top_distdir) && pwd`; \
97705
 
+           (cd $$subdir && \
97706
 
+             $(MAKE) $(AM_MAKEFLAGS) \
97707
 
+               top_distdir="$$top_distdir" \
97708
 
+               distdir="$$distdir/$$subdir" \
97709
 
+               am__remove_distdir=: \
97710
 
+               am__skip_length_check=: \
97711
 
+               distdir) \
97712
 
+             || exit 1; \
97713
 
+         fi; \
97714
 
+       done
97715
 
+check-am: all-am
97716
 
+check: check-recursive
97717
 
+all-am: Makefile
97718
 
+installdirs: installdirs-recursive
97719
 
+installdirs-am:
97720
 
+install: install-recursive
97721
 
+install-exec: install-exec-recursive
97722
 
+install-data: install-data-recursive
97723
 
+uninstall: uninstall-recursive
97724
 
+
97725
 
+install-am: all-am
97726
 
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
97727
 
+
97728
 
+installcheck: installcheck-recursive
97729
 
+install-strip:
97730
 
+       $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
97731
 
+         install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
97732
 
+         `test -z '$(STRIP)' || \
97733
 
+           echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
97734
 
+mostlyclean-generic:
97735
 
+
97736
 
+clean-generic:
97737
 
+
97738
 
+distclean-generic:
97739
 
+       -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
97740
 
+
97741
 
+maintainer-clean-generic:
97742
 
+       @echo "This command is intended for maintainers to use"
97743
 
+       @echo "it deletes files that may require special tools to rebuild."
97744
 
+clean: clean-recursive
97745
 
+
97746
 
+clean-am: clean-generic clean-libtool mostlyclean-am
97747
 
+
97748
 
+distclean: distclean-recursive
97749
 
+       -rm -f Makefile
97750
 
+distclean-am: clean-am distclean-generic distclean-tags
97751
 
+
97752
 
+dvi: dvi-recursive
97753
 
+
97754
 
+dvi-am:
97755
 
+
97756
 
+html: html-recursive
97757
 
+
97758
 
+info: info-recursive
97759
 
+
97760
 
+info-am:
97761
 
+
97762
 
+install-data-am:
97763
 
+
97764
 
+install-dvi: install-dvi-recursive
97765
 
+
97766
 
+install-exec-am:
97767
 
+
97768
 
+install-html: install-html-recursive
97769
 
+
97770
 
+install-info: install-info-recursive
97771
 
+
97772
 
+install-man:
97773
 
+
97774
 
+install-pdf: install-pdf-recursive
97775
 
+
97776
 
+install-ps: install-ps-recursive
97777
 
+
97778
 
+installcheck-am:
97779
 
+
97780
 
+maintainer-clean: maintainer-clean-recursive
97781
 
+       -rm -f Makefile
97782
 
+maintainer-clean-am: distclean-am maintainer-clean-generic
97783
 
+
97784
 
+mostlyclean: mostlyclean-recursive
97785
 
+
97786
 
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
97787
 
+
97788
 
+pdf: pdf-recursive
97789
 
+
97790
 
+pdf-am:
97791
 
+
97792
 
+ps: ps-recursive
97793
 
+
97794
 
+ps-am:
97795
 
+
97796
 
+uninstall-am:
97797
 
+
97798
 
+.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) install-am \
97799
 
+       install-strip
97800
 
+
97801
 
+.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
97802
 
+       all all-am check check-am clean clean-generic clean-libtool \
97803
 
+       ctags ctags-recursive distclean distclean-generic \
97804
 
+       distclean-libtool distclean-tags distdir dvi dvi-am html \
97805
 
+       html-am info info-am install install-am install-data \
97806
 
+       install-data-am install-dvi install-dvi-am install-exec \
97807
 
+       install-exec-am install-html install-html-am install-info \
97808
 
+       install-info-am install-man install-pdf install-pdf-am \
97809
 
+       install-ps install-ps-am install-strip installcheck \
97810
 
+       installcheck-am installdirs installdirs-am maintainer-clean \
97811
 
+       maintainer-clean-generic mostlyclean mostlyclean-generic \
97812
 
+       mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \
97813
 
+       uninstall uninstall-am
97814
 
+
97815
 
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
97816
 
+# Otherwise a system limit (for SysV at least) may be exceeded.
97817
 
+.NOEXPORT:
97818
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/sieve-tools/debug/cmd-debug-print.c dovecot-1.2.4.debian/dovecot-libsieve/src/sieve-tools/debug/cmd-debug-print.c
97819
 
--- dovecot-1.2.4/dovecot-libsieve/src/sieve-tools/debug/cmd-debug-print.c      1970-01-01 01:00:00.000000000 +0100
97820
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/sieve-tools/debug/cmd-debug-print.c       2009-03-26 17:53:38.000000000 +0100
97821
 
@@ -0,0 +1,133 @@
97822
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
97823
 
+ */
97824
 
97825
 
+#include "sieve-extensions.h"
97826
 
+#include "sieve-commands.h"
97827
 
+#include "sieve-code.h"
97828
 
+
97829
 
+#include "sieve-validator.h"
97830
 
+#include "sieve-generator.h"
97831
 
+#include "sieve-binary.h"
97832
 
+#include "sieve-interpreter.h"
97833
 
+#include "sieve-dump.h"
97834
 
+
97835
 
+#include "ext-debug-common.h"
97836
 
+
97837
 
+/* 
97838
 
+ * Debug_print command
97839
 
+ *
97840
 
+ * Syntax
97841
 
+ *   debug_print <message: string>
97842
 
+ */
97843
 
+
97844
 
+static bool cmd_debug_print_validate
97845
 
+       (struct sieve_validator *validator, struct sieve_command_context *tst);
97846
 
+static bool cmd_debug_print_generate
97847
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx);
97848
 
+
97849
 
+const struct sieve_command debug_print_command = { 
97850
 
+       "debug_print", 
97851
 
+       SCT_COMMAND, 
97852
 
+       1, 0, FALSE, FALSE,
97853
 
+       NULL, NULL,
97854
 
+       cmd_debug_print_validate, 
97855
 
+       cmd_debug_print_generate, 
97856
 
+       NULL 
97857
 
+};
97858
 
+
97859
 
+/* 
97860
 
+ * Body operation 
97861
 
+ */
97862
 
+
97863
 
+static bool cmd_debug_print_operation_dump
97864
 
+       (const struct sieve_operation *op, 
97865
 
+               const struct sieve_dumptime_env *denv, sieve_size_t *address);
97866
 
+static int cmd_debug_print_operation_execute
97867
 
+       (const struct sieve_operation *op,
97868
 
+               const struct sieve_runtime_env *renv, sieve_size_t *address);
97869
 
+
97870
 
+const struct sieve_operation debug_print_operation = { 
97871
 
+       "debug_print",
97872
 
+       &debug_extension,
97873
 
+       0,
97874
 
+       cmd_debug_print_operation_dump, 
97875
 
+       cmd_debug_print_operation_execute 
97876
 
+};
97877
 
+
97878
 
+/* 
97879
 
+ * Validation 
97880
 
+ */
97881
 
97882
 
+static bool cmd_debug_print_validate
97883
 
+(struct sieve_validator *validator, struct sieve_command_context *tst) 
97884
 
+{              
97885
 
+       struct sieve_ast_argument *arg = tst->first_positional;
97886
 
+                                       
97887
 
+       if ( !sieve_validate_positional_argument
97888
 
+               (validator, tst, arg, "message", 1, SAAT_STRING) ) {
97889
 
+               return FALSE;
97890
 
+       }
97891
 
+
97892
 
+       return sieve_validator_argument_activate(validator, tst, arg, FALSE);
97893
 
+}
97894
 
+
97895
 
+/*
97896
 
+ * Code generation
97897
 
+ */
97898
 
97899
 
+static bool cmd_debug_print_generate
97900
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx) 
97901
 
+{
97902
 
+       (void)sieve_operation_emit_code(cgenv->sbin, &debug_print_operation);
97903
 
+
97904
 
+       /* Generate arguments */
97905
 
+       return sieve_generate_arguments(cgenv, ctx, NULL);
97906
 
+}
97907
 
+
97908
 
+/* 
97909
 
+ * Code dump 
97910
 
+ */
97911
 
97912
 
+static bool cmd_debug_print_operation_dump
97913
 
+(const struct sieve_operation *op ATTR_UNUSED, 
97914
 
+       const struct sieve_dumptime_env *denv, sieve_size_t *address)
97915
 
+{
97916
 
+       sieve_code_dumpf(denv, "DEBUG_PRINT");
97917
 
+       sieve_code_descend(denv);
97918
 
+
97919
 
+       return sieve_opr_string_dump(denv, address, "key list");
97920
 
+}
97921
 
+
97922
 
+/*
97923
 
+ * Interpretation
97924
 
+ */
97925
 
+
97926
 
+static int cmd_debug_print_operation_execute
97927
 
+(const struct sieve_operation *op ATTR_UNUSED,
97928
 
+       const struct sieve_runtime_env *renv, sieve_size_t *address)
97929
 
+{
97930
 
+       string_t *message;
97931
 
+       int ret = SIEVE_EXEC_OK;
97932
 
+
97933
 
+       /*
97934
 
+        * Read operands
97935
 
+        */
97936
 
+       
97937
 
+       /* Read message */
97938
 
+
97939
 
+       if ( sieve_opr_string_read(renv, address, &message) < 0 ) {
97940
 
+               sieve_runtime_trace_error(renv, "invalid message operand");
97941
 
+               return SIEVE_EXEC_BIN_CORRUPT;
97942
 
+       }
97943
 
+       
97944
 
+       /*
97945
 
+        * Perform operation
97946
 
+        */
97947
 
+
97948
 
+       sieve_runtime_trace(renv, "DEBUG_PRINT");
97949
 
+       
97950
 
+       /* FIXME: give this proper source location */
97951
 
+       sieve_runtime_log(renv, "DEBUG", "%s", str_c(message));
97952
 
+
97953
 
+       return ret;
97954
 
+}
97955
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/sieve-tools/debug/ext-debug.c dovecot-1.2.4.debian/dovecot-libsieve/src/sieve-tools/debug/ext-debug.c
97956
 
--- dovecot-1.2.4/dovecot-libsieve/src/sieve-tools/debug/ext-debug.c    1970-01-01 01:00:00.000000000 +0100
97957
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/sieve-tools/debug/ext-debug.c     2009-03-26 17:53:38.000000000 +0100
97958
 
@@ -0,0 +1,57 @@
97959
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
97960
 
+ */
97961
 
+
97962
 
+/* Extension debug 
97963
 
+ * ------------------
97964
 
+ *
97965
 
+ * Authors: Stephan Bosch
97966
 
+ * Specification: vendor-defined
97967
 
+ * Implementation: full
97968
 
+ * Status: experimental
97969
 
+ *
97970
 
+ */
97971
 
97972
 
+#include "lib.h"
97973
 
+#include "array.h"
97974
 
+
97975
 
+#include "sieve-extensions.h"
97976
 
+#include "sieve-commands.h"
97977
 
+#include "sieve-comparators.h"
97978
 
+#include "sieve-match-types.h"
97979
 
+#include "sieve-address-parts.h"
97980
 
+
97981
 
+#include "sieve-validator.h"
97982
 
+#include "sieve-generator.h"
97983
 
+#include "sieve-binary.h"
97984
 
+#include "sieve-interpreter.h"
97985
 
+#include "sieve-dump.h"
97986
 
+
97987
 
+#include "ext-debug-common.h"
97988
 
+
97989
 
+/* 
97990
 
+ * Extension 
97991
 
+ */
97992
 
+
97993
 
+static bool ext_debug_validator_load(struct sieve_validator *validator);
97994
 
+
97995
 
+int ext_debug_my_id = -1;
97996
 
+
97997
 
+const struct sieve_extension debug_extension = { 
97998
 
+       "vnd.dovecot.debug", 
97999
 
+       &ext_debug_my_id,
98000
 
+       NULL, NULL,
98001
 
+       ext_debug_validator_load, 
98002
 
+       NULL, NULL, NULL, NULL, NULL,
98003
 
+       SIEVE_EXT_DEFINE_OPERATION(debug_print_operation), 
98004
 
+       SIEVE_EXT_DEFINE_NO_OPERANDS
98005
 
+};
98006
 
+
98007
 
+static bool ext_debug_validator_load(struct sieve_validator *validator)
98008
 
+{
98009
 
+       /* Register new test */
98010
 
+       sieve_validator_register_command(validator, &debug_print_command);
98011
 
+
98012
 
+       return TRUE;
98013
 
+}
98014
 
+
98015
 
+
98016
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/sieve-tools/debug/ext-debug-common.h dovecot-1.2.4.debian/dovecot-libsieve/src/sieve-tools/debug/ext-debug-common.h
98017
 
--- dovecot-1.2.4/dovecot-libsieve/src/sieve-tools/debug/ext-debug-common.h     1970-01-01 01:00:00.000000000 +0100
98018
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/sieve-tools/debug/ext-debug-common.h      2009-03-26 17:53:38.000000000 +0100
98019
 
@@ -0,0 +1,21 @@
98020
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
98021
 
+ */
98022
 
98023
 
+#ifndef __EXT_DEBUG_COMMON_H
98024
 
+#define __EXT_DEBUG_COMMON_H
98025
 
+
98026
 
+#include "sieve-ext-debug.h"
98027
 
+
98028
 
+/* 
98029
 
+ * Commands
98030
 
+ */
98031
 
+
98032
 
+extern const struct sieve_command debug_print_command;
98033
 
98034
 
+/*
98035
 
+ * Operations
98036
 
+ */
98037
 
+
98038
 
+extern const struct sieve_operation debug_print_operation;
98039
 
+
98040
 
+#endif /* __EXT_DEBUG_COMMON_H */
98041
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/sieve-tools/debug/Makefile.am dovecot-1.2.4.debian/dovecot-libsieve/src/sieve-tools/debug/Makefile.am
98042
 
--- dovecot-1.2.4/dovecot-libsieve/src/sieve-tools/debug/Makefile.am    1970-01-01 01:00:00.000000000 +0100
98043
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/sieve-tools/debug/Makefile.am     2009-03-26 17:53:38.000000000 +0100
98044
 
@@ -0,0 +1,19 @@
98045
 
+noinst_LTLIBRARIES = libsieve_ext_debug.la
98046
 
+
98047
 
+AM_CPPFLAGS = \
98048
 
+       -I$(top_srcdir)/src/lib-sieve \
98049
 
+       -I$(dovecot_incdir) \
98050
 
+       -I$(dovecot_incdir)/src/lib \
98051
 
+       -I$(dovecot_incdir)/src/lib-mail \
98052
 
+       -I$(dovecot_incdir)/src/lib-storage 
98053
 
+
98054
 
+commands = \
98055
 
+       cmd-debug-print.c
98056
 
+
98057
 
+libsieve_ext_debug_la_SOURCES = \
98058
 
+       $(commands) \
98059
 
+       ext-debug.c
98060
 
+
98061
 
+noinst_HEADERS = \
98062
 
+       sieve-ext-debug.h \
98063
 
+       ext-debug-common.h
98064
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/sieve-tools/debug/Makefile.in dovecot-1.2.4.debian/dovecot-libsieve/src/sieve-tools/debug/Makefile.in
98065
 
--- dovecot-1.2.4/dovecot-libsieve/src/sieve-tools/debug/Makefile.in    1970-01-01 01:00:00.000000000 +0100
98066
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/sieve-tools/debug/Makefile.in     2009-08-21 00:55:44.000000000 +0200
98067
 
@@ -0,0 +1,466 @@
98068
 
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
98069
 
+# @configure_input@
98070
 
+
98071
 
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
98072
 
+# 2003, 2004, 2005, 2006, 2007, 2008  Free Software Foundation, Inc.
98073
 
+# This Makefile.in is free software; the Free Software Foundation
98074
 
+# gives unlimited permission to copy and/or distribute it,
98075
 
+# with or without modifications, as long as this notice is preserved.
98076
 
+
98077
 
+# This program is distributed in the hope that it will be useful,
98078
 
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
98079
 
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
98080
 
+# PARTICULAR PURPOSE.
98081
 
+
98082
 
+@SET_MAKE@
98083
 
+
98084
 
+
98085
 
+VPATH = @srcdir@
98086
 
+pkgdatadir = $(datadir)/@PACKAGE@
98087
 
+pkglibdir = $(libdir)/@PACKAGE@
98088
 
+pkgincludedir = $(includedir)/@PACKAGE@
98089
 
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
98090
 
+install_sh_DATA = $(install_sh) -c -m 644
98091
 
+install_sh_PROGRAM = $(install_sh) -c
98092
 
+install_sh_SCRIPT = $(install_sh) -c
98093
 
+INSTALL_HEADER = $(INSTALL_DATA)
98094
 
+transform = $(program_transform_name)
98095
 
+NORMAL_INSTALL = :
98096
 
+PRE_INSTALL = :
98097
 
+POST_INSTALL = :
98098
 
+NORMAL_UNINSTALL = :
98099
 
+PRE_UNINSTALL = :
98100
 
+POST_UNINSTALL = :
98101
 
+build_triplet = @build@
98102
 
+host_triplet = @host@
98103
 
+subdir = src/sieve-tools/debug
98104
 
+DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
98105
 
+       $(srcdir)/Makefile.in
98106
 
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
98107
 
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
98108
 
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
98109
 
+       $(ACLOCAL_M4)
98110
 
+mkinstalldirs = $(install_sh) -d
98111
 
+CONFIG_HEADER = $(top_builddir)/dummy-config.h \
98112
 
+       $(top_builddir)/dsieve-config.h
98113
 
+CONFIG_CLEAN_FILES =
98114
 
+LTLIBRARIES = $(noinst_LTLIBRARIES)
98115
 
+libsieve_ext_debug_la_LIBADD =
98116
 
+am__objects_1 = cmd-debug-print.lo
98117
 
+am_libsieve_ext_debug_la_OBJECTS = $(am__objects_1) ext-debug.lo
98118
 
+libsieve_ext_debug_la_OBJECTS = $(am_libsieve_ext_debug_la_OBJECTS)
98119
 
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
98120
 
+depcomp = $(SHELL) $(top_srcdir)/depcomp
98121
 
+am__depfiles_maybe = depfiles
98122
 
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
98123
 
+       $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
98124
 
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
98125
 
+       --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
98126
 
+       $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
98127
 
+CCLD = $(CC)
98128
 
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
98129
 
+       --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
98130
 
+       $(LDFLAGS) -o $@
98131
 
+SOURCES = $(libsieve_ext_debug_la_SOURCES)
98132
 
+DIST_SOURCES = $(libsieve_ext_debug_la_SOURCES)
98133
 
+HEADERS = $(noinst_HEADERS)
98134
 
+ETAGS = etags
98135
 
+CTAGS = ctags
98136
 
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
98137
 
+ACLOCAL = @ACLOCAL@
98138
 
+AMTAR = @AMTAR@
98139
 
+AR = @AR@
98140
 
+AUTOCONF = @AUTOCONF@
98141
 
+AUTOHEADER = @AUTOHEADER@
98142
 
+AUTOMAKE = @AUTOMAKE@
98143
 
+AWK = @AWK@
98144
 
+CC = @CC@
98145
 
+CCDEPMODE = @CCDEPMODE@
98146
 
+CFLAGS = @CFLAGS@
98147
 
+CPP = @CPP@
98148
 
+CPPFLAGS = @CPPFLAGS@
98149
 
+CYGPATH_W = @CYGPATH_W@
98150
 
+DEFS = @DEFS@
98151
 
+DEPDIR = @DEPDIR@
98152
 
+DSYMUTIL = @DSYMUTIL@
98153
 
+DUMPBIN = @DUMPBIN@
98154
 
+ECHO_C = @ECHO_C@
98155
 
+ECHO_N = @ECHO_N@
98156
 
+ECHO_T = @ECHO_T@
98157
 
+EGREP = @EGREP@
98158
 
+EXEEXT = @EXEEXT@
98159
 
+FGREP = @FGREP@
98160
 
+GREP = @GREP@
98161
 
+INSTALL = @INSTALL@
98162
 
+INSTALL_DATA = @INSTALL_DATA@
98163
 
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
98164
 
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
98165
 
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
98166
 
+LD = @LD@
98167
 
+LDFLAGS = @LDFLAGS@
98168
 
+LIBICONV = @LIBICONV@
98169
 
+LIBOBJS = @LIBOBJS@
98170
 
+LIBS = @LIBS@
98171
 
+LIBTOOL = @LIBTOOL@
98172
 
+LIPO = @LIPO@
98173
 
+LN_S = @LN_S@
98174
 
+LTLIBOBJS = @LTLIBOBJS@
98175
 
+MAINT = @MAINT@
98176
 
+MAKEINFO = @MAKEINFO@
98177
 
+MKDIR_P = @MKDIR_P@
98178
 
+MODULE_LIBS = @MODULE_LIBS@
98179
 
+NM = @NM@
98180
 
+NMEDIT = @NMEDIT@
98181
 
+OBJDUMP = @OBJDUMP@
98182
 
+OBJEXT = @OBJEXT@
98183
 
+OTOOL = @OTOOL@
98184
 
+OTOOL64 = @OTOOL64@
98185
 
+PACKAGE = @PACKAGE@
98186
 
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
98187
 
+PACKAGE_NAME = @PACKAGE_NAME@
98188
 
+PACKAGE_STRING = @PACKAGE_STRING@
98189
 
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
98190
 
+PACKAGE_URL = @PACKAGE_URL@
98191
 
+PACKAGE_VERSION = @PACKAGE_VERSION@
98192
 
+PATH_SEPARATOR = @PATH_SEPARATOR@
98193
 
+RAND_LIBS = @RAND_LIBS@
98194
 
+RANLIB = @RANLIB@
98195
 
+SED = @SED@
98196
 
+SET_MAKE = @SET_MAKE@
98197
 
+SHELL = @SHELL@
98198
 
+STORAGE_LIBS = @STORAGE_LIBS@
98199
 
+STRIP = @STRIP@
98200
 
+VERSION = @VERSION@
98201
 
+abs_builddir = @abs_builddir@
98202
 
+abs_srcdir = @abs_srcdir@
98203
 
+abs_top_builddir = @abs_top_builddir@
98204
 
+abs_top_srcdir = @abs_top_srcdir@
98205
 
+ac_ct_CC = @ac_ct_CC@
98206
 
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
98207
 
+am__include = @am__include@
98208
 
+am__leading_dot = @am__leading_dot@
98209
 
+am__quote = @am__quote@
98210
 
+am__tar = @am__tar@
98211
 
+am__untar = @am__untar@
98212
 
+bindir = @bindir@
98213
 
+build = @build@
98214
 
+build_alias = @build_alias@
98215
 
+build_cpu = @build_cpu@
98216
 
+build_os = @build_os@
98217
 
+build_vendor = @build_vendor@
98218
 
+builddir = @builddir@
98219
 
+datadir = @datadir@
98220
 
+datarootdir = @datarootdir@
98221
 
+docdir = @docdir@
98222
 
+dovecot_incdir = @dovecot_incdir@
98223
 
+dovecotdir = @dovecotdir@
98224
 
+dvidir = @dvidir@
98225
 
+exec_prefix = @exec_prefix@
98226
 
+host = @host@
98227
 
+host_alias = @host_alias@
98228
 
+host_cpu = @host_cpu@
98229
 
+host_os = @host_os@
98230
 
+host_vendor = @host_vendor@
98231
 
+htmldir = @htmldir@
98232
 
+includedir = @includedir@
98233
 
+infodir = @infodir@
98234
 
+install_sh = @install_sh@
98235
 
+libdir = @libdir@
98236
 
+libexecdir = @libexecdir@
98237
 
+localedir = @localedir@
98238
 
+localstatedir = @localstatedir@
98239
 
+lt_ECHO = @lt_ECHO@
98240
 
+mandir = @mandir@
98241
 
+mkdir_p = @mkdir_p@
98242
 
+moduledir = @moduledir@
98243
 
+oldincludedir = @oldincludedir@
98244
 
+pdfdir = @pdfdir@
98245
 
+prefix = @prefix@
98246
 
+program_transform_name = @program_transform_name@
98247
 
+psdir = @psdir@
98248
 
+sbindir = @sbindir@
98249
 
+sharedstatedir = @sharedstatedir@
98250
 
+srcdir = @srcdir@
98251
 
+sysconfdir = @sysconfdir@
98252
 
+target_alias = @target_alias@
98253
 
+top_build_prefix = @top_build_prefix@
98254
 
+top_builddir = @top_builddir@
98255
 
+top_srcdir = @top_srcdir@
98256
 
+noinst_LTLIBRARIES = libsieve_ext_debug.la
98257
 
+AM_CPPFLAGS = \
98258
 
+       -I$(top_srcdir)/src/lib-sieve \
98259
 
+       -I$(dovecot_incdir) \
98260
 
+       -I$(dovecot_incdir)/src/lib \
98261
 
+       -I$(dovecot_incdir)/src/lib-mail \
98262
 
+       -I$(dovecot_incdir)/src/lib-storage 
98263
 
+
98264
 
+commands = \
98265
 
+       cmd-debug-print.c
98266
 
+
98267
 
+libsieve_ext_debug_la_SOURCES = \
98268
 
+       $(commands) \
98269
 
+       ext-debug.c
98270
 
+
98271
 
+noinst_HEADERS = \
98272
 
+       sieve-ext-debug.h \
98273
 
+       ext-debug-common.h
98274
 
+
98275
 
+all: all-am
98276
 
+
98277
 
+.SUFFIXES:
98278
 
+.SUFFIXES: .c .lo .o .obj
98279
 
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
98280
 
+       @for dep in $?; do \
98281
 
+         case '$(am__configure_deps)' in \
98282
 
+           *$$dep*) \
98283
 
+             ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
98284
 
+               && { if test -f $@; then exit 0; else break; fi; }; \
98285
 
+             exit 1;; \
98286
 
+         esac; \
98287
 
+       done; \
98288
 
+       echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign  src/sieve-tools/debug/Makefile'; \
98289
 
+       cd $(top_srcdir) && \
98290
 
+         $(AUTOMAKE) --foreign  src/sieve-tools/debug/Makefile
98291
 
+.PRECIOUS: Makefile
98292
 
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
98293
 
+       @case '$?' in \
98294
 
+         *config.status*) \
98295
 
+           cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
98296
 
+         *) \
98297
 
+           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
98298
 
+           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
98299
 
+       esac;
98300
 
+
98301
 
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
98302
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
98303
 
+
98304
 
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
98305
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
98306
 
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
98307
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
98308
 
+
98309
 
+clean-noinstLTLIBRARIES:
98310
 
+       -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
98311
 
+       @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
98312
 
+         dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
98313
 
+         test "$$dir" != "$$p" || dir=.; \
98314
 
+         echo "rm -f \"$${dir}/so_locations\""; \
98315
 
+         rm -f "$${dir}/so_locations"; \
98316
 
+       done
98317
 
+libsieve_ext_debug.la: $(libsieve_ext_debug_la_OBJECTS) $(libsieve_ext_debug_la_DEPENDENCIES) 
98318
 
+       $(LINK)  $(libsieve_ext_debug_la_OBJECTS) $(libsieve_ext_debug_la_LIBADD) $(LIBS)
98319
 
+
98320
 
+mostlyclean-compile:
98321
 
+       -rm -f *.$(OBJEXT)
98322
 
+
98323
 
+distclean-compile:
98324
 
+       -rm -f *.tab.c
98325
 
+
98326
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd-debug-print.Plo@am__quote@
98327
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-debug.Plo@am__quote@
98328
 
+
98329
 
+.c.o:
98330
 
+@am__fastdepCC_TRUE@   $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
98331
 
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
98332
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
98333
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
98334
 
+@am__fastdepCC_FALSE@  $(COMPILE) -c $<
98335
 
+
98336
 
+.c.obj:
98337
 
+@am__fastdepCC_TRUE@   $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
98338
 
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
98339
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
98340
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
98341
 
+@am__fastdepCC_FALSE@  $(COMPILE) -c `$(CYGPATH_W) '$<'`
98342
 
+
98343
 
+.c.lo:
98344
 
+@am__fastdepCC_TRUE@   $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
98345
 
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
98346
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
98347
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
98348
 
+@am__fastdepCC_FALSE@  $(LTCOMPILE) -c -o $@ $<
98349
 
+
98350
 
+mostlyclean-libtool:
98351
 
+       -rm -f *.lo
98352
 
+
98353
 
+clean-libtool:
98354
 
+       -rm -rf .libs _libs
98355
 
+
98356
 
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
98357
 
+       list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
98358
 
+       unique=`for i in $$list; do \
98359
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
98360
 
+         done | \
98361
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
98362
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
98363
 
+       mkid -fID $$unique
98364
 
+tags: TAGS
98365
 
+
98366
 
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
98367
 
+               $(TAGS_FILES) $(LISP)
98368
 
+       tags=; \
98369
 
+       here=`pwd`; \
98370
 
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
98371
 
+       unique=`for i in $$list; do \
98372
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
98373
 
+         done | \
98374
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
98375
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
98376
 
+       if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
98377
 
+         test -n "$$unique" || unique=$$empty_fix; \
98378
 
+         $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
98379
 
+           $$tags $$unique; \
98380
 
+       fi
98381
 
+ctags: CTAGS
98382
 
+CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
98383
 
+               $(TAGS_FILES) $(LISP)
98384
 
+       tags=; \
98385
 
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
98386
 
+       unique=`for i in $$list; do \
98387
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
98388
 
+         done | \
98389
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
98390
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
98391
 
+       test -z "$(CTAGS_ARGS)$$tags$$unique" \
98392
 
+         || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
98393
 
+            $$tags $$unique
98394
 
+
98395
 
+GTAGS:
98396
 
+       here=`$(am__cd) $(top_builddir) && pwd` \
98397
 
+         && cd $(top_srcdir) \
98398
 
+         && gtags -i $(GTAGS_ARGS) $$here
98399
 
+
98400
 
+distclean-tags:
98401
 
+       -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
98402
 
+
98403
 
+distdir: $(DISTFILES)
98404
 
+       @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
98405
 
+       topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
98406
 
+       list='$(DISTFILES)'; \
98407
 
+         dist_files=`for file in $$list; do echo $$file; done | \
98408
 
+         sed -e "s|^$$srcdirstrip/||;t" \
98409
 
+             -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
98410
 
+       case $$dist_files in \
98411
 
+         */*) $(MKDIR_P) `echo "$$dist_files" | \
98412
 
+                          sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
98413
 
+                          sort -u` ;; \
98414
 
+       esac; \
98415
 
+       for file in $$dist_files; do \
98416
 
+         if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
98417
 
+         if test -d $$d/$$file; then \
98418
 
+           dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
98419
 
+           if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
98420
 
+             cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
98421
 
+           fi; \
98422
 
+           cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
98423
 
+         else \
98424
 
+           test -f $(distdir)/$$file \
98425
 
+           || cp -p $$d/$$file $(distdir)/$$file \
98426
 
+           || exit 1; \
98427
 
+         fi; \
98428
 
+       done
98429
 
+check-am: all-am
98430
 
+check: check-am
98431
 
+all-am: Makefile $(LTLIBRARIES) $(HEADERS)
98432
 
+installdirs:
98433
 
+install: install-am
98434
 
+install-exec: install-exec-am
98435
 
+install-data: install-data-am
98436
 
+uninstall: uninstall-am
98437
 
+
98438
 
+install-am: all-am
98439
 
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
98440
 
+
98441
 
+installcheck: installcheck-am
98442
 
+install-strip:
98443
 
+       $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
98444
 
+         install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
98445
 
+         `test -z '$(STRIP)' || \
98446
 
+           echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
98447
 
+mostlyclean-generic:
98448
 
+
98449
 
+clean-generic:
98450
 
+
98451
 
+distclean-generic:
98452
 
+       -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
98453
 
+
98454
 
+maintainer-clean-generic:
98455
 
+       @echo "This command is intended for maintainers to use"
98456
 
+       @echo "it deletes files that may require special tools to rebuild."
98457
 
+clean: clean-am
98458
 
+
98459
 
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
98460
 
+       mostlyclean-am
98461
 
+
98462
 
+distclean: distclean-am
98463
 
+       -rm -rf ./$(DEPDIR)
98464
 
+       -rm -f Makefile
98465
 
+distclean-am: clean-am distclean-compile distclean-generic \
98466
 
+       distclean-tags
98467
 
+
98468
 
+dvi: dvi-am
98469
 
+
98470
 
+dvi-am:
98471
 
+
98472
 
+html: html-am
98473
 
+
98474
 
+info: info-am
98475
 
+
98476
 
+info-am:
98477
 
+
98478
 
+install-data-am:
98479
 
+
98480
 
+install-dvi: install-dvi-am
98481
 
+
98482
 
+install-exec-am:
98483
 
+
98484
 
+install-html: install-html-am
98485
 
+
98486
 
+install-info: install-info-am
98487
 
+
98488
 
+install-man:
98489
 
+
98490
 
+install-pdf: install-pdf-am
98491
 
+
98492
 
+install-ps: install-ps-am
98493
 
+
98494
 
+installcheck-am:
98495
 
+
98496
 
+maintainer-clean: maintainer-clean-am
98497
 
+       -rm -rf ./$(DEPDIR)
98498
 
+       -rm -f Makefile
98499
 
+maintainer-clean-am: distclean-am maintainer-clean-generic
98500
 
+
98501
 
+mostlyclean: mostlyclean-am
98502
 
+
98503
 
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
98504
 
+       mostlyclean-libtool
98505
 
+
98506
 
+pdf: pdf-am
98507
 
+
98508
 
+pdf-am:
98509
 
+
98510
 
+ps: ps-am
98511
 
+
98512
 
+ps-am:
98513
 
+
98514
 
+uninstall-am:
98515
 
+
98516
 
+.MAKE: install-am install-strip
98517
 
+
98518
 
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
98519
 
+       clean-libtool clean-noinstLTLIBRARIES ctags distclean \
98520
 
+       distclean-compile distclean-generic distclean-libtool \
98521
 
+       distclean-tags distdir dvi dvi-am html html-am info info-am \
98522
 
+       install install-am install-data install-data-am install-dvi \
98523
 
+       install-dvi-am install-exec install-exec-am install-html \
98524
 
+       install-html-am install-info install-info-am install-man \
98525
 
+       install-pdf install-pdf-am install-ps install-ps-am \
98526
 
+       install-strip installcheck installcheck-am installdirs \
98527
 
+       maintainer-clean maintainer-clean-generic mostlyclean \
98528
 
+       mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
98529
 
+       pdf pdf-am ps ps-am tags uninstall uninstall-am
98530
 
+
98531
 
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
98532
 
+# Otherwise a system limit (for SysV at least) may be exceeded.
98533
 
+.NOEXPORT:
98534
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/sieve-tools/debug/sieve-ext-debug.h dovecot-1.2.4.debian/dovecot-libsieve/src/sieve-tools/debug/sieve-ext-debug.h
98535
 
--- dovecot-1.2.4/dovecot-libsieve/src/sieve-tools/debug/sieve-ext-debug.h      1970-01-01 01:00:00.000000000 +0100
98536
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/sieve-tools/debug/sieve-ext-debug.h       2009-03-26 17:53:38.000000000 +0100
98537
 
@@ -0,0 +1,13 @@
98538
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
98539
 
+ */
98540
 
98541
 
+#ifndef __SIEVE_EXT_DEBUG_H
98542
 
+#define __SIEVE_EXT_DEBUG_H
98543
 
+
98544
 
+/*
98545
 
+ * Extension
98546
 
+ */
98547
 
98548
 
+extern const struct sieve_extension debug_extension;
98549
 
+
98550
 
+#endif /* __SIEVE_EXT_DEBUG_H */
98551
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/sieve-tools/Makefile.am dovecot-1.2.4.debian/dovecot-libsieve/src/sieve-tools/Makefile.am
98552
 
--- dovecot-1.2.4/dovecot-libsieve/src/sieve-tools/Makefile.am  1970-01-01 01:00:00.000000000 +0100
98553
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/sieve-tools/Makefile.am   2009-07-20 23:30:49.000000000 +0200
98554
 
@@ -0,0 +1,72 @@
98555
 
+pkglibexecdir = $(libexecdir)/dovecot
98556
 
+
98557
 
+SUBDIRS = debug
98558
 
+
98559
 
+bin_PROGRAMS = sievec sieved sieve-test
98560
 
+
98561
 
+if BUILD_UNFINISHED
98562
 
+bin_PROGRAMS += sieve-filter
98563
 
+endif
98564
 
+
98565
 
+AM_CPPFLAGS = \
98566
 
+       -I$(top_srcdir)/src/lib-sieve \
98567
 
+       -I$(top_srcdir)/src/lib-sieve-tool \
98568
 
+       -I./debug \
98569
 
+       -I$(dovecot_incdir) \
98570
 
+       -I$(dovecot_incdir)/src/lib \
98571
 
+       -I$(dovecot_incdir)/src/lib-mail \
98572
 
+       -I$(dovecot_incdir)/src/lib-index \
98573
 
+       -I$(dovecot_incdir)/src/lib-storage \
98574
 
+       -I$(dovecot_incdir)/src/deliver
98575
 
+
98576
 
+libs = \
98577
 
+       $(top_srcdir)/src/lib-sieve/libsieve.la \
98578
 
+       $(top_srcdir)/src/lib-sieve-tool/libsieve-tool.la \
98579
 
+       ./debug/libsieve_ext_debug.la \
98580
 
+       $(STORAGE_LIBS) 
98581
 
+
98582
 
+ldadd = \
98583
 
+       $(libs) \
98584
 
+       $(LIBICONV) \
98585
 
+       $(RAND_LIBS) \
98586
 
+       $(MODULE_LIBS)
98587
 
+
98588
 
+# Sieve Compile Tool
98589
 
+
98590
 
+sievec_LDFLAGS = -export-dynamic 
98591
 
+sievec_LDADD = $(ldadd)
98592
 
+sievec_DEPENDENCIES = $(libs)
98593
 
+
98594
 
+sievec_SOURCES = \
98595
 
+       sievec.c 
98596
 
+
98597
 
+# Sieve Dump Tool
98598
 
+
98599
 
+sieved_LDFLAGS = -export-dynamic 
98600
 
+sieved_LDADD = $(ldadd)
98601
 
+sieved_DEPENDENCIES = $(libs)
98602
 
+
98603
 
+sieved_SOURCES = \
98604
 
+       sieved.c 
98605
 
+
98606
 
+# Sieve Test Tool
98607
 
+
98608
 
+sieve_test_LDFLAGS = -export-dynamic
98609
 
+sieve_test_LDADD = $(ldadd)
98610
 
+sieve_test_DEPENDENCIES = $(libs)
98611
 
+
98612
 
+sieve_test_SOURCES = \
98613
 
+       sieve-test.c 
98614
 
+
98615
 
+## Unfinished tools
98616
 
+
98617
 
+# Sieve Filter Tool
98618
 
+
98619
 
+sieve_filter_LDFLAGS = -export-dynamic
98620
 
+sieve_filter_LDADD = $(ldadd)
98621
 
+sieve_filter_DEPENDENCIES = $(libs)
98622
 
+
98623
 
+sieve_filter_SOURCES = \
98624
 
+       sieve-filter.c 
98625
 
+
98626
 
+noinst_HEADERS =
98627
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/sieve-tools/Makefile.in dovecot-1.2.4.debian/dovecot-libsieve/src/sieve-tools/Makefile.in
98628
 
--- dovecot-1.2.4/dovecot-libsieve/src/sieve-tools/Makefile.in  1970-01-01 01:00:00.000000000 +0100
98629
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/sieve-tools/Makefile.in   2009-08-21 00:55:44.000000000 +0200
98630
 
@@ -0,0 +1,683 @@
98631
 
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
98632
 
+# @configure_input@
98633
 
+
98634
 
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
98635
 
+# 2003, 2004, 2005, 2006, 2007, 2008  Free Software Foundation, Inc.
98636
 
+# This Makefile.in is free software; the Free Software Foundation
98637
 
+# gives unlimited permission to copy and/or distribute it,
98638
 
+# with or without modifications, as long as this notice is preserved.
98639
 
+
98640
 
+# This program is distributed in the hope that it will be useful,
98641
 
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
98642
 
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
98643
 
+# PARTICULAR PURPOSE.
98644
 
+
98645
 
+@SET_MAKE@
98646
 
+
98647
 
+
98648
 
+VPATH = @srcdir@
98649
 
+pkgdatadir = $(datadir)/@PACKAGE@
98650
 
+pkglibdir = $(libdir)/@PACKAGE@
98651
 
+pkgincludedir = $(includedir)/@PACKAGE@
98652
 
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
98653
 
+install_sh_DATA = $(install_sh) -c -m 644
98654
 
+install_sh_PROGRAM = $(install_sh) -c
98655
 
+install_sh_SCRIPT = $(install_sh) -c
98656
 
+INSTALL_HEADER = $(INSTALL_DATA)
98657
 
+transform = $(program_transform_name)
98658
 
+NORMAL_INSTALL = :
98659
 
+PRE_INSTALL = :
98660
 
+POST_INSTALL = :
98661
 
+NORMAL_UNINSTALL = :
98662
 
+PRE_UNINSTALL = :
98663
 
+POST_UNINSTALL = :
98664
 
+build_triplet = @build@
98665
 
+host_triplet = @host@
98666
 
+bin_PROGRAMS = sievec$(EXEEXT) sieved$(EXEEXT) sieve-test$(EXEEXT) \
98667
 
+       $(am__EXEEXT_1)
98668
 
+@BUILD_UNFINISHED_TRUE@am__append_1 = sieve-filter
98669
 
+subdir = src/sieve-tools
98670
 
+DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
98671
 
+       $(srcdir)/Makefile.in
98672
 
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
98673
 
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
98674
 
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
98675
 
+       $(ACLOCAL_M4)
98676
 
+mkinstalldirs = $(install_sh) -d
98677
 
+CONFIG_HEADER = $(top_builddir)/dummy-config.h \
98678
 
+       $(top_builddir)/dsieve-config.h
98679
 
+CONFIG_CLEAN_FILES =
98680
 
+@BUILD_UNFINISHED_TRUE@am__EXEEXT_1 = sieve-filter$(EXEEXT)
98681
 
+am__installdirs = "$(DESTDIR)$(bindir)"
98682
 
+binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
98683
 
+PROGRAMS = $(bin_PROGRAMS)
98684
 
+am_sieve_filter_OBJECTS = sieve-filter.$(OBJEXT)
98685
 
+sieve_filter_OBJECTS = $(am_sieve_filter_OBJECTS)
98686
 
+am__DEPENDENCIES_1 =
98687
 
+am__DEPENDENCIES_2 = $(top_srcdir)/src/lib-sieve/libsieve.la \
98688
 
+       $(top_srcdir)/src/lib-sieve-tool/libsieve-tool.la \
98689
 
+       ./debug/libsieve_ext_debug.la $(am__DEPENDENCIES_1)
98690
 
+am__DEPENDENCIES_3 = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1) \
98691
 
+       $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
98692
 
+sieve_filter_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
98693
 
+       $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
98694
 
+       $(sieve_filter_LDFLAGS) $(LDFLAGS) -o $@
98695
 
+am_sieve_test_OBJECTS = sieve-test.$(OBJEXT)
98696
 
+sieve_test_OBJECTS = $(am_sieve_test_OBJECTS)
98697
 
+sieve_test_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
98698
 
+       $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
98699
 
+       $(sieve_test_LDFLAGS) $(LDFLAGS) -o $@
98700
 
+am_sievec_OBJECTS = sievec.$(OBJEXT)
98701
 
+sievec_OBJECTS = $(am_sievec_OBJECTS)
98702
 
+sievec_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
98703
 
+       --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(sievec_LDFLAGS) \
98704
 
+       $(LDFLAGS) -o $@
98705
 
+am_sieved_OBJECTS = sieved.$(OBJEXT)
98706
 
+sieved_OBJECTS = $(am_sieved_OBJECTS)
98707
 
+sieved_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
98708
 
+       --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(sieved_LDFLAGS) \
98709
 
+       $(LDFLAGS) -o $@
98710
 
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
98711
 
+depcomp = $(SHELL) $(top_srcdir)/depcomp
98712
 
+am__depfiles_maybe = depfiles
98713
 
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
98714
 
+       $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
98715
 
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
98716
 
+       --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
98717
 
+       $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
98718
 
+CCLD = $(CC)
98719
 
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
98720
 
+       --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
98721
 
+       $(LDFLAGS) -o $@
98722
 
+SOURCES = $(sieve_filter_SOURCES) $(sieve_test_SOURCES) \
98723
 
+       $(sievec_SOURCES) $(sieved_SOURCES)
98724
 
+DIST_SOURCES = $(sieve_filter_SOURCES) $(sieve_test_SOURCES) \
98725
 
+       $(sievec_SOURCES) $(sieved_SOURCES)
98726
 
+RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
98727
 
+       html-recursive info-recursive install-data-recursive \
98728
 
+       install-dvi-recursive install-exec-recursive \
98729
 
+       install-html-recursive install-info-recursive \
98730
 
+       install-pdf-recursive install-ps-recursive install-recursive \
98731
 
+       installcheck-recursive installdirs-recursive pdf-recursive \
98732
 
+       ps-recursive uninstall-recursive
98733
 
+HEADERS = $(noinst_HEADERS)
98734
 
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive        \
98735
 
+  distclean-recursive maintainer-clean-recursive
98736
 
+ETAGS = etags
98737
 
+CTAGS = ctags
98738
 
+DIST_SUBDIRS = $(SUBDIRS)
98739
 
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
98740
 
+ACLOCAL = @ACLOCAL@
98741
 
+AMTAR = @AMTAR@
98742
 
+AR = @AR@
98743
 
+AUTOCONF = @AUTOCONF@
98744
 
+AUTOHEADER = @AUTOHEADER@
98745
 
+AUTOMAKE = @AUTOMAKE@
98746
 
+AWK = @AWK@
98747
 
+CC = @CC@
98748
 
+CCDEPMODE = @CCDEPMODE@
98749
 
+CFLAGS = @CFLAGS@
98750
 
+CPP = @CPP@
98751
 
+CPPFLAGS = @CPPFLAGS@
98752
 
+CYGPATH_W = @CYGPATH_W@
98753
 
+DEFS = @DEFS@
98754
 
+DEPDIR = @DEPDIR@
98755
 
+DSYMUTIL = @DSYMUTIL@
98756
 
+DUMPBIN = @DUMPBIN@
98757
 
+ECHO_C = @ECHO_C@
98758
 
+ECHO_N = @ECHO_N@
98759
 
+ECHO_T = @ECHO_T@
98760
 
+EGREP = @EGREP@
98761
 
+EXEEXT = @EXEEXT@
98762
 
+FGREP = @FGREP@
98763
 
+GREP = @GREP@
98764
 
+INSTALL = @INSTALL@
98765
 
+INSTALL_DATA = @INSTALL_DATA@
98766
 
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
98767
 
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
98768
 
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
98769
 
+LD = @LD@
98770
 
+LDFLAGS = @LDFLAGS@
98771
 
+LIBICONV = @LIBICONV@
98772
 
+LIBOBJS = @LIBOBJS@
98773
 
+LIBS = @LIBS@
98774
 
+LIBTOOL = @LIBTOOL@
98775
 
+LIPO = @LIPO@
98776
 
+LN_S = @LN_S@
98777
 
+LTLIBOBJS = @LTLIBOBJS@
98778
 
+MAINT = @MAINT@
98779
 
+MAKEINFO = @MAKEINFO@
98780
 
+MKDIR_P = @MKDIR_P@
98781
 
+MODULE_LIBS = @MODULE_LIBS@
98782
 
+NM = @NM@
98783
 
+NMEDIT = @NMEDIT@
98784
 
+OBJDUMP = @OBJDUMP@
98785
 
+OBJEXT = @OBJEXT@
98786
 
+OTOOL = @OTOOL@
98787
 
+OTOOL64 = @OTOOL64@
98788
 
+PACKAGE = @PACKAGE@
98789
 
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
98790
 
+PACKAGE_NAME = @PACKAGE_NAME@
98791
 
+PACKAGE_STRING = @PACKAGE_STRING@
98792
 
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
98793
 
+PACKAGE_URL = @PACKAGE_URL@
98794
 
+PACKAGE_VERSION = @PACKAGE_VERSION@
98795
 
+PATH_SEPARATOR = @PATH_SEPARATOR@
98796
 
+RAND_LIBS = @RAND_LIBS@
98797
 
+RANLIB = @RANLIB@
98798
 
+SED = @SED@
98799
 
+SET_MAKE = @SET_MAKE@
98800
 
+SHELL = @SHELL@
98801
 
+STORAGE_LIBS = @STORAGE_LIBS@
98802
 
+STRIP = @STRIP@
98803
 
+VERSION = @VERSION@
98804
 
+abs_builddir = @abs_builddir@
98805
 
+abs_srcdir = @abs_srcdir@
98806
 
+abs_top_builddir = @abs_top_builddir@
98807
 
+abs_top_srcdir = @abs_top_srcdir@
98808
 
+ac_ct_CC = @ac_ct_CC@
98809
 
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
98810
 
+am__include = @am__include@
98811
 
+am__leading_dot = @am__leading_dot@
98812
 
+am__quote = @am__quote@
98813
 
+am__tar = @am__tar@
98814
 
+am__untar = @am__untar@
98815
 
+bindir = @bindir@
98816
 
+build = @build@
98817
 
+build_alias = @build_alias@
98818
 
+build_cpu = @build_cpu@
98819
 
+build_os = @build_os@
98820
 
+build_vendor = @build_vendor@
98821
 
+builddir = @builddir@
98822
 
+datadir = @datadir@
98823
 
+datarootdir = @datarootdir@
98824
 
+docdir = @docdir@
98825
 
+dovecot_incdir = @dovecot_incdir@
98826
 
+dovecotdir = @dovecotdir@
98827
 
+dvidir = @dvidir@
98828
 
+exec_prefix = @exec_prefix@
98829
 
+host = @host@
98830
 
+host_alias = @host_alias@
98831
 
+host_cpu = @host_cpu@
98832
 
+host_os = @host_os@
98833
 
+host_vendor = @host_vendor@
98834
 
+htmldir = @htmldir@
98835
 
+includedir = @includedir@
98836
 
+infodir = @infodir@
98837
 
+install_sh = @install_sh@
98838
 
+libdir = @libdir@
98839
 
+libexecdir = @libexecdir@
98840
 
+localedir = @localedir@
98841
 
+localstatedir = @localstatedir@
98842
 
+lt_ECHO = @lt_ECHO@
98843
 
+mandir = @mandir@
98844
 
+mkdir_p = @mkdir_p@
98845
 
+moduledir = @moduledir@
98846
 
+oldincludedir = @oldincludedir@
98847
 
+pdfdir = @pdfdir@
98848
 
+prefix = @prefix@
98849
 
+program_transform_name = @program_transform_name@
98850
 
+psdir = @psdir@
98851
 
+sbindir = @sbindir@
98852
 
+sharedstatedir = @sharedstatedir@
98853
 
+srcdir = @srcdir@
98854
 
+sysconfdir = @sysconfdir@
98855
 
+target_alias = @target_alias@
98856
 
+top_build_prefix = @top_build_prefix@
98857
 
+top_builddir = @top_builddir@
98858
 
+top_srcdir = @top_srcdir@
98859
 
+pkglibexecdir = $(libexecdir)/dovecot
98860
 
+SUBDIRS = debug
98861
 
+AM_CPPFLAGS = \
98862
 
+       -I$(top_srcdir)/src/lib-sieve \
98863
 
+       -I$(top_srcdir)/src/lib-sieve-tool \
98864
 
+       -I./debug \
98865
 
+       -I$(dovecot_incdir) \
98866
 
+       -I$(dovecot_incdir)/src/lib \
98867
 
+       -I$(dovecot_incdir)/src/lib-mail \
98868
 
+       -I$(dovecot_incdir)/src/lib-index \
98869
 
+       -I$(dovecot_incdir)/src/lib-storage \
98870
 
+       -I$(dovecot_incdir)/src/deliver
98871
 
+
98872
 
+libs = \
98873
 
+       $(top_srcdir)/src/lib-sieve/libsieve.la \
98874
 
+       $(top_srcdir)/src/lib-sieve-tool/libsieve-tool.la \
98875
 
+       ./debug/libsieve_ext_debug.la \
98876
 
+       $(STORAGE_LIBS) 
98877
 
+
98878
 
+ldadd = \
98879
 
+       $(libs) \
98880
 
+       $(LIBICONV) \
98881
 
+       $(RAND_LIBS) \
98882
 
+       $(MODULE_LIBS)
98883
 
+
98884
 
+
98885
 
+# Sieve Compile Tool
98886
 
+sievec_LDFLAGS = -export-dynamic 
98887
 
+sievec_LDADD = $(ldadd)
98888
 
+sievec_DEPENDENCIES = $(libs)
98889
 
+sievec_SOURCES = \
98890
 
+       sievec.c 
98891
 
+
98892
 
+
98893
 
+# Sieve Dump Tool
98894
 
+sieved_LDFLAGS = -export-dynamic 
98895
 
+sieved_LDADD = $(ldadd)
98896
 
+sieved_DEPENDENCIES = $(libs)
98897
 
+sieved_SOURCES = \
98898
 
+       sieved.c 
98899
 
+
98900
 
+
98901
 
+# Sieve Test Tool
98902
 
+sieve_test_LDFLAGS = -export-dynamic
98903
 
+sieve_test_LDADD = $(ldadd)
98904
 
+sieve_test_DEPENDENCIES = $(libs)
98905
 
+sieve_test_SOURCES = \
98906
 
+       sieve-test.c 
98907
 
+
98908
 
+
98909
 
+# Sieve Filter Tool
98910
 
+sieve_filter_LDFLAGS = -export-dynamic
98911
 
+sieve_filter_LDADD = $(ldadd)
98912
 
+sieve_filter_DEPENDENCIES = $(libs)
98913
 
+sieve_filter_SOURCES = \
98914
 
+       sieve-filter.c 
98915
 
+
98916
 
+noinst_HEADERS = 
98917
 
+all: all-recursive
98918
 
+
98919
 
+.SUFFIXES:
98920
 
+.SUFFIXES: .c .lo .o .obj
98921
 
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
98922
 
+       @for dep in $?; do \
98923
 
+         case '$(am__configure_deps)' in \
98924
 
+           *$$dep*) \
98925
 
+             ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
98926
 
+               && { if test -f $@; then exit 0; else break; fi; }; \
98927
 
+             exit 1;; \
98928
 
+         esac; \
98929
 
+       done; \
98930
 
+       echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign  src/sieve-tools/Makefile'; \
98931
 
+       cd $(top_srcdir) && \
98932
 
+         $(AUTOMAKE) --foreign  src/sieve-tools/Makefile
98933
 
+.PRECIOUS: Makefile
98934
 
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
98935
 
+       @case '$?' in \
98936
 
+         *config.status*) \
98937
 
+           cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
98938
 
+         *) \
98939
 
+           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
98940
 
+           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
98941
 
+       esac;
98942
 
+
98943
 
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
98944
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
98945
 
+
98946
 
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
98947
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
98948
 
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
98949
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
98950
 
+install-binPROGRAMS: $(bin_PROGRAMS)
98951
 
+       @$(NORMAL_INSTALL)
98952
 
+       test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
98953
 
+       @list='$(bin_PROGRAMS)'; for p in $$list; do \
98954
 
+         p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
98955
 
+         if test -f $$p \
98956
 
+            || test -f $$p1 \
98957
 
+         ; then \
98958
 
+           f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
98959
 
+          echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \
98960
 
+          $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \
98961
 
+         else :; fi; \
98962
 
+       done
98963
 
+
98964
 
+uninstall-binPROGRAMS:
98965
 
+       @$(NORMAL_UNINSTALL)
98966
 
+       @list='$(bin_PROGRAMS)'; for p in $$list; do \
98967
 
+         f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
98968
 
+         echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \
98969
 
+         rm -f "$(DESTDIR)$(bindir)/$$f"; \
98970
 
+       done
98971
 
+
98972
 
+clean-binPROGRAMS:
98973
 
+       @list='$(bin_PROGRAMS)'; for p in $$list; do \
98974
 
+         f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
98975
 
+         echo " rm -f $$p $$f"; \
98976
 
+         rm -f $$p $$f ; \
98977
 
+       done
98978
 
+sieve-filter$(EXEEXT): $(sieve_filter_OBJECTS) $(sieve_filter_DEPENDENCIES) 
98979
 
+       @rm -f sieve-filter$(EXEEXT)
98980
 
+       $(sieve_filter_LINK) $(sieve_filter_OBJECTS) $(sieve_filter_LDADD) $(LIBS)
98981
 
+sieve-test$(EXEEXT): $(sieve_test_OBJECTS) $(sieve_test_DEPENDENCIES) 
98982
 
+       @rm -f sieve-test$(EXEEXT)
98983
 
+       $(sieve_test_LINK) $(sieve_test_OBJECTS) $(sieve_test_LDADD) $(LIBS)
98984
 
+sievec$(EXEEXT): $(sievec_OBJECTS) $(sievec_DEPENDENCIES) 
98985
 
+       @rm -f sievec$(EXEEXT)
98986
 
+       $(sievec_LINK) $(sievec_OBJECTS) $(sievec_LDADD) $(LIBS)
98987
 
+sieved$(EXEEXT): $(sieved_OBJECTS) $(sieved_DEPENDENCIES) 
98988
 
+       @rm -f sieved$(EXEEXT)
98989
 
+       $(sieved_LINK) $(sieved_OBJECTS) $(sieved_LDADD) $(LIBS)
98990
 
+
98991
 
+mostlyclean-compile:
98992
 
+       -rm -f *.$(OBJEXT)
98993
 
+
98994
 
+distclean-compile:
98995
 
+       -rm -f *.tab.c
98996
 
+
98997
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-filter.Po@am__quote@
98998
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieve-test.Po@am__quote@
98999
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sievec.Po@am__quote@
99000
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sieved.Po@am__quote@
99001
 
+
99002
 
+.c.o:
99003
 
+@am__fastdepCC_TRUE@   $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
99004
 
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
99005
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
99006
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
99007
 
+@am__fastdepCC_FALSE@  $(COMPILE) -c $<
99008
 
+
99009
 
+.c.obj:
99010
 
+@am__fastdepCC_TRUE@   $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
99011
 
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
99012
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
99013
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
99014
 
+@am__fastdepCC_FALSE@  $(COMPILE) -c `$(CYGPATH_W) '$<'`
99015
 
+
99016
 
+.c.lo:
99017
 
+@am__fastdepCC_TRUE@   $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
99018
 
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
99019
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
99020
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
99021
 
+@am__fastdepCC_FALSE@  $(LTCOMPILE) -c -o $@ $<
99022
 
+
99023
 
+mostlyclean-libtool:
99024
 
+       -rm -f *.lo
99025
 
+
99026
 
+clean-libtool:
99027
 
+       -rm -rf .libs _libs
99028
 
+
99029
 
+# This directory's subdirectories are mostly independent; you can cd
99030
 
+# into them and run `make' without going through this Makefile.
99031
 
+# To change the values of `make' variables: instead of editing Makefiles,
99032
 
+# (1) if the variable is set in `config.status', edit `config.status'
99033
 
+#     (which will cause the Makefiles to be regenerated when you run `make');
99034
 
+# (2) otherwise, pass the desired values on the `make' command line.
99035
 
+$(RECURSIVE_TARGETS):
99036
 
+       @failcom='exit 1'; \
99037
 
+       for f in x $$MAKEFLAGS; do \
99038
 
+         case $$f in \
99039
 
+           *=* | --[!k]*);; \
99040
 
+           *k*) failcom='fail=yes';; \
99041
 
+         esac; \
99042
 
+       done; \
99043
 
+       dot_seen=no; \
99044
 
+       target=`echo $@ | sed s/-recursive//`; \
99045
 
+       list='$(SUBDIRS)'; for subdir in $$list; do \
99046
 
+         echo "Making $$target in $$subdir"; \
99047
 
+         if test "$$subdir" = "."; then \
99048
 
+           dot_seen=yes; \
99049
 
+           local_target="$$target-am"; \
99050
 
+         else \
99051
 
+           local_target="$$target"; \
99052
 
+         fi; \
99053
 
+         (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
99054
 
+         || eval $$failcom; \
99055
 
+       done; \
99056
 
+       if test "$$dot_seen" = "no"; then \
99057
 
+         $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
99058
 
+       fi; test -z "$$fail"
99059
 
+
99060
 
+$(RECURSIVE_CLEAN_TARGETS):
99061
 
+       @failcom='exit 1'; \
99062
 
+       for f in x $$MAKEFLAGS; do \
99063
 
+         case $$f in \
99064
 
+           *=* | --[!k]*);; \
99065
 
+           *k*) failcom='fail=yes';; \
99066
 
+         esac; \
99067
 
+       done; \
99068
 
+       dot_seen=no; \
99069
 
+       case "$@" in \
99070
 
+         distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
99071
 
+         *) list='$(SUBDIRS)' ;; \
99072
 
+       esac; \
99073
 
+       rev=''; for subdir in $$list; do \
99074
 
+         if test "$$subdir" = "."; then :; else \
99075
 
+           rev="$$subdir $$rev"; \
99076
 
+         fi; \
99077
 
+       done; \
99078
 
+       rev="$$rev ."; \
99079
 
+       target=`echo $@ | sed s/-recursive//`; \
99080
 
+       for subdir in $$rev; do \
99081
 
+         echo "Making $$target in $$subdir"; \
99082
 
+         if test "$$subdir" = "."; then \
99083
 
+           local_target="$$target-am"; \
99084
 
+         else \
99085
 
+           local_target="$$target"; \
99086
 
+         fi; \
99087
 
+         (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
99088
 
+         || eval $$failcom; \
99089
 
+       done && test -z "$$fail"
99090
 
+tags-recursive:
99091
 
+       list='$(SUBDIRS)'; for subdir in $$list; do \
99092
 
+         test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
99093
 
+       done
99094
 
+ctags-recursive:
99095
 
+       list='$(SUBDIRS)'; for subdir in $$list; do \
99096
 
+         test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
99097
 
+       done
99098
 
+
99099
 
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
99100
 
+       list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
99101
 
+       unique=`for i in $$list; do \
99102
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
99103
 
+         done | \
99104
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
99105
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
99106
 
+       mkid -fID $$unique
99107
 
+tags: TAGS
99108
 
+
99109
 
+TAGS: tags-recursive $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
99110
 
+               $(TAGS_FILES) $(LISP)
99111
 
+       tags=; \
99112
 
+       here=`pwd`; \
99113
 
+       if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
99114
 
+         include_option=--etags-include; \
99115
 
+         empty_fix=.; \
99116
 
+       else \
99117
 
+         include_option=--include; \
99118
 
+         empty_fix=; \
99119
 
+       fi; \
99120
 
+       list='$(SUBDIRS)'; for subdir in $$list; do \
99121
 
+         if test "$$subdir" = .; then :; else \
99122
 
+           test ! -f $$subdir/TAGS || \
99123
 
+             tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \
99124
 
+         fi; \
99125
 
+       done; \
99126
 
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
99127
 
+       unique=`for i in $$list; do \
99128
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
99129
 
+         done | \
99130
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
99131
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
99132
 
+       if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
99133
 
+         test -n "$$unique" || unique=$$empty_fix; \
99134
 
+         $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
99135
 
+           $$tags $$unique; \
99136
 
+       fi
99137
 
+ctags: CTAGS
99138
 
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
99139
 
+               $(TAGS_FILES) $(LISP)
99140
 
+       tags=; \
99141
 
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
99142
 
+       unique=`for i in $$list; do \
99143
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
99144
 
+         done | \
99145
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
99146
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
99147
 
+       test -z "$(CTAGS_ARGS)$$tags$$unique" \
99148
 
+         || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
99149
 
+            $$tags $$unique
99150
 
+
99151
 
+GTAGS:
99152
 
+       here=`$(am__cd) $(top_builddir) && pwd` \
99153
 
+         && cd $(top_srcdir) \
99154
 
+         && gtags -i $(GTAGS_ARGS) $$here
99155
 
+
99156
 
+distclean-tags:
99157
 
+       -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
99158
 
+
99159
 
+distdir: $(DISTFILES)
99160
 
+       @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
99161
 
+       topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
99162
 
+       list='$(DISTFILES)'; \
99163
 
+         dist_files=`for file in $$list; do echo $$file; done | \
99164
 
+         sed -e "s|^$$srcdirstrip/||;t" \
99165
 
+             -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
99166
 
+       case $$dist_files in \
99167
 
+         */*) $(MKDIR_P) `echo "$$dist_files" | \
99168
 
+                          sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
99169
 
+                          sort -u` ;; \
99170
 
+       esac; \
99171
 
+       for file in $$dist_files; do \
99172
 
+         if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
99173
 
+         if test -d $$d/$$file; then \
99174
 
+           dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
99175
 
+           if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
99176
 
+             cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
99177
 
+           fi; \
99178
 
+           cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
99179
 
+         else \
99180
 
+           test -f $(distdir)/$$file \
99181
 
+           || cp -p $$d/$$file $(distdir)/$$file \
99182
 
+           || exit 1; \
99183
 
+         fi; \
99184
 
+       done
99185
 
+       list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
99186
 
+         if test "$$subdir" = .; then :; else \
99187
 
+           test -d "$(distdir)/$$subdir" \
99188
 
+           || $(MKDIR_P) "$(distdir)/$$subdir" \
99189
 
+           || exit 1; \
99190
 
+           distdir=`$(am__cd) $(distdir) && pwd`; \
99191
 
+           top_distdir=`$(am__cd) $(top_distdir) && pwd`; \
99192
 
+           (cd $$subdir && \
99193
 
+             $(MAKE) $(AM_MAKEFLAGS) \
99194
 
+               top_distdir="$$top_distdir" \
99195
 
+               distdir="$$distdir/$$subdir" \
99196
 
+               am__remove_distdir=: \
99197
 
+               am__skip_length_check=: \
99198
 
+               distdir) \
99199
 
+             || exit 1; \
99200
 
+         fi; \
99201
 
+       done
99202
 
+check-am: all-am
99203
 
+check: check-recursive
99204
 
+all-am: Makefile $(PROGRAMS) $(HEADERS)
99205
 
+installdirs: installdirs-recursive
99206
 
+installdirs-am:
99207
 
+       for dir in "$(DESTDIR)$(bindir)"; do \
99208
 
+         test -z "$$dir" || $(MKDIR_P) "$$dir"; \
99209
 
+       done
99210
 
+install: install-recursive
99211
 
+install-exec: install-exec-recursive
99212
 
+install-data: install-data-recursive
99213
 
+uninstall: uninstall-recursive
99214
 
+
99215
 
+install-am: all-am
99216
 
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
99217
 
+
99218
 
+installcheck: installcheck-recursive
99219
 
+install-strip:
99220
 
+       $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
99221
 
+         install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
99222
 
+         `test -z '$(STRIP)' || \
99223
 
+           echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
99224
 
+mostlyclean-generic:
99225
 
+
99226
 
+clean-generic:
99227
 
+
99228
 
+distclean-generic:
99229
 
+       -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
99230
 
+
99231
 
+maintainer-clean-generic:
99232
 
+       @echo "This command is intended for maintainers to use"
99233
 
+       @echo "it deletes files that may require special tools to rebuild."
99234
 
+clean: clean-recursive
99235
 
+
99236
 
+clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am
99237
 
+
99238
 
+distclean: distclean-recursive
99239
 
+       -rm -rf ./$(DEPDIR)
99240
 
+       -rm -f Makefile
99241
 
+distclean-am: clean-am distclean-compile distclean-generic \
99242
 
+       distclean-tags
99243
 
+
99244
 
+dvi: dvi-recursive
99245
 
+
99246
 
+dvi-am:
99247
 
+
99248
 
+html: html-recursive
99249
 
+
99250
 
+info: info-recursive
99251
 
+
99252
 
+info-am:
99253
 
+
99254
 
+install-data-am:
99255
 
+
99256
 
+install-dvi: install-dvi-recursive
99257
 
+
99258
 
+install-exec-am: install-binPROGRAMS
99259
 
+
99260
 
+install-html: install-html-recursive
99261
 
+
99262
 
+install-info: install-info-recursive
99263
 
+
99264
 
+install-man:
99265
 
+
99266
 
+install-pdf: install-pdf-recursive
99267
 
+
99268
 
+install-ps: install-ps-recursive
99269
 
+
99270
 
+installcheck-am:
99271
 
+
99272
 
+maintainer-clean: maintainer-clean-recursive
99273
 
+       -rm -rf ./$(DEPDIR)
99274
 
+       -rm -f Makefile
99275
 
+maintainer-clean-am: distclean-am maintainer-clean-generic
99276
 
+
99277
 
+mostlyclean: mostlyclean-recursive
99278
 
+
99279
 
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
99280
 
+       mostlyclean-libtool
99281
 
+
99282
 
+pdf: pdf-recursive
99283
 
+
99284
 
+pdf-am:
99285
 
+
99286
 
+ps: ps-recursive
99287
 
+
99288
 
+ps-am:
99289
 
+
99290
 
+uninstall-am: uninstall-binPROGRAMS
99291
 
+
99292
 
+.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) install-am \
99293
 
+       install-strip
99294
 
+
99295
 
+.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
99296
 
+       all all-am check check-am clean clean-binPROGRAMS \
99297
 
+       clean-generic clean-libtool ctags ctags-recursive distclean \
99298
 
+       distclean-compile distclean-generic distclean-libtool \
99299
 
+       distclean-tags distdir dvi dvi-am html html-am info info-am \
99300
 
+       install install-am install-binPROGRAMS install-data \
99301
 
+       install-data-am install-dvi install-dvi-am install-exec \
99302
 
+       install-exec-am install-html install-html-am install-info \
99303
 
+       install-info-am install-man install-pdf install-pdf-am \
99304
 
+       install-ps install-ps-am install-strip installcheck \
99305
 
+       installcheck-am installdirs installdirs-am maintainer-clean \
99306
 
+       maintainer-clean-generic mostlyclean mostlyclean-compile \
99307
 
+       mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
99308
 
+       tags tags-recursive uninstall uninstall-am \
99309
 
+       uninstall-binPROGRAMS
99310
 
+
99311
 
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
99312
 
+# Otherwise a system limit (for SysV at least) may be exceeded.
99313
 
+.NOEXPORT:
99314
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/sieve-tools/sievec.c dovecot-1.2.4.debian/dovecot-libsieve/src/sieve-tools/sievec.c
99315
 
--- dovecot-1.2.4/dovecot-libsieve/src/sieve-tools/sievec.c     1970-01-01 01:00:00.000000000 +0100
99316
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/sieve-tools/sievec.c      2009-08-04 21:31:07.000000000 +0200
99317
 
@@ -0,0 +1,153 @@
99318
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
99319
 
+ */
99320
 
+
99321
 
+#include "lib.h"
99322
 
+
99323
 
+#include "sieve.h"
99324
 
+#include "sieve-extensions.h"
99325
 
+#include "sieve-script.h"
99326
 
+#include "sieve-tool.h"
99327
 
+
99328
 
+#include "sieve-ext-debug.h"
99329
 
+
99330
 
+#include <stdio.h>
99331
 
+#include <sys/types.h>
99332
 
+#include <sys/stat.h>
99333
 
+#include <fcntl.h>
99334
 
+#include <stdlib.h>
99335
 
+#include <unistd.h>
99336
 
+#include <stdio.h>
99337
 
+#include <dirent.h>
99338
 
+
99339
 
+/*
99340
 
+ * Print help
99341
 
+ */
99342
 
+
99343
 
+static void print_help(void)
99344
 
+{
99345
 
+       printf(
99346
 
+"Usage: sievec [-d] [-x <extensions>] <script-file> [<out-file>]\n"
99347
 
+       );
99348
 
+}
99349
 
+
99350
 
+/* 
99351
 
+ * Tool implementation
99352
 
+ */
99353
 
+
99354
 
+int main(int argc, char **argv) {
99355
 
+       int i;
99356
 
+       struct stat st;
99357
 
+       struct sieve_binary *sbin;
99358
 
+       bool dump = FALSE;
99359
 
+       const char *scriptfile, *outfile, *extensions;
99360
 
+               
99361
 
+       sieve_tool_init();      
99362
 
+               
99363
 
+       scriptfile = outfile = extensions = NULL;
99364
 
+       for (i = 1; i < argc; i++) {
99365
 
+               if (strcmp(argv[i], "-d") == 0) {
99366
 
+                       /* dump file */
99367
 
+                       dump = TRUE;
99368
 
+               } else if (strcmp(argv[i], "-x") == 0) {
99369
 
+                       /* extensions */
99370
 
+                       i++;
99371
 
+                       if (i == argc) {
99372
 
+                               print_help();
99373
 
+                               i_fatal("Missing -x argument");
99374
 
+                       }
99375
 
+                       extensions = argv[i];
99376
 
+               } else if ( scriptfile == NULL ) {
99377
 
+                       scriptfile = argv[i];
99378
 
+               } else if ( outfile == NULL ) {
99379
 
+                       outfile = argv[i];
99380
 
+               } else {
99381
 
+                       print_help();
99382
 
+                       i_fatal("Unknown argument: %s", argv[i]);
99383
 
+               }
99384
 
+       }
99385
 
+       
99386
 
+       if ( scriptfile == NULL ) {
99387
 
+               print_help();
99388
 
+               i_fatal("Missing <script-file> argument");
99389
 
+       }
99390
 
+       
99391
 
+       if ( outfile == NULL && dump )
99392
 
+               outfile = "-";
99393
 
+
99394
 
+       if ( extensions != NULL ) {
99395
 
+               sieve_set_extensions(extensions);
99396
 
+       }
99397
 
+
99398
 
+       /* Register tool-specific extensions */
99399
 
+       (void) sieve_extension_register(&debug_extension, TRUE);
99400
 
+
99401
 
+       if ( stat(scriptfile, &st) == 0 && S_ISDIR(st.st_mode) ) {
99402
 
+               /* Script directory */
99403
 
+               DIR *dirp;
99404
 
+               struct dirent *dp;
99405
 
+               
99406
 
+               /* Sanity checks on some of the arguments */
99407
 
+               
99408
 
+               if ( dump )
99409
 
+                       i_fatal("the -d option is not allowed when scriptfile is a directory."); 
99410
 
+               
99411
 
+               if ( outfile != NULL )
99412
 
+                       i_fatal("the outfile argument is not allowed when scriptfile is a "
99413
 
+                               "directory."); 
99414
 
+               
99415
 
+               /* Open the directory */
99416
 
+               if ( (dirp = opendir(scriptfile)) == NULL )
99417
 
+                       i_fatal("opendir(%s) failed: %m", scriptfile);
99418
 
+                       
99419
 
+               /* Compile each sieve file */
99420
 
+               for (;;) {
99421
 
+               
99422
 
+                       errno = 0;
99423
 
+                       if ( (dp = readdir(dirp)) == NULL ) {
99424
 
+                               if ( errno != 0 ) 
99425
 
+                                       i_fatal("readdir(%s) failed: %m", scriptfile);
99426
 
+                               break;
99427
 
+                       }
99428
 
+                                                                                       
99429
 
+                       if ( sieve_script_file_has_extension(dp->d_name) ) {
99430
 
+                               const char *file;
99431
 
+                               
99432
 
+                               if ( scriptfile[strlen(scriptfile)-1] == '/' )
99433
 
+                                       file = t_strconcat(scriptfile, dp->d_name, NULL);
99434
 
+                               else
99435
 
+                                       file = t_strconcat(scriptfile, "/", dp->d_name, NULL);
99436
 
+
99437
 
+                               sbin = sieve_tool_script_compile(file, dp->d_name);
99438
 
+
99439
 
+                               if ( sbin != NULL ) {
99440
 
+                                       sieve_save(sbin, NULL);
99441
 
+               
99442
 
+                                       sieve_close(&sbin);
99443
 
+                               }
99444
 
+                       }
99445
 
+               }
99446
 
+   
99447
 
+               /* Close the directory */
99448
 
+               if ( closedir(dirp) < 0 ) 
99449
 
+                       i_fatal("closedir(%s) failed: %m", scriptfile);
99450
 
+       
99451
 
+       } else {
99452
 
+               /* Script file (i.e. not a directory)
99453
 
+                * 
99454
 
+                *   NOTE: For consistency, stat errors are handled here as well 
99455
 
+                */     
99456
 
+               sbin = sieve_tool_script_compile(scriptfile, NULL);
99457
 
+
99458
 
+               if ( sbin != NULL ) {
99459
 
+                       if ( dump ) 
99460
 
+                               sieve_tool_dump_binary_to(sbin, outfile);
99461
 
+                       else {
99462
 
+                               sieve_save(sbin, outfile);
99463
 
+                       }
99464
 
+               
99465
 
+                       sieve_close(&sbin);
99466
 
+               }
99467
 
+       }
99468
 
+               
99469
 
+       sieve_tool_deinit();
99470
 
+}
99471
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/sieve-tools/sieved.c dovecot-1.2.4.debian/dovecot-libsieve/src/sieve-tools/sieved.c
99472
 
--- dovecot-1.2.4/dovecot-libsieve/src/sieve-tools/sieved.c     1970-01-01 01:00:00.000000000 +0100
99473
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/sieve-tools/sieved.c      2009-08-04 21:31:07.000000000 +0200
99474
 
@@ -0,0 +1,85 @@
99475
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
99476
 
+ */
99477
 
+
99478
 
+#include "lib.h"
99479
 
+
99480
 
+#include "sieve.h"
99481
 
+#include "sieve-extensions.h"
99482
 
+#include "sieve-tool.h"
99483
 
+
99484
 
+#include "sieve-ext-debug.h"
99485
 
+
99486
 
+#include <stdio.h>
99487
 
+#include <sys/types.h>
99488
 
+#include <sys/stat.h>
99489
 
+#include <fcntl.h>
99490
 
+#include <stdlib.h>
99491
 
+#include <unistd.h>
99492
 
+#include <stdio.h>
99493
 
+
99494
 
+/*
99495
 
+ * Print help
99496
 
+ */
99497
 
+
99498
 
+static void print_help(void)
99499
 
+{
99500
 
+       printf(
99501
 
+"Usage: sieved [-x <extensions>] <sieve-binary> [<out-file>]\n"
99502
 
+       );
99503
 
+}
99504
 
+
99505
 
+/*
99506
 
+ * Tool implementation
99507
 
+ */
99508
 
+
99509
 
+int main(int argc, char **argv) {
99510
 
+       int i;
99511
 
+       struct sieve_binary *sbin;
99512
 
+       const char *binfile, *outfile, *extensions;
99513
 
+       
99514
 
+       sieve_tool_init();
99515
 
+       
99516
 
+       binfile = outfile = extensions = NULL;
99517
 
+       for (i = 1; i < argc; i++) {
99518
 
+               if (strcmp(argv[i], "-x") == 0) {
99519
 
+                       /* extensions */
99520
 
+                       i++;
99521
 
+                       if (i == argc) {
99522
 
+                               print_help();
99523
 
+                               i_fatal("Missing -x argument");
99524
 
+                       }
99525
 
+                       extensions = argv[i];
99526
 
+               } else if ( binfile == NULL ) {
99527
 
+                       binfile = argv[i];
99528
 
+               } else if ( outfile == NULL ) {
99529
 
+                       outfile = argv[i];
99530
 
+               } else {
99531
 
+                       print_help();
99532
 
+                       i_fatal("unknown argument: %s", argv[i]);
99533
 
+               }
99534
 
+       }
99535
 
+       
99536
 
+       if ( binfile == NULL ) {
99537
 
+               print_help();
99538
 
+               i_fatal("missing <sieve-binary> argument");
99539
 
+       }
99540
 
+
99541
 
+       if ( extensions != NULL ) {
99542
 
+               sieve_set_extensions(extensions);
99543
 
+       }
99544
 
+
99545
 
+       /* Register tool-specific extensions */
99546
 
+       (void) sieve_extension_register(&debug_extension, TRUE);
99547
 
+               
99548
 
+       sbin = sieve_load(binfile);
99549
 
+
99550
 
+       if ( sbin != NULL ) {
99551
 
+               sieve_tool_dump_binary_to(sbin, outfile == NULL ? "-" : outfile);
99552
 
+       
99553
 
+               sieve_close(&sbin);
99554
 
+       } else 
99555
 
+               i_error("failed to load binary: %s", binfile);
99556
 
+       
99557
 
+       sieve_tool_deinit();
99558
 
+}
99559
 
+
99560
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/sieve-tools/sieve-filter.c dovecot-1.2.4.debian/dovecot-libsieve/src/sieve-tools/sieve-filter.c
99561
 
--- dovecot-1.2.4/dovecot-libsieve/src/sieve-tools/sieve-filter.c       1970-01-01 01:00:00.000000000 +0100
99562
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/sieve-tools/sieve-filter.c        2009-07-27 17:40:27.000000000 +0200
99563
 
@@ -0,0 +1,390 @@
99564
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
99565
 
+ */
99566
 
+
99567
 
+#include "lib.h"
99568
 
+#include "ostream.h"
99569
 
+#include "array.h"
99570
 
+#include "mail-namespace.h"
99571
 
+#include "mail-storage.h"
99572
 
+#include "mail-search-build.h"
99573
 
+#include "env-util.h"
99574
 
+
99575
 
+#include "sieve.h"
99576
 
+#include "sieve-extensions.h"
99577
 
+#include "sieve-binary.h"
99578
 
+
99579
 
+#include "mail-raw.h"
99580
 
+#include "sieve-tool.h"
99581
 
+
99582
 
+#include "sieve-ext-debug.h"
99583
 
+
99584
 
+#include <stdio.h>
99585
 
+#include <stdlib.h>
99586
 
+#include <unistd.h>
99587
 
+#include <fcntl.h>
99588
 
+#include <pwd.h>
99589
 
+
99590
 
+/*
99591
 
+ * Print help
99592
 
+ */
99593
 
+
99594
 
+static void print_help(void)
99595
 
+{
99596
 
+       printf(
99597
 
+"Usage: sieve-filter [-m <mailbox>] [-x <extensions>] [-s <script-file>] [-c]\n"
99598
 
+"                    <script-file> <src-mail-store> [<dest-mail-store>]\n"
99599
 
+       );
99600
 
+}
99601
 
+
99602
 
+enum discard_action_type {
99603
 
+       DISCARD_ACTION_KEEP,            /* Always keep messages in source folder */ 
99604
 
+       DISCARD_ACTION_DELETE,          /* Flag discarded messages as \DELETED */
99605
 
+       DISCARD_ACTION_TRASH_FOLDER,    /* Move discarded messages to Trash folder */      
99606
 
+       DISCARD_ACTION_EXPUNGE          /* Expunge discarded messages */
99607
 
+};
99608
 
+
99609
 
+struct discard_action {
99610
 
+       enum discard_action_type type;
99611
 
+       const char *trash_folder;
99612
 
+};
99613
 
+
99614
 
+static int filter_message
99615
 
+(struct mail *mail, struct sieve_binary *main_sbin, 
99616
 
+       struct sieve_script_env *senv, struct sieve_error_handler *ehandler,
99617
 
+       struct discard_action discard_action)
99618
 
+{
99619
 
+       struct sieve_exec_status estatus;
99620
 
+       struct sieve_binary *sbin;
99621
 
+       struct sieve_message_data msgdata;
99622
 
+       const char *recipient, *sender;
99623
 
+       int ret;
99624
 
+
99625
 
+       sieve_tool_get_envelope_data(mail, &recipient, &sender);
99626
 
+
99627
 
+       /* Initialize execution status */
99628
 
+       memset(&estatus, 0, sizeof(estatus));
99629
 
+       senv->exec_status = &estatus;
99630
 
+
99631
 
+       /* Collect necessary message data */
99632
 
+       memset(&msgdata, 0, sizeof(msgdata));
99633
 
+       msgdata.mail = mail;
99634
 
+       msgdata.return_path = sender;
99635
 
+       msgdata.to_address = recipient;
99636
 
+       msgdata.auth_user = senv->username;
99637
 
+       (void)mail_get_first_header(mail, "Message-ID", &msgdata.id);
99638
 
+
99639
 
+       /* Single script */
99640
 
+       sbin = main_sbin;
99641
 
+       main_sbin = NULL;
99642
 
+
99643
 
+       /* Execute script */
99644
 
+       ret = sieve_execute(sbin, &msgdata, senv, ehandler, NULL);
99645
 
+
99646
 
+       /* Handle message in source folder */
99647
 
+       if ( ret > 0 && !estatus.keep_original ) {
99648
 
+               switch ( discard_action.type ) {
99649
 
+               /* Leave it there */
99650
 
+               case DISCARD_ACTION_KEEP:
99651
 
+                       sieve_info(ehandler, NULL, "message left in source folder");
99652
 
+                       break;
99653
 
+               /* Flag message as \DELETED */
99654
 
+               case DISCARD_ACTION_DELETE:                                     
99655
 
+                       sieve_info(ehandler, NULL, "message flagged as deleted in source folder");
99656
 
+                       mail_update_flags(mail, MODIFY_ADD, MAIL_DELETED);
99657
 
+                       break;
99658
 
+               /* Move message to Trash folder */
99659
 
+               case DISCARD_ACTION_TRASH_FOLDER:                       
99660
 
+                       sieve_info(ehandler, NULL, 
99661
 
+                               "message in source folder moved to folder '%s'", 
99662
 
+                               discard_action.trash_folder);
99663
 
+                       break;
99664
 
+               /* Expunge the message immediately */
99665
 
+               case DISCARD_ACTION_EXPUNGE:
99666
 
+                       sieve_info(ehandler, NULL, "message removed from source folder");
99667
 
+                       mail_expunge(mail);
99668
 
+                       break;
99669
 
+               /* Unknown */
99670
 
+               default:
99671
 
+                       i_unreached();
99672
 
+                       break;
99673
 
+               }
99674
 
+       }
99675
 
+
99676
 
+       return ret;
99677
 
+}
99678
 
+
99679
 
+/* FIXME: introduce this into Dovecot */
99680
 
+static void mail_search_build_add_flags
99681
 
+(struct mail_search_args *args, enum mail_flags flags, bool not)
99682
 
+{
99683
 
+       struct mail_search_arg *arg;
99684
 
+
99685
 
+       arg = p_new(args->pool, struct mail_search_arg, 1);
99686
 
+       arg->type = SEARCH_FLAGS;
99687
 
+       arg->value.flags = flags;
99688
 
+       arg->not = not;
99689
 
+
99690
 
+       arg->next = args->args;
99691
 
+       args->args = arg;
99692
 
+}
99693
 
+
99694
 
+static int filter_mailbox
99695
 
+(struct mailbox *box, struct sieve_binary *main_sbin, 
99696
 
+       struct sieve_script_env *senv, struct sieve_error_handler *ehandler,
99697
 
+       struct discard_action discard_action)
99698
 
+{
99699
 
+       struct mail_search_args *search_args;
99700
 
+       struct mailbox_transaction_context *t;
99701
 
+       struct mail_search_context *search_ctx;
99702
 
+       struct mail *mail;
99703
 
+       int ret = 1;
99704
 
+
99705
 
+       /* Sync mailbox */
99706
 
+
99707
 
+       if ( mailbox_sync(box, MAILBOX_SYNC_FLAG_FULL_READ, 0, NULL) < 0 ) {
99708
 
+               return -1;
99709
 
+       }
99710
 
+
99711
 
+       /* Search non-deleted messages in the source folder */
99712
 
+
99713
 
+       search_args = mail_search_build_init();
99714
 
+       mail_search_build_add_flags(search_args, MAIL_DELETED, TRUE);
99715
 
+
99716
 
+       /* Iterate through all requested messages */
99717
 
+
99718
 
+       t = mailbox_transaction_begin(box, 0);
99719
 
+       search_ctx = mailbox_search_init(t, search_args, NULL);
99720
 
+       mail_search_args_unref(&search_args);
99721
 
+
99722
 
+       mail = mail_alloc(t, 0, NULL);
99723
 
+       while ( ret > 0 && mailbox_search_next(search_ctx, mail) > 0 ) {
99724
 
+               const char *subject, *date;
99725
 
+               uoff_t size = 0;
99726
 
+                                       
99727
 
+               /* Request message size */
99728
 
+
99729
 
+               if ( mail_get_virtual_size(mail, &size) < 0 ) {
99730
 
+                       if ( mail->expunged )
99731
 
+                               continue;
99732
 
+                       
99733
 
+                       sieve_error(ehandler, NULL, "failed to obtain message size");
99734
 
+                       continue;
99735
 
+               }
99736
 
+
99737
 
+               if ( mail_get_first_header(mail, "date", &date) <= 0 )
99738
 
+                       date = "";
99739
 
+               if ( mail_get_first_header(mail, "subject", &subject) <= 0 ) 
99740
 
+                       subject = "";
99741
 
+               
99742
 
+               sieve_info(ehandler, NULL,
99743
 
+                       "filtering: [%s; %"PRIuUOFF_T" bytes] %s", date, size, subject);
99744
 
+       
99745
 
+               ret = filter_message(mail, main_sbin, senv, ehandler, discard_action);
99746
 
+       }
99747
 
+       mail_free(&mail);
99748
 
+       
99749
 
+       /* Cleanup */
99750
 
+
99751
 
+       if ( mailbox_search_deinit(&search_ctx) < 0 ) {
99752
 
+               ret = -1;
99753
 
+       }
99754
 
+
99755
 
+       if ( ret < 0 ) {
99756
 
+               mailbox_transaction_rollback(&t);
99757
 
+               return -1;
99758
 
+       } else {
99759
 
+               if ( mailbox_transaction_commit(&t) < 0 ) {
99760
 
+                       return -1;
99761
 
+               }
99762
 
+       }
99763
 
+
99764
 
+       /* Sync mailbox */
99765
 
+
99766
 
+       if ( mailbox_sync(box, MAILBOX_SYNC_FLAG_FULL_WRITE, 0, NULL) < 0 ) {
99767
 
+               return -1;
99768
 
+       }
99769
 
+       
99770
 
+       return ret;
99771
 
+}
99772
 
+
99773
 
+/*
99774
 
+ * Tool implementation
99775
 
+ */
99776
 
+
99777
 
+int main(int argc, char **argv) 
99778
 
+{
99779
 
+       const char *scriptfile, *recipient, *sender, *extensions,
99780
 
+               *src_mailbox, *dst_mailbox, *src_mailstore, *dst_mailstore; 
99781
 
+       bool force_compile;
99782
 
+       struct mail_namespace *src_ns = NULL, *dst_ns = NULL;
99783
 
+       struct mail_user *mail_user = NULL;
99784
 
+       struct sieve_binary *main_sbin;
99785
 
+       struct sieve_script_env scriptenv;
99786
 
+       struct sieve_error_handler *ehandler;
99787
 
+       struct mail_storage *dst_storage, *src_storage;
99788
 
+       struct discard_action discard_action = 
99789
 
+               { DISCARD_ACTION_KEEP, "Trash" };
99790
 
+       struct mailbox *src_box;
99791
 
+       enum mail_error error;
99792
 
+       enum mailbox_open_flags open_flags = 
99793
 
+               MAILBOX_OPEN_KEEP_RECENT | MAILBOX_OPEN_IGNORE_ACLS;
99794
 
+       const char *user, *home, *folder;
99795
 
+       int i;
99796
 
+
99797
 
+       sieve_tool_init();
99798
 
+       
99799
 
+       /* Parse arguments */
99800
 
+       scriptfile = recipient = sender = extensions = src_mailstore = dst_mailstore 
99801
 
+               = NULL;
99802
 
+       src_mailbox = dst_mailbox = "INBOX";
99803
 
+       force_compile = FALSE;
99804
 
+       for (i = 1; i < argc; i++) {
99805
 
+               if (strcmp(argv[i], "-m") == 0) {
99806
 
+                       /* default mailbox (keep box) */
99807
 
+                       i++;
99808
 
+                       if (i == argc) 
99809
 
+                               i_fatal("Missing -m argument");
99810
 
+                       dst_mailbox = argv[i];
99811
 
+               } else if (strcmp(argv[i], "-x") == 0) {
99812
 
+                       /* extensions */
99813
 
+                       i++;
99814
 
+                       if (i == argc)
99815
 
+                               i_fatal("Missing -x argument");
99816
 
+                       extensions = argv[i];
99817
 
+               } else if (strcmp(argv[i], "-c") == 0) {
99818
 
+                       /* force compile */
99819
 
+                       force_compile = TRUE;
99820
 
+               } else if ( scriptfile == NULL ) {
99821
 
+                       scriptfile = argv[i];
99822
 
+               } else if ( src_mailstore == NULL ) {
99823
 
+                       src_mailstore = argv[i];
99824
 
+               } else if ( dst_mailstore == NULL ) {
99825
 
+                       dst_mailstore = argv[i];
99826
 
+               } else {
99827
 
+                       print_help();
99828
 
+                       i_fatal("Unknown argument: %s", argv[i]);
99829
 
+               }
99830
 
+       }
99831
 
+       
99832
 
+       if ( scriptfile == NULL ) {
99833
 
+               print_help();
99834
 
+               i_fatal("Missing <scriptfile> argument");
99835
 
+       }
99836
 
+       
99837
 
+       if ( src_mailstore == NULL ) {
99838
 
+               print_help();
99839
 
+               i_fatal("Missing <mailstore> argument");
99840
 
+       }
99841
 
+
99842
 
+       if ( extensions != NULL ) {
99843
 
+               sieve_set_extensions(extensions);
99844
 
+       }
99845
 
+
99846
 
+       /* Register tool-specific extensions */
99847
 
+       (void) sieve_extension_register(&debug_extension, TRUE);
99848
 
+
99849
 
+       /* Create error handler */
99850
 
+       ehandler = sieve_stderr_ehandler_create(0);
99851
 
+       sieve_system_ehandler_set(ehandler);
99852
 
+       sieve_error_handler_accept_infolog(ehandler, TRUE);
99853
 
+
99854
 
+       /* Compile main sieve script */
99855
 
+       if ( force_compile ) {
99856
 
+               main_sbin = sieve_tool_script_compile(scriptfile, NULL);
99857
 
+               (void) sieve_save(main_sbin, NULL);
99858
 
+       } else {
99859
 
+               main_sbin = sieve_tool_script_open(scriptfile);
99860
 
+       }
99861
 
+       
99862
 
+       user = sieve_tool_get_user();
99863
 
+       home = getenv("HOME");
99864
 
+
99865
 
+       /* Initialize mail storages */
99866
 
+       mail_users_init(getenv("AUTH_SOCKET_PATH"), getenv("DEBUG") != NULL);
99867
 
+       mail_storage_init();
99868
 
+       mail_storage_register_all();
99869
 
+       mailbox_list_register_all();
99870
 
+
99871
 
+       /* Build namespaces environment (ugly!) */
99872
 
+       env_put(t_strdup_printf("NAMESPACE_1=%s", src_mailstore));
99873
 
+       env_put("NAMESPACE_1_INBOX=1");
99874
 
+       env_put("NAMESPACE_1_LIST=1");
99875
 
+       env_put("NAMESPACE_1_SEP=/");
99876
 
+       env_put("NAMESPACE_1_SUBSCRIPTIONS=1");
99877
 
+
99878
 
+       if ( dst_mailstore != NULL ) {
99879
 
+               env_put(t_strdup_printf("NAMESPACE_2=%s", dst_mailstore));
99880
 
+               env_put("NAMESPACE_2_LIST=1");
99881
 
+               env_put("NAMESPACE_2_SEP=/");
99882
 
+               env_put("NAMESPACE_2_SUBSCRIPTIONS=1");
99883
 
+
99884
 
+               env_put("NAMESPACE_1_PREFIX=#src/");
99885
 
+       }
99886
 
+
99887
 
+       /* Initialize namespaces */
99888
 
+       mail_user = mail_user_init(user);
99889
 
+       mail_user_set_home(mail_user, home);
99890
 
+       if (mail_namespaces_init(mail_user) < 0)
99891
 
+               i_fatal("Namespace initialization failed");     
99892
 
+
99893
 
+       if ( dst_mailstore != NULL ) {
99894
 
+               folder = "#src/";
99895
 
+               src_ns = mail_namespace_find(mail_user->namespaces, &folder);
99896
 
+
99897
 
+               folder = "/";
99898
 
+               dst_ns = mail_namespace_find(mail_user->namespaces, &folder);   
99899
 
+
99900
 
+               discard_action.type = DISCARD_ACTION_KEEP;      
99901
 
+       } else {
99902
 
+               dst_ns = src_ns = mail_user->namespaces;
99903
 
+               discard_action.type = DISCARD_ACTION_DELETE;    
99904
 
+       }
99905
 
+
99906
 
+       src_storage = src_ns->storage;
99907
 
+       dst_storage = dst_ns->storage;
99908
 
+
99909
 
+       /* Open the source mailbox */   
99910
 
+       src_box = mailbox_open(&src_storage, src_mailbox, NULL, open_flags);
99911
 
+       if ( src_box == NULL ) {
99912
 
+               i_fatal("Couldn't open mailbox '%s': %s", 
99913
 
+                       src_mailbox, mail_storage_get_last_error(src_storage, &error));
99914
 
+       }
99915
 
+
99916
 
+       /* Compose script environment */
99917
 
+       memset(&scriptenv, 0, sizeof(scriptenv));
99918
 
+       scriptenv.mailbox_autocreate = TRUE;
99919
 
+       scriptenv.default_mailbox = dst_mailbox;
99920
 
+       scriptenv.namespaces = dst_ns;
99921
 
+       scriptenv.username = user;
99922
 
+       scriptenv.hostname = "host.example.com";
99923
 
+       scriptenv.postmaster_address = "postmaster@example.com";
99924
 
+       scriptenv.smtp_open = NULL;
99925
 
+       scriptenv.smtp_close = NULL;
99926
 
+       scriptenv.duplicate_mark = NULL;
99927
 
+       scriptenv.duplicate_check = NULL;
99928
 
+       scriptenv.trace_stream = NULL;
99929
 
+
99930
 
+       /* Apply Sieve filter to all messages found */
99931
 
+       (void) filter_mailbox
99932
 
+               (src_box, main_sbin, &scriptenv, ehandler, discard_action);
99933
 
+       
99934
 
+       /* Close the mailbox */
99935
 
+       if ( src_box != NULL )
99936
 
+               mailbox_close(&src_box);
99937
 
+
99938
 
+       /* Cleanup error handler */
99939
 
+       sieve_error_handler_unref(&ehandler);
99940
 
+       sieve_system_ehandler_reset();  
99941
 
+
99942
 
+       /* De-initialize mail user object */
99943
 
+       if ( mail_user != NULL )
99944
 
+               mail_user_unref(&mail_user);
99945
 
+
99946
 
+       /* De-initialize mail storages */
99947
 
+       mail_storage_deinit();
99948
 
+       mail_users_deinit();    
99949
 
+       
99950
 
+       sieve_tool_deinit();
99951
 
+       
99952
 
+       return 0;
99953
 
+}
99954
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/sieve-tools/sieve-test.c dovecot-1.2.4.debian/dovecot-libsieve/src/sieve-tools/sieve-test.c
99955
 
--- dovecot-1.2.4/dovecot-libsieve/src/sieve-tools/sieve-test.c 1970-01-01 01:00:00.000000000 +0100
99956
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/sieve-tools/sieve-test.c  2009-08-04 21:31:07.000000000 +0200
99957
 
@@ -0,0 +1,417 @@
99958
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
99959
 
+ */
99960
 
+
99961
 
+#include "lib.h"
99962
 
+#include "ostream.h"
99963
 
+#include "array.h"
99964
 
+#include "mail-namespace.h"
99965
 
+#include "mail-storage.h"
99966
 
+#include "env-util.h"
99967
 
+
99968
 
+#include "sieve.h"
99969
 
+#include "sieve-binary.h"
99970
 
+#include "sieve-extensions.h"
99971
 
+
99972
 
+#include "mail-raw.h"
99973
 
+#include "sieve-tool.h"
99974
 
+
99975
 
+#include "sieve-ext-debug.h"
99976
 
+
99977
 
+#include <stdio.h>
99978
 
+#include <stdlib.h>
99979
 
+#include <unistd.h>
99980
 
+#include <fcntl.h>
99981
 
+#include <pwd.h>
99982
 
+
99983
 
+/* 
99984
 
+ * Configuration
99985
 
+ */
99986
 
+
99987
 
+#define DEFAULT_SENDMAIL_PATH "/usr/lib/sendmail"
99988
 
+#define DEFAULT_ENVELOPE_SENDER "MAILER-DAEMON"
99989
 
+
99990
 
+/*
99991
 
+ * Print help
99992
 
+ */
99993
 
+
99994
 
+static void print_help(void)
99995
 
+{
99996
 
+       printf(
99997
 
+"Usage: sieve-test [-c] [-d <dump-filename>] [-e] [-f <envelope-sender>]\n"
99998
 
+"                  [-l <mail-location>] [-m <default-mailbox>]\n" 
99999
 
+"                  [-r <recipient-address>] [-s <script-file>]\n"
100000
 
+"                  [-t] [-x <extensions>] <script-file> <mail-file>\n"
100001
 
+       );
100002
 
+}
100003
 
+
100004
 
+/*
100005
 
+ * Dummy SMTP session
100006
 
+ */
100007
 
+
100008
 
+static void *sieve_smtp_open(const char *destination,
100009
 
+       const char *return_path, FILE **file_r)
100010
 
+{
100011
 
+       i_info("sending message from <%s> to <%s>:",
100012
 
+               ( return_path == NULL ? "" : return_path ), destination);
100013
 
+       printf("\nSTART MESSAGE:\n");
100014
 
+       
100015
 
+       *file_r = stdout;
100016
 
+       
100017
 
+       return NULL;    
100018
 
+}
100019
 
+
100020
 
+static bool sieve_smtp_close(void *handle ATTR_UNUSED)
100021
 
+{
100022
 
+       printf("END MESSAGE\n\n");
100023
 
+       return TRUE;
100024
 
+}
100025
 
+
100026
 
+/*
100027
 
+ * Dummy duplicate check implementation
100028
 
+ */
100029
 
+
100030
 
+static int duplicate_check(const void *id ATTR_UNUSED, size_t id_size ATTR_UNUSED, 
100031
 
+       const char *user)
100032
 
+{
100033
 
+       i_info("checked duplicate for user %s.\n", user);
100034
 
+       return 0;
100035
 
+}
100036
 
+
100037
 
+static void duplicate_mark
100038
 
+(const void *id ATTR_UNUSED, size_t id_size ATTR_UNUSED, const char *user, 
100039
 
+       time_t time ATTR_UNUSED)
100040
 
+{
100041
 
+       i_info("marked duplicate for user %s.\n", user);
100042
 
+}
100043
 
+
100044
 
+/*
100045
 
+ * Tool implementation
100046
 
+ */
100047
 
+
100048
 
+int main(int argc, char **argv) 
100049
 
+{
100050
 
+       ARRAY_DEFINE(scriptfiles, const char *);
100051
 
+       const char *scriptfile, *recipient, *sender, *mailbox, *dumpfile, *mailfile, 
100052
 
+               *mailloc, *extensions; 
100053
 
+       const char *user, *home;
100054
 
+       int i;
100055
 
+       struct mail_raw *mailr;
100056
 
+       struct mail_namespace *ns = NULL;
100057
 
+       struct mail_user *mail_user = NULL;
100058
 
+       struct sieve_binary *main_sbin, *sbin = NULL;
100059
 
+       struct sieve_message_data msgdata;
100060
 
+       struct sieve_script_env scriptenv;
100061
 
+       struct sieve_exec_status estatus;
100062
 
+       struct sieve_error_handler *ehandler;
100063
 
+       struct ostream *teststream = NULL;
100064
 
+       bool force_compile = FALSE, execute = FALSE;
100065
 
+       bool trace = FALSE;
100066
 
+       int ret;
100067
 
+
100068
 
+       sieve_tool_init();
100069
 
+       
100070
 
+       t_array_init(&scriptfiles, 16);
100071
 
+
100072
 
+       /* Parse arguments (ugly) */
100073
 
+       scriptfile = recipient = sender = mailbox = dumpfile = mailfile = mailloc = 
100074
 
+               extensions = NULL;
100075
 
+       for (i = 1; i < argc; i++) {
100076
 
+               if (strcmp(argv[i], "-r") == 0) {
100077
 
+                       /* recipient address */
100078
 
+                       i++;
100079
 
+                       if (i == argc) {
100080
 
+                               print_help();
100081
 
+                               i_fatal("Missing -r argument");
100082
 
+                       }
100083
 
+                       recipient = argv[i];
100084
 
+               } else if (strcmp(argv[i], "-f") == 0) {
100085
 
+                       /* envelope sender */
100086
 
+                       i++;
100087
 
+                       if (i == argc) {
100088
 
+                               print_help();
100089
 
+                               i_fatal("Missing -f argument");
100090
 
+                       }
100091
 
+                       sender = argv[i];
100092
 
+               } else if (strcmp(argv[i], "-m") == 0) {
100093
 
+                       /* default mailbox (keep box) */
100094
 
+                       i++;
100095
 
+                       if (i == argc) {
100096
 
+                               print_help();
100097
 
+                               i_fatal("Missing -m argument");
100098
 
+                       }
100099
 
+                       mailbox = argv[i];
100100
 
+               } else if (strcmp(argv[i], "-d") == 0) {
100101
 
+                       /* dump file */
100102
 
+                       i++;
100103
 
+                       if (i == argc) {
100104
 
+                               print_help();
100105
 
+                               i_fatal("Missing -d argument");
100106
 
+                       }
100107
 
+                       dumpfile = argv[i];
100108
 
+               } else if (strcmp(argv[i], "-l") == 0) {
100109
 
+                       /* mail location */
100110
 
+                       i++;
100111
 
+                       if (i == argc) {
100112
 
+                               print_help();
100113
 
+                               i_fatal("Missing -l argument");
100114
 
+                       }
100115
 
+                       mailloc = argv[i];
100116
 
+               } else if (strcmp(argv[i], "-x") == 0) {
100117
 
+                       /* extensions */
100118
 
+                       i++;
100119
 
+                       if (i == argc) {
100120
 
+                               print_help();
100121
 
+                               i_fatal("Missing -x argument");
100122
 
+                       }
100123
 
+                       extensions = argv[i];
100124
 
+               } else if (strcmp(argv[i], "-s") == 0) {
100125
 
+                       const char *file;
100126
 
+                       
100127
 
+                       /* scriptfile executed before main script */
100128
 
+                       i++;
100129
 
+                       if (i == argc) {
100130
 
+                               print_help();
100131
 
+                               i_fatal("Missing -s argument");
100132
 
+                       }
100133
 
+                               
100134
 
+                       file = t_strdup(argv[i]);
100135
 
+                       array_append(&scriptfiles, &file, 1);
100136
 
+               } else if (strcmp(argv[i], "-c") == 0) {
100137
 
+                       /* force compile */
100138
 
+                       force_compile = TRUE;
100139
 
+               } else if (strcmp(argv[i], "-e") == 0) {
100140
 
+                       /* execute */
100141
 
+                       execute = TRUE;
100142
 
+#ifdef SIEVE_RUNTIME_TRACE
100143
 
+               } else if (strcmp(argv[i], "-t") == 0) {
100144
 
+                       /* runtime trace */
100145
 
+                       trace = TRUE;
100146
 
+#endif
100147
 
+               } else if ( scriptfile == NULL ) {
100148
 
+                       scriptfile = argv[i];
100149
 
+               } else if ( mailfile == NULL ) {
100150
 
+                       mailfile = argv[i];
100151
 
+               } else {
100152
 
+                       print_help();
100153
 
+                       i_fatal("Unknown argument: %s", argv[i]);
100154
 
+               }
100155
 
+       }
100156
 
+       
100157
 
+       if ( scriptfile == NULL ) {
100158
 
+               print_help();
100159
 
+               i_fatal("Missing <script-file> argument");
100160
 
+       }
100161
 
+       
100162
 
+       if ( mailfile == NULL ) {
100163
 
+               print_help();
100164
 
+               i_fatal("Missing <mail-file> argument");
100165
 
+       }
100166
 
+
100167
 
+       if ( extensions != NULL ) {
100168
 
+               sieve_set_extensions(extensions);
100169
 
+       }
100170
 
+
100171
 
+       /* Register tool-specific extensions */
100172
 
+       (void) sieve_extension_register(&debug_extension, TRUE);
100173
 
+       
100174
 
+       /* Create error handler */
100175
 
+       ehandler = sieve_stderr_ehandler_create(0);
100176
 
+       sieve_system_ehandler_set(ehandler);
100177
 
+       sieve_error_handler_accept_infolog(ehandler, TRUE);
100178
 
+
100179
 
+       /* Compile main sieve script */
100180
 
+       if ( force_compile ) {
100181
 
+               main_sbin = sieve_tool_script_compile(scriptfile, NULL);
100182
 
+               (void) sieve_save(main_sbin, NULL);
100183
 
+       } else {
100184
 
+               main_sbin = sieve_tool_script_open(scriptfile);
100185
 
+       }
100186
 
+
100187
 
+       if ( main_sbin != NULL ) {
100188
 
+               /* Dump script */
100189
 
+               sieve_tool_dump_binary_to(main_sbin, dumpfile);
100190
 
+       
100191
 
+               user = sieve_tool_get_user();
100192
 
+               home = getenv("HOME");
100193
 
+
100194
 
+               /* Initialize mail storages */
100195
 
+               mail_users_init(getenv("AUTH_SOCKET_PATH"), getenv("DEBUG") != NULL);
100196
 
+               mail_storage_init();
100197
 
+               mail_storage_register_all();
100198
 
+               mailbox_list_register_all();
100199
 
+       
100200
 
+               /* Obtain mail namespaces from -l argument */
100201
 
+               if ( mailloc != NULL ) {
100202
 
+                       env_put(t_strdup_printf("NAMESPACE_1=%s", mailloc));
100203
 
+                       env_put("NAMESPACE_1_INBOX=1");
100204
 
+                       env_put("NAMESPACE_1_LIST=1");
100205
 
+                       env_put("NAMESPACE_1_SEP=.");
100206
 
+                       env_put("NAMESPACE_1_SUBSCRIPTIONS=1");
100207
 
+
100208
 
+                       mail_user = mail_user_init(user);
100209
 
+                       mail_user_set_home(mail_user, home);
100210
 
+                       if (mail_namespaces_init(mail_user) < 0)
100211
 
+                               i_fatal("Namespace initialization failed");     
100212
 
+
100213
 
+                       ns = mail_user->namespaces;
100214
 
+               }
100215
 
+
100216
 
+               /* Initialize raw mail object */
100217
 
+               mail_raw_init(user);
100218
 
+               mailr = mail_raw_open_file(mailfile);
100219
 
+
100220
 
+               sieve_tool_get_envelope_data(mailr->mail, &recipient, &sender);
100221
 
+
100222
 
+               if ( mailbox == NULL )
100223
 
+                       mailbox = "INBOX";
100224
 
+
100225
 
+               /* Collect necessary message data */
100226
 
+               memset(&msgdata, 0, sizeof(msgdata));
100227
 
+               msgdata.mail = mailr->mail;
100228
 
+               msgdata.return_path = sender;
100229
 
+               msgdata.to_address = recipient;
100230
 
+               msgdata.auth_user = user;
100231
 
+               (void)mail_get_first_header(mailr->mail, "Message-ID", &msgdata.id);
100232
 
+
100233
 
+               /* Create stream for test and trace output */
100234
 
+               if ( !execute || trace )
100235
 
+                       teststream = o_stream_create_fd(1, 0, FALSE);   
100236
 
+               
100237
 
+               /* Compose script environment */
100238
 
+               memset(&scriptenv, 0, sizeof(scriptenv));
100239
 
+               scriptenv.default_mailbox = "INBOX";
100240
 
+               scriptenv.namespaces = ns;
100241
 
+               scriptenv.username = user;
100242
 
+               scriptenv.hostname = "host.example.com";
100243
 
+               scriptenv.postmaster_address = "postmaster@example.com";
100244
 
+               scriptenv.smtp_open = sieve_smtp_open;
100245
 
+               scriptenv.smtp_close = sieve_smtp_close;
100246
 
+               scriptenv.duplicate_mark = duplicate_mark;
100247
 
+               scriptenv.duplicate_check = duplicate_check;
100248
 
+               scriptenv.trace_stream = ( trace ? teststream : NULL );
100249
 
+               scriptenv.exec_status = &estatus;
100250
 
+       
100251
 
+               /* Run the test */
100252
 
+               ret = 1;
100253
 
+               if ( array_count(&scriptfiles) == 0 ) {
100254
 
+                       /* Single script */
100255
 
+                       sbin = main_sbin;
100256
 
+                       main_sbin = NULL;
100257
 
+       
100258
 
+                       /* Execute/Test script */
100259
 
+                       if ( execute )
100260
 
+                               ret = sieve_execute
100261
 
+                                       (sbin, &msgdata, &scriptenv, ehandler, NULL);
100262
 
+                       else
100263
 
+                               ret = sieve_test
100264
 
+                                       (sbin, &msgdata, &scriptenv, ehandler, teststream, NULL);                               
100265
 
+               } else {
100266
 
+                       /* Multiple scripts */
100267
 
+                       const char *const *sfiles;
100268
 
+                       unsigned int i, count;
100269
 
+                       struct sieve_multiscript *mscript;
100270
 
+                       bool more = TRUE;
100271
 
+                       int result;
100272
 
+
100273
 
+                       if ( execute )
100274
 
+                               mscript = sieve_multiscript_start_execute
100275
 
+                                       (&msgdata, &scriptenv);
100276
 
+                       else
100277
 
+                               mscript = sieve_multiscript_start_test
100278
 
+                                       (&msgdata, &scriptenv, teststream);
100279
 
+               
100280
 
+                       /* Execute scripts sequentially */
100281
 
+                       sfiles = array_get(&scriptfiles, &count); 
100282
 
+                       for ( i = 0; i < count && more; i++ ) {
100283
 
+                               if ( teststream != NULL ) 
100284
 
+                                       o_stream_send_str(teststream, 
100285
 
+                                               t_strdup_printf("\n## Executing script: %s\n", sfiles[i]));
100286
 
+                       
100287
 
+                               /* Close previous script */
100288
 
+                               if ( sbin != NULL )                                             
100289
 
+                                       sieve_close(&sbin);
100290
 
+               
100291
 
+                               /* Compile sieve script */
100292
 
+                               if ( force_compile ) {
100293
 
+                                       sbin = sieve_tool_script_compile(sfiles[i], sfiles[i]);
100294
 
+                                       (void) sieve_save(sbin, NULL);
100295
 
+                               } else {
100296
 
+                                       sbin = sieve_tool_script_open(sfiles[i]);
100297
 
+                               }
100298
 
+                       
100299
 
+                               if ( sbin == NULL ) {
100300
 
+                                       ret = SIEVE_EXEC_FAILURE;
100301
 
+                                       break;
100302
 
+                               }
100303
 
+                       
100304
 
+                               /* Execute/Test script */
100305
 
+                               more = sieve_multiscript_run(mscript, sbin, ehandler, FALSE);
100306
 
+                       }
100307
 
+               
100308
 
+                       /* Execute/Test main script */
100309
 
+                       if ( more && ret > 0 ) {
100310
 
+                               if ( teststream != NULL ) 
100311
 
+                                       o_stream_send_str(teststream, 
100312
 
+                                               t_strdup_printf("## Executing script: %s\n", scriptfile));
100313
 
+                               
100314
 
+                               /* Close previous script */
100315
 
+                               if ( sbin != NULL )                                             
100316
 
+                                       sieve_close(&sbin);     
100317
 
+                               
100318
 
+                               sbin = main_sbin;
100319
 
+                               main_sbin = NULL;
100320
 
+                       
100321
 
+                               sieve_multiscript_run(mscript, sbin, ehandler, TRUE);
100322
 
+                       }
100323
 
+                       
100324
 
+                       result = sieve_multiscript_finish(&mscript, ehandler, NULL);
100325
 
+                       
100326
 
+                       ret = ret > 0 ? result : ret;
100327
 
+               }
100328
 
+       
100329
 
+               /* Run */
100330
 
+               switch ( ret ) {
100331
 
+               case SIEVE_EXEC_OK:
100332
 
+                       i_info("final result: success");
100333
 
+                       break;
100334
 
+               case SIEVE_EXEC_BIN_CORRUPT:
100335
 
+                       i_info("corrupt binary deleted.");
100336
 
+                       (void) unlink(sieve_binary_path(sbin));
100337
 
+               case SIEVE_EXEC_FAILURE:
100338
 
+                       i_info("final result: failed; resolved with successful implicit keep");
100339
 
+                       break;
100340
 
+               case SIEVE_EXEC_KEEP_FAILED:
100341
 
+                       i_info("final result: utter failure");
100342
 
+                       break;
100343
 
+               default:
100344
 
+                       i_info("final result: unrecognized return value?!");    
100345
 
+               }
100346
 
+
100347
 
+               if ( teststream != NULL )
100348
 
+                       o_stream_destroy(&teststream);
100349
 
+
100350
 
+               /* Cleanup remaining binaries */
100351
 
+               sieve_close(&sbin);
100352
 
+               if ( main_sbin != NULL ) sieve_close(&main_sbin);
100353
 
+               
100354
 
+               /* De-initialize raw mail object */
100355
 
+               mail_raw_close(mailr);
100356
 
+               mail_raw_deinit();
100357
 
+
100358
 
+               /* De-initialize mail user object */
100359
 
+               if ( mail_user != NULL )
100360
 
+                       mail_user_unref(&mail_user);
100361
 
+
100362
 
+               /* De-initialize mail storages */
100363
 
+               mail_storage_deinit();
100364
 
+               mail_users_deinit();
100365
 
+       }
100366
 
+
100367
 
+       /* Cleanup error handler */
100368
 
+       sieve_error_handler_unref(&ehandler);
100369
 
+       sieve_system_ehandler_reset();
100370
 
+
100371
 
+       sieve_tool_deinit();
100372
 
+       
100373
 
+       return 0;
100374
 
+}
100375
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/testsuite/cmd-test-binary.c dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/cmd-test-binary.c
100376
 
--- dovecot-1.2.4/dovecot-libsieve/src/testsuite/cmd-test-binary.c      1970-01-01 01:00:00.000000000 +0100
100377
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/cmd-test-binary.c       2009-08-21 00:52:15.000000000 +0200
100378
 
@@ -0,0 +1,269 @@
100379
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
100380
 
+ */
100381
 
+
100382
 
+#include "sieve-common.h"
100383
 
+#include "sieve-commands.h"
100384
 
+#include "sieve-validator.h"
100385
 
+#include "sieve-generator.h"
100386
 
+#include "sieve-interpreter.h"
100387
 
+#include "sieve-code.h"
100388
 
+#include "sieve-binary.h"
100389
 
+#include "sieve-dump.h"
100390
 
+
100391
 
+#include "testsuite-common.h"
100392
 
+#include "testsuite-binary.h"
100393
 
+#include "testsuite-script.h"
100394
 
+
100395
 
+/*
100396
 
+ * Test_binary command
100397
 
+ *
100398
 
+ * Syntax:   
100399
 
+ *   test_binary ( :load / :save ) <mailbox: string>
100400
 
+ */
100401
 
+
100402
 
+static bool cmd_test_binary_registered
100403
 
+       (struct sieve_validator *valdtr, 
100404
 
+               struct sieve_command_registration *cmd_reg);
100405
 
+static bool cmd_test_binary_validate
100406
 
+       (struct sieve_validator *valdtr, struct sieve_command_context *cmd);
100407
 
+static bool cmd_test_binary_generate
100408
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx);
100409
 
+
100410
 
+const struct sieve_command cmd_test_binary = { 
100411
 
+       "test_binary", 
100412
 
+       SCT_COMMAND, 
100413
 
+       1, 0, FALSE, FALSE,
100414
 
+       cmd_test_binary_registered, 
100415
 
+       NULL,
100416
 
+       cmd_test_binary_validate, 
100417
 
+       cmd_test_binary_generate, 
100418
 
+       NULL 
100419
 
+};
100420
 
+
100421
 
+/* 
100422
 
+ * Operations
100423
 
+ */ 
100424
 
+
100425
 
+static bool cmd_test_binary_operation_dump
100426
 
+       (const struct sieve_operation *op,
100427
 
+               const struct sieve_dumptime_env *denv, sieve_size_t *address);
100428
 
+static int cmd_test_binary_operation_execute
100429
 
+       (const struct sieve_operation *op, 
100430
 
+               const struct sieve_runtime_env *renv, sieve_size_t *address);
100431
 
100432
 
+/* test_binary_create operation */
100433
 
+
100434
 
+const struct sieve_operation test_binary_load_operation = { 
100435
 
+       "TEST_BINARY_LOAD",
100436
 
+       &testsuite_extension, 
100437
 
+       TESTSUITE_OPERATION_TEST_BINARY_LOAD,
100438
 
+       cmd_test_binary_operation_dump, 
100439
 
+       cmd_test_binary_operation_execute 
100440
 
+};
100441
 
+
100442
 
+/* test_binary_delete operation */
100443
 
+
100444
 
+const struct sieve_operation test_binary_save_operation = { 
100445
 
+       "TEST_BINARY_SAVE",
100446
 
+       &testsuite_extension, 
100447
 
+       TESTSUITE_OPERATION_TEST_BINARY_SAVE,
100448
 
+       cmd_test_binary_operation_dump, 
100449
 
+       cmd_test_binary_operation_execute 
100450
 
+};
100451
 
+
100452
 
+/*
100453
 
+ * Compiler context data
100454
 
+ */
100455
 
100456
 
+enum test_binary_operation {
100457
 
+       BINARY_OP_LOAD, 
100458
 
+       BINARY_OP_SAVE,
100459
 
+       BINARY_OP_LAST
100460
 
+};
100461
 
+
100462
 
+const struct sieve_operation *test_binary_operations[] = {
100463
 
+       &test_binary_load_operation,
100464
 
+       &test_binary_save_operation
100465
 
+};
100466
 
+
100467
 
+struct cmd_test_binary_context_data {
100468
 
+       enum test_binary_operation binary_op;
100469
 
+       const char *folder;
100470
 
+};
100471
 
+
100472
 
+/* 
100473
 
+ * Command tags 
100474
 
+ */
100475
 
100476
 
+static bool cmd_test_binary_validate_tag
100477
 
+       (struct sieve_validator *valdtr, struct sieve_ast_argument **arg, 
100478
 
+               struct sieve_command_context *cmd);
100479
 
+
100480
 
+static const struct sieve_argument test_binary_load_tag = { 
100481
 
+       "load", 
100482
 
+       NULL, NULL,
100483
 
+       cmd_test_binary_validate_tag,
100484
 
+       NULL, NULL 
100485
 
+};
100486
 
+
100487
 
+static const struct sieve_argument test_binary_save_tag = { 
100488
 
+       "save", 
100489
 
+       NULL, NULL, 
100490
 
+       cmd_test_binary_validate_tag,
100491
 
+       NULL, NULL 
100492
 
+};
100493
 
+
100494
 
+static bool cmd_test_binary_registered
100495
 
+(struct sieve_validator *valdtr, struct sieve_command_registration *cmd_reg) 
100496
 
+{
100497
 
+       /* Register our tags */
100498
 
+       sieve_validator_register_tag(valdtr, cmd_reg, &test_binary_load_tag, 0);        
100499
 
+       sieve_validator_register_tag(valdtr, cmd_reg, &test_binary_save_tag, 0);        
100500
 
+
100501
 
+       return TRUE;
100502
 
+}
100503
 
+
100504
 
+static bool cmd_test_binary_validate_tag
100505
 
+(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, 
100506
 
+       struct sieve_command_context *cmd)
100507
 
+{
100508
 
+       struct cmd_test_binary_context_data *ctx_data = 
100509
 
+               (struct cmd_test_binary_context_data *) cmd->data;      
100510
 
+       
100511
 
+       if ( ctx_data != NULL ) {
100512
 
+               sieve_argument_validate_error
100513
 
+                       (valdtr, *arg, "exactly one of the ':load' or ':save' tags must be "
100514
 
+                               "specified for the test_binary command, but more were found");
100515
 
+               return NULL;            
100516
 
+       }
100517
 
+       
100518
 
+       ctx_data = p_new
100519
 
+               (sieve_command_pool(cmd), struct cmd_test_binary_context_data, 1);
100520
 
+       cmd->data = ctx_data;
100521
 
+       
100522
 
+       if ( (*arg)->argument == &test_binary_load_tag ) 
100523
 
+               ctx_data->binary_op = BINARY_OP_LOAD;
100524
 
+       else
100525
 
+               ctx_data->binary_op = BINARY_OP_SAVE;
100526
 
+
100527
 
+       /* Delete this tag */
100528
 
+       *arg = sieve_ast_arguments_detach(*arg, 1);
100529
 
+
100530
 
+       return TRUE;
100531
 
+}
100532
 
+
100533
 
+/* 
100534
 
+ * Validation 
100535
 
+ */
100536
 
+
100537
 
+static bool cmd_test_binary_validate
100538
 
+(struct sieve_validator *valdtr, struct sieve_command_context *cmd) 
100539
 
+{
100540
 
+       struct sieve_ast_argument *arg = cmd->first_positional;
100541
 
+       
100542
 
+       if ( cmd->data == NULL ) {
100543
 
+               sieve_command_validate_error(valdtr, cmd, 
100544
 
+                       "the test_binary command requires either the :load or the :save tag "
100545
 
+                       "to be specified");
100546
 
+               return FALSE;           
100547
 
+       }
100548
 
+               
100549
 
+       if ( !sieve_validate_positional_argument
100550
 
+               (valdtr, cmd, arg, "binary-name", 1, SAAT_STRING) ) {
100551
 
+               return FALSE;
100552
 
+       }
100553
 
+       
100554
 
+       return sieve_validator_argument_activate(valdtr, cmd, arg, FALSE);
100555
 
+}
100556
 
+
100557
 
+/* 
100558
 
+ * Code generation 
100559
 
+ */
100560
 
+
100561
 
+static bool cmd_test_binary_generate
100562
 
+(const struct sieve_codegen_env *cgenv, struct sieve_command_context *cmd)
100563
 
+{
100564
 
+       struct cmd_test_binary_context_data *ctx_data =
100565
 
+               (struct cmd_test_binary_context_data *) cmd->data; 
100566
 
+
100567
 
+       i_assert( ctx_data->binary_op < BINARY_OP_LAST );
100568
 
+       
100569
 
+       /* Emit operation */
100570
 
+       sieve_operation_emit_code(cgenv->sbin, 
100571
 
+               test_binary_operations[ctx_data->binary_op]);
100572
 
+               
100573
 
+       /* Generate arguments */
100574
 
+       if ( !sieve_generate_arguments(cgenv, cmd, NULL) )
100575
 
+               return FALSE;
100576
 
+
100577
 
+       return TRUE;
100578
 
+}
100579
 
+
100580
 
+/* 
100581
 
+ * Code dump
100582
 
+ */
100583
 
100584
 
+static bool cmd_test_binary_operation_dump
100585
 
+(const struct sieve_operation *op,
100586
 
+       const struct sieve_dumptime_env *denv, sieve_size_t *address)
100587
 
+{
100588
 
+       sieve_code_dumpf(denv, "%s:", op->mnemonic);
100589
 
+       
100590
 
+       sieve_code_descend(denv);
100591
 
+       
100592
 
+       return sieve_opr_string_dump(denv, address, "binary-name");
100593
 
+}
100594
 
+
100595
 
+
100596
 
+/*
100597
 
+ * Intepretation
100598
 
+ */
100599
 
100600
 
+static int cmd_test_binary_operation_execute
100601
 
+(const struct sieve_operation *op,
100602
 
+       const struct sieve_runtime_env *renv, sieve_size_t *address)
100603
 
+{
100604
 
+       string_t *binary_name = NULL;
100605
 
+
100606
 
+       /* 
100607
 
+        * Read operands 
100608
 
+        */
100609
 
+
100610
 
+       /* Binary Name */
100611
 
+
100612
 
+       if ( !sieve_opr_string_read(renv, address, &binary_name) ) {
100613
 
+               sieve_runtime_trace_error(renv, "invalid mailbox operand");
100614
 
+               return SIEVE_EXEC_BIN_CORRUPT;
100615
 
+       }
100616
 
+
100617
 
+       /*
100618
 
+        * Perform operation
100619
 
+        */
100620
 
+               
100621
 
+       sieve_runtime_trace(renv, "%s %s:", op->mnemonic, str_c(binary_name));
100622
 
+
100623
 
+       if ( op == &test_binary_load_operation ) {
100624
 
+               struct sieve_binary *sbin = testsuite_binary_load(str_c(binary_name));
100625
 
+
100626
 
+               if ( sbin != NULL ) {
100627
 
+                       testsuite_script_set_binary(sbin);
100628
 
+
100629
 
+                       sieve_binary_unref(&sbin);
100630
 
+               } else {
100631
 
+                       sieve_sys_error("failed to load binary %s", str_c(binary_name));
100632
 
+                       return SIEVE_EXEC_FAILURE;
100633
 
+               }
100634
 
+
100635
 
+       } else if ( op == &test_binary_save_operation ) {
100636
 
+               struct sieve_binary *sbin = testsuite_script_get_binary();
100637
 
+
100638
 
+               if ( sbin != NULL ) 
100639
 
+                       testsuite_binary_save(sbin, str_c(binary_name));
100640
 
+               else {
100641
 
+                       sieve_sys_error("no compiled binary to save as %s", str_c(binary_name));
100642
 
+                       return SIEVE_EXEC_FAILURE;
100643
 
+               }
100644
 
+       }
100645
 
+
100646
 
+       return SIEVE_EXEC_OK;
100647
 
+}
100648
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/testsuite/cmd-test.c dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/cmd-test.c
100649
 
--- dovecot-1.2.4/dovecot-libsieve/src/testsuite/cmd-test.c     1970-01-01 01:00:00.000000000 +0100
100650
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/cmd-test.c      2009-04-11 17:47:41.000000000 +0200
100651
 
@@ -0,0 +1,185 @@
100652
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
100653
 
+ */
100654
 
+
100655
 
+#include "sieve-common.h"
100656
 
+#include "sieve-commands.h"
100657
 
+#include "sieve-validator.h"
100658
 
+#include "sieve-generator.h"
100659
 
+#include "sieve-interpreter.h"
100660
 
+#include "sieve-code.h"
100661
 
+#include "sieve-binary.h"
100662
 
+#include "sieve-dump.h"
100663
 
+
100664
 
+#include "testsuite-common.h"
100665
 
+
100666
 
+/*
100667
 
+ * Test command
100668
 
+ *
100669
 
+ * Syntax:   
100670
 
+ *   test <test-name: string> <block>
100671
 
+ */
100672
 
+
100673
 
+static bool cmd_test_validate
100674
 
+       (struct sieve_validator *validator, struct sieve_command_context *cmd);
100675
 
+static bool cmd_test_generate
100676
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx);
100677
 
+
100678
 
+const struct sieve_command cmd_test = { 
100679
 
+       "test", 
100680
 
+       SCT_COMMAND, 
100681
 
+       1, 0, TRUE, TRUE,
100682
 
+       NULL, NULL,
100683
 
+       cmd_test_validate, 
100684
 
+       cmd_test_generate, 
100685
 
+       NULL 
100686
 
+};
100687
 
+
100688
 
+/* 
100689
 
+ * Test operations 
100690
 
+ */
100691
 
+
100692
 
+/* Test operation */
100693
 
+
100694
 
+static bool cmd_test_operation_dump
100695
 
+       (const struct sieve_operation *op,
100696
 
+               const struct sieve_dumptime_env *denv, sieve_size_t *address);
100697
 
+static int cmd_test_operation_execute
100698
 
+       (const struct sieve_operation *op, 
100699
 
+               const struct sieve_runtime_env *renv, sieve_size_t *address);
100700
 
+
100701
 
+const struct sieve_operation test_operation = { 
100702
 
+       "TEST",
100703
 
+       &testsuite_extension, 
100704
 
+       TESTSUITE_OPERATION_TEST,
100705
 
+       cmd_test_operation_dump, 
100706
 
+       cmd_test_operation_execute 
100707
 
+};
100708
 
+
100709
 
+/* Test_finish operation */
100710
 
+
100711
 
+static int cmd_test_finish_operation_execute
100712
 
+       (const struct sieve_operation *op, 
100713
 
+               const struct sieve_runtime_env *renv, sieve_size_t *address);
100714
 
+
100715
 
+const struct sieve_operation test_finish_operation = { 
100716
 
+       "TEST-FINISH",
100717
 
+       &testsuite_extension, 
100718
 
+       TESTSUITE_OPERATION_TEST_FINISH,
100719
 
+       NULL, 
100720
 
+       cmd_test_finish_operation_execute 
100721
 
+};
100722
 
+
100723
 
+/* 
100724
 
+ * Validation 
100725
 
+ */
100726
 
+
100727
 
+static bool cmd_test_validate
100728
 
+(struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_command_context *cmd) 
100729
 
+{
100730
 
+       struct sieve_ast_argument *arg = cmd->first_positional;
100731
 
+               
100732
 
+       /* Check valid command placement */
100733
 
+       if ( !sieve_command_is_toplevel(cmd) )
100734
 
+       {
100735
 
+               sieve_command_validate_error(valdtr, cmd,
100736
 
+                       "tests cannot be nested: test command must be issued at top-level");
100737
 
+               return FALSE;
100738
 
+       }
100739
 
+       
100740
 
+       if ( !sieve_validate_positional_argument
100741
 
+               (valdtr, cmd, arg, "test-name", 1, SAAT_STRING) ) {
100742
 
+               return FALSE;
100743
 
+       }
100744
 
+       
100745
 
+       return sieve_validator_argument_activate(valdtr, cmd, arg, FALSE);
100746
 
+}
100747
 
+
100748
 
+/* 
100749
 
+ * Code generation 
100750
 
+ */
100751
 
+
100752
 
+static inline struct testsuite_generator_context *
100753
 
+       _get_generator_context(struct sieve_generator *gentr)
100754
 
+{
100755
 
+       return (struct testsuite_generator_context *) 
100756
 
+               sieve_generator_extension_get_context(gentr, &testsuite_extension);
100757
 
+}
100758
 
+
100759
 
+static bool cmd_test_generate
100760
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx)
100761
 
+{
100762
 
+       struct testsuite_generator_context *genctx = 
100763
 
+               _get_generator_context(cgenv->gentr);
100764
 
+       
100765
 
+       sieve_operation_emit_code(cgenv->sbin, &test_operation);
100766
 
+
100767
 
+       /* Generate arguments */
100768
 
+       if ( !sieve_generate_arguments(cgenv, ctx, NULL) )
100769
 
+               return FALSE;
100770
 
+               
100771
 
+       /* Prepare jumplist */
100772
 
+       sieve_jumplist_reset(genctx->exit_jumps);
100773
 
+               
100774
 
+       /* Test body */
100775
 
+       if ( !sieve_generate_block(cgenv, ctx->ast_node) )
100776
 
+               return FALSE;
100777
 
+       
100778
 
+       sieve_operation_emit_code(cgenv->sbin, &test_finish_operation);
100779
 
+       
100780
 
+       /* Resolve exit jumps to this point */
100781
 
+       sieve_jumplist_resolve(genctx->exit_jumps); 
100782
 
+                       
100783
 
+       return TRUE;
100784
 
+}
100785
 
+
100786
 
+/* 
100787
 
+ * Code dump
100788
 
+ */
100789
 
100790
 
+static bool cmd_test_operation_dump
100791
 
+(const struct sieve_operation *op ATTR_UNUSED,
100792
 
+       const struct sieve_dumptime_env *denv, sieve_size_t *address)
100793
 
+{
100794
 
+       sieve_code_dumpf(denv, "TEST:");
100795
 
+       sieve_code_descend(denv);
100796
 
+
100797
 
+       return 
100798
 
+               sieve_opr_string_dump(denv, address, "test name");
100799
 
+}
100800
 
+
100801
 
+/*
100802
 
+ * Intepretation
100803
 
+ */
100804
 
+
100805
 
+static int cmd_test_operation_execute
100806
 
+(const struct sieve_operation *op ATTR_UNUSED,
100807
 
+       const struct sieve_runtime_env *renv, sieve_size_t *address)
100808
 
+{
100809
 
+       string_t *test_name;
100810
 
+
100811
 
+       if ( !sieve_opr_string_read(renv, address, &test_name) ) {
100812
 
+               sieve_runtime_trace_error(renv, "invalid test name operand");
100813
 
+               return SIEVE_EXEC_BIN_CORRUPT;
100814
 
+       }
100815
 
+       
100816
 
+       sieve_runtime_trace(renv, "TEST \"%s\"", str_c(test_name));
100817
 
+
100818
 
+       testsuite_test_start(test_name);
100819
 
+       return SIEVE_EXEC_OK;
100820
 
+}
100821
 
+
100822
 
+static int cmd_test_finish_operation_execute
100823
 
+(const struct sieve_operation *op ATTR_UNUSED,
100824
 
+       const struct sieve_runtime_env *renv ATTR_UNUSED, 
100825
 
+       sieve_size_t *address ATTR_UNUSED)
100826
 
+{
100827
 
+       sieve_runtime_trace(renv, "TEST FINISHED");
100828
 
+       
100829
 
+       testsuite_test_succeed(NULL);
100830
 
+       return SIEVE_EXEC_OK;
100831
 
+}
100832
 
+
100833
 
+
100834
 
+
100835
 
+
100836
 
+
100837
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/testsuite/cmd-test-fail.c dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/cmd-test-fail.c
100838
 
--- dovecot-1.2.4/dovecot-libsieve/src/testsuite/cmd-test-fail.c        1970-01-01 01:00:00.000000000 +0100
100839
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/cmd-test-fail.c 2009-01-06 00:15:52.000000000 +0100
100840
 
@@ -0,0 +1,152 @@
100841
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
100842
 
+ */
100843
 
+
100844
 
+#include "sieve-common.h"
100845
 
+#include "sieve-commands.h"
100846
 
+#include "sieve-validator.h"
100847
 
+#include "sieve-generator.h"
100848
 
+#include "sieve-interpreter.h"
100849
 
+#include "sieve-code.h"
100850
 
+#include "sieve-binary.h"
100851
 
+#include "sieve-dump.h"
100852
 
+
100853
 
+#include "testsuite-common.h"
100854
 
+
100855
 
+/* 
100856
 
+ * Test_fail command
100857
 
+ *
100858
 
+ * Syntax:   
100859
 
+ *   test_fail <reason: string>
100860
 
+ */
100861
 
+
100862
 
+static bool cmd_test_fail_validate
100863
 
+       (struct sieve_validator *validator, struct sieve_command_context *cmd);
100864
 
+static bool cmd_test_fail_generate
100865
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx);
100866
 
+
100867
 
+const struct sieve_command cmd_test_fail = { 
100868
 
+       "test_fail", 
100869
 
+       SCT_COMMAND, 
100870
 
+       1, 0, FALSE, FALSE,
100871
 
+       NULL, NULL,
100872
 
+       cmd_test_fail_validate, 
100873
 
+       cmd_test_fail_generate, 
100874
 
+       NULL 
100875
 
+};
100876
 
+
100877
 
+/* 
100878
 
+ * Test operation 
100879
 
+ */
100880
 
+
100881
 
+static bool cmd_test_fail_operation_dump
100882
 
+       (const struct sieve_operation *op,
100883
 
+               const struct sieve_dumptime_env *denv, sieve_size_t *address);
100884
 
+static int cmd_test_fail_operation_execute
100885
 
+       (const struct sieve_operation *op, 
100886
 
+               const struct sieve_runtime_env *renv, sieve_size_t *address);
100887
 
+
100888
 
+const struct sieve_operation test_fail_operation = { 
100889
 
+       "TEST_FAIL",
100890
 
+       &testsuite_extension, 
100891
 
+       TESTSUITE_OPERATION_TEST_FAIL,
100892
 
+       cmd_test_fail_operation_dump, 
100893
 
+       cmd_test_fail_operation_execute 
100894
 
+};
100895
 
+
100896
 
+/* 
100897
 
+ * Validation 
100898
 
+ */
100899
 
+
100900
 
+static bool cmd_test_fail_validate
100901
 
+(struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_command_context *cmd) 
100902
 
+{
100903
 
+       struct sieve_ast_argument *arg = cmd->first_positional;
100904
 
+       
100905
 
+       if ( !sieve_validate_positional_argument
100906
 
+               (valdtr, cmd, arg, "reason", 1, SAAT_STRING) ) {
100907
 
+               return FALSE;
100908
 
+       }
100909
 
+       
100910
 
+       return sieve_validator_argument_activate(valdtr, cmd, arg, FALSE);
100911
 
+}
100912
 
+
100913
 
+/* 
100914
 
+ * Code generation 
100915
 
+ */
100916
 
+
100917
 
+static inline struct testsuite_generator_context *
100918
 
+       _get_generator_context(struct sieve_generator *gentr)
100919
 
+{
100920
 
+       return (struct testsuite_generator_context *) 
100921
 
+               sieve_generator_extension_get_context(gentr, &testsuite_extension);
100922
 
+}
100923
 
+
100924
 
+static bool cmd_test_fail_generate
100925
 
+(const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx)
100926
 
+{
100927
 
+       struct testsuite_generator_context *genctx = 
100928
 
+               _get_generator_context(cgenv->gentr);
100929
 
+       
100930
 
+       sieve_operation_emit_code(cgenv->sbin, &test_fail_operation);
100931
 
+
100932
 
+       /* Generate arguments */
100933
 
+       if ( !sieve_generate_arguments(cgenv, ctx, NULL) )
100934
 
+               return FALSE;
100935
 
+               
100936
 
+       sieve_jumplist_add(genctx->exit_jumps, 
100937
 
+               sieve_binary_emit_offset(cgenv->sbin, 0));                      
100938
 
+       
100939
 
+       return TRUE;
100940
 
+}
100941
 
+
100942
 
+/* 
100943
 
+ * Code dump
100944
 
+ */
100945
 
100946
 
+static bool cmd_test_fail_operation_dump
100947
 
+(const struct sieve_operation *op ATTR_UNUSED,
100948
 
+       const struct sieve_dumptime_env *denv, sieve_size_t *address)
100949
 
+{
100950
 
+       unsigned int pc;
100951
 
+       int offset;
100952
 
+    
100953
 
+       sieve_code_dumpf(denv, "TEST_FAIL:");
100954
 
+       sieve_code_descend(denv);
100955
 
+
100956
 
+       if ( !sieve_opr_string_dump(denv, address, "reason") ) 
100957
 
+               return FALSE;
100958
 
+
100959
 
+       sieve_code_mark(denv);
100960
 
+       pc = *address;
100961
 
+       if ( sieve_binary_read_offset(denv->sbin, address, &offset) )
100962
 
+               sieve_code_dumpf(denv, "offset: %d [%08x]", offset, pc + offset);
100963
 
+       else
100964
 
+               return FALSE;
100965
 
+
100966
 
+       return TRUE;
100967
 
+}
100968
 
+
100969
 
+/*
100970
 
+ * Intepretation
100971
 
+ */
100972
 
+
100973
 
+static int cmd_test_fail_operation_execute
100974
 
+(const struct sieve_operation *op ATTR_UNUSED,
100975
 
+       const struct sieve_runtime_env *renv, sieve_size_t *address)
100976
 
+{
100977
 
+       string_t *reason;
100978
 
+
100979
 
+       if ( !sieve_opr_string_read(renv, address, &reason) ) {
100980
 
+               sieve_runtime_trace_error(renv, "invalid reason operand");
100981
 
+               return SIEVE_EXEC_BIN_CORRUPT;
100982
 
+       }
100983
 
+
100984
 
+       sieve_runtime_trace(renv, "TEST FAIL");
100985
 
+       testsuite_test_fail(reason);
100986
 
+       
100987
 
+       return sieve_interpreter_program_jump(renv->interp, TRUE);
100988
 
+}
100989
 
+
100990
 
+
100991
 
+
100992
 
+
100993
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/testsuite/cmd-test-mailbox.c dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/cmd-test-mailbox.c
100994
 
--- dovecot-1.2.4/dovecot-libsieve/src/testsuite/cmd-test-mailbox.c     1970-01-01 01:00:00.000000000 +0100
100995
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/cmd-test-mailbox.c      2009-07-31 17:34:58.000000000 +0200
100996
 
@@ -0,0 +1,248 @@
100997
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
100998
 
+ */
100999
 
+
101000
 
+#include "sieve-common.h"
101001
 
+#include "sieve-commands.h"
101002
 
+#include "sieve-validator.h"
101003
 
+#include "sieve-generator.h"
101004
 
+#include "sieve-interpreter.h"
101005
 
+#include "sieve-code.h"
101006
 
+#include "sieve-binary.h"
101007
 
+#include "sieve-dump.h"
101008
 
+
101009
 
+#include "testsuite-common.h"
101010
 
+#include "testsuite-mailstore.h"
101011
 
+
101012
 
+/*
101013
 
+ * Test_mailbox command
101014
 
+ *
101015
 
+ * Syntax:   
101016
 
+ *   test_mailbox ( :create / :delete ) <mailbox: string>
101017
 
+ */
101018
 
+
101019
 
+static bool cmd_test_mailbox_registered
101020
 
+       (struct sieve_validator *valdtr, 
101021
 
+               struct sieve_command_registration *cmd_reg);
101022
 
+static bool cmd_test_mailbox_validate
101023
 
+       (struct sieve_validator *valdtr, struct sieve_command_context *cmd);
101024
 
+static bool cmd_test_mailbox_generate
101025
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx);
101026
 
+
101027
 
+const struct sieve_command cmd_test_mailbox = { 
101028
 
+       "test_mailbox", 
101029
 
+       SCT_COMMAND, 
101030
 
+       1, 0, FALSE, FALSE,
101031
 
+       cmd_test_mailbox_registered, 
101032
 
+       NULL,
101033
 
+       cmd_test_mailbox_validate, 
101034
 
+       cmd_test_mailbox_generate, 
101035
 
+       NULL 
101036
 
+};
101037
 
+
101038
 
+/* 
101039
 
+ * Operations
101040
 
+ */ 
101041
 
+
101042
 
+static bool cmd_test_mailbox_operation_dump
101043
 
+       (const struct sieve_operation *op,
101044
 
+               const struct sieve_dumptime_env *denv, sieve_size_t *address);
101045
 
+static int cmd_test_mailbox_operation_execute
101046
 
+       (const struct sieve_operation *op, 
101047
 
+               const struct sieve_runtime_env *renv, sieve_size_t *address);
101048
 
101049
 
+/* Test_mailbox_create operation */
101050
 
+
101051
 
+const struct sieve_operation test_mailbox_create_operation = { 
101052
 
+       "TEST_MAILBOX_CREATE",
101053
 
+       &testsuite_extension, 
101054
 
+       TESTSUITE_OPERATION_TEST_MAILBOX_CREATE,
101055
 
+       cmd_test_mailbox_operation_dump, 
101056
 
+       cmd_test_mailbox_operation_execute 
101057
 
+};
101058
 
+
101059
 
+/* Test_mailbox_delete operation */
101060
 
+
101061
 
+const struct sieve_operation test_mailbox_delete_operation = { 
101062
 
+       "TEST_MAILBOX_DELETE",
101063
 
+       &testsuite_extension, 
101064
 
+       TESTSUITE_OPERATION_TEST_MAILBOX_DELETE,
101065
 
+       cmd_test_mailbox_operation_dump, 
101066
 
+       cmd_test_mailbox_operation_execute 
101067
 
+};
101068
 
+
101069
 
+/*
101070
 
+ * Compiler context data
101071
 
+ */
101072
 
101073
 
+enum test_mailbox_operation {
101074
 
+       MAILBOX_OP_CREATE, 
101075
 
+       MAILBOX_OP_DELETE,
101076
 
+       MAILBOX_OP_LAST
101077
 
+};
101078
 
+
101079
 
+const struct sieve_operation *test_mailbox_operations[] = {
101080
 
+       &test_mailbox_create_operation,
101081
 
+       &test_mailbox_delete_operation
101082
 
+};
101083
 
+
101084
 
+struct cmd_test_mailbox_context_data {
101085
 
+       enum test_mailbox_operation mailbox_op;
101086
 
+       const char *folder;
101087
 
+};
101088
 
+
101089
 
+/* 
101090
 
+ * Command tags 
101091
 
+ */
101092
 
101093
 
+static bool cmd_test_mailbox_validate_tag
101094
 
+       (struct sieve_validator *valdtr, struct sieve_ast_argument **arg, 
101095
 
+               struct sieve_command_context *cmd);
101096
 
+
101097
 
+static const struct sieve_argument test_mailbox_create_tag = { 
101098
 
+       "create", 
101099
 
+       NULL, NULL,
101100
 
+       cmd_test_mailbox_validate_tag,
101101
 
+       NULL, NULL 
101102
 
+};
101103
 
+
101104
 
+static const struct sieve_argument test_mailbox_delete_tag = { 
101105
 
+       "delete", 
101106
 
+       NULL, NULL, 
101107
 
+       cmd_test_mailbox_validate_tag,
101108
 
+       NULL, NULL 
101109
 
+};
101110
 
+
101111
 
+static bool cmd_test_mailbox_registered
101112
 
+(struct sieve_validator *valdtr, struct sieve_command_registration *cmd_reg) 
101113
 
+{
101114
 
+       /* Register our tags */
101115
 
+       sieve_validator_register_tag(valdtr, cmd_reg, &test_mailbox_create_tag, 0);     
101116
 
+       sieve_validator_register_tag(valdtr, cmd_reg, &test_mailbox_delete_tag, 0);     
101117
 
+
101118
 
+       return TRUE;
101119
 
+}
101120
 
+
101121
 
+static bool cmd_test_mailbox_validate_tag
101122
 
+(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, 
101123
 
+       struct sieve_command_context *cmd)
101124
 
+{
101125
 
+       struct cmd_test_mailbox_context_data *ctx_data = 
101126
 
+               (struct cmd_test_mailbox_context_data *) cmd->data;     
101127
 
+       
101128
 
+       if ( ctx_data != NULL ) {
101129
 
+               sieve_argument_validate_error
101130
 
+                       (valdtr, *arg, "exactly one of the ':create' or ':delete' tags must be "
101131
 
+                               "specified for the test_mailbox command, but more were found");
101132
 
+               return NULL;            
101133
 
+       }
101134
 
+       
101135
 
+       ctx_data = p_new
101136
 
+               (sieve_command_pool(cmd), struct cmd_test_mailbox_context_data, 1);
101137
 
+       cmd->data = ctx_data;
101138
 
+       
101139
 
+       if ( (*arg)->argument == &test_mailbox_create_tag ) 
101140
 
+               ctx_data->mailbox_op = MAILBOX_OP_CREATE;
101141
 
+       else
101142
 
+               ctx_data->mailbox_op = MAILBOX_OP_DELETE;
101143
 
+
101144
 
+       /* Delete this tag */
101145
 
+       *arg = sieve_ast_arguments_detach(*arg, 1);
101146
 
+
101147
 
+       return TRUE;
101148
 
+}
101149
 
+
101150
 
+/* 
101151
 
+ * Validation 
101152
 
+ */
101153
 
+
101154
 
+static bool cmd_test_mailbox_validate
101155
 
+(struct sieve_validator *valdtr, struct sieve_command_context *cmd) 
101156
 
+{
101157
 
+       struct sieve_ast_argument *arg = cmd->first_positional;
101158
 
+       
101159
 
+       if ( cmd->data == NULL ) {
101160
 
+               sieve_command_validate_error(valdtr, cmd, 
101161
 
+                       "the test_mailbox command requires either the :create or the :delete tag "
101162
 
+                       "to be specified");
101163
 
+               return FALSE;           
101164
 
+       }
101165
 
+               
101166
 
+       if ( !sieve_validate_positional_argument
101167
 
+               (valdtr, cmd, arg, "mailbox", 1, SAAT_STRING) ) {
101168
 
+               return FALSE;
101169
 
+       }
101170
 
+       
101171
 
+       return sieve_validator_argument_activate(valdtr, cmd, arg, FALSE);
101172
 
+}
101173
 
+
101174
 
+/* 
101175
 
+ * Code generation 
101176
 
+ */
101177
 
+
101178
 
+static bool cmd_test_mailbox_generate
101179
 
+(const struct sieve_codegen_env *cgenv, struct sieve_command_context *cmd)
101180
 
+{
101181
 
+       struct cmd_test_mailbox_context_data *ctx_data =
101182
 
+               (struct cmd_test_mailbox_context_data *) cmd->data; 
101183
 
+
101184
 
+       i_assert( ctx_data->mailbox_op < MAILBOX_OP_LAST );
101185
 
+       
101186
 
+       /* Emit operation */
101187
 
+       sieve_operation_emit_code(cgenv->sbin, 
101188
 
+               test_mailbox_operations[ctx_data->mailbox_op]);
101189
 
+               
101190
 
+       /* Generate arguments */
101191
 
+       if ( !sieve_generate_arguments(cgenv, cmd, NULL) )
101192
 
+               return FALSE;
101193
 
+
101194
 
+       return TRUE;
101195
 
+}
101196
 
+
101197
 
+/* 
101198
 
+ * Code dump
101199
 
+ */
101200
 
101201
 
+static bool cmd_test_mailbox_operation_dump
101202
 
+(const struct sieve_operation *op,
101203
 
+       const struct sieve_dumptime_env *denv, sieve_size_t *address)
101204
 
+{
101205
 
+       sieve_code_dumpf(denv, "%s:", op->mnemonic);
101206
 
+       
101207
 
+       sieve_code_descend(denv);
101208
 
+       
101209
 
+       return sieve_opr_string_dump(denv, address, "mailbox");
101210
 
+}
101211
 
+
101212
 
+
101213
 
+/*
101214
 
+ * Intepretation
101215
 
+ */
101216
 
101217
 
+static int cmd_test_mailbox_operation_execute
101218
 
+(const struct sieve_operation *op,
101219
 
+       const struct sieve_runtime_env *renv, sieve_size_t *address)
101220
 
+{
101221
 
+       string_t *mailbox = NULL;
101222
 
+
101223
 
+       /* 
101224
 
+        * Read operands 
101225
 
+        */
101226
 
+
101227
 
+       /* Index */
101228
 
+
101229
 
+       if ( !sieve_opr_string_read(renv, address, &mailbox) ) {
101230
 
+               sieve_runtime_trace_error(renv, "invalid mailbox operand");
101231
 
+               return SIEVE_EXEC_BIN_CORRUPT;
101232
 
+       }
101233
 
+
101234
 
+       /*
101235
 
+        * Perform operation
101236
 
+        */
101237
 
+               
101238
 
+       sieve_runtime_trace(renv, "%s %s:", op->mnemonic, str_c(mailbox));
101239
 
+
101240
 
+       if ( op == &test_mailbox_create_operation )
101241
 
+               testsuite_mailstore_mailbox_create(renv, str_c(mailbox));
101242
 
+
101243
 
+       return SIEVE_EXEC_OK;
101244
 
+}
101245
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/testsuite/cmd-test-message.c dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/cmd-test-message.c
101246
 
--- dovecot-1.2.4/dovecot-libsieve/src/testsuite/cmd-test-message.c     1970-01-01 01:00:00.000000000 +0100
101247
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/cmd-test-message.c      2009-08-02 09:44:14.000000000 +0200
101248
 
@@ -0,0 +1,401 @@
101249
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
101250
 
+ */
101251
 
+
101252
 
+#include "sieve-common.h"
101253
 
+#include "sieve-commands.h"
101254
 
+#include "sieve-validator.h"
101255
 
+#include "sieve-generator.h"
101256
 
+#include "sieve-interpreter.h"
101257
 
+#include "sieve-code.h"
101258
 
+#include "sieve-binary.h"
101259
 
+#include "sieve-dump.h"
101260
 
+
101261
 
+#include "testsuite-common.h"
101262
 
+#include "testsuite-smtp.h"
101263
 
+#include "testsuite-mailstore.h"
101264
 
+
101265
 
+/*
101266
 
+ * Test_message command
101267
 
+ *
101268
 
+ * Syntax:   
101269
 
+ *   test_message ( :smtp / :mailbox <mailbox: string> ) <index: number>
101270
 
+ */
101271
 
+
101272
 
+static bool cmd_test_message_registered
101273
 
+       (struct sieve_validator *valdtr, 
101274
 
+               struct sieve_command_registration *cmd_reg);
101275
 
+static bool cmd_test_message_validate
101276
 
+       (struct sieve_validator *valdtr, struct sieve_command_context *cmd);
101277
 
+static bool cmd_test_message_generate
101278
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx);
101279
 
+
101280
 
+const struct sieve_command cmd_test_message = { 
101281
 
+       "test_message", 
101282
 
+       SCT_HYBRID, 
101283
 
+       1, 0, FALSE, FALSE,
101284
 
+       cmd_test_message_registered, 
101285
 
+       NULL,
101286
 
+       cmd_test_message_validate, 
101287
 
+       cmd_test_message_generate, 
101288
 
+       NULL 
101289
 
+};
101290
 
+
101291
 
+/* 
101292
 
+ * Operations
101293
 
+ */ 
101294
 
101295
 
+/* Test_message_smtp operation */
101296
 
+
101297
 
+static bool cmd_test_message_smtp_operation_dump
101298
 
+       (const struct sieve_operation *op,
101299
 
+               const struct sieve_dumptime_env *denv, sieve_size_t *address);
101300
 
+static int cmd_test_message_smtp_operation_execute
101301
 
+       (const struct sieve_operation *op, 
101302
 
+               const struct sieve_runtime_env *renv, sieve_size_t *address);
101303
 
+
101304
 
+const struct sieve_operation test_message_smtp_operation = { 
101305
 
+       "TEST_MESSAGE_SMTP",
101306
 
+       &testsuite_extension, 
101307
 
+       TESTSUITE_OPERATION_TEST_MESSAGE_SMTP,
101308
 
+       cmd_test_message_smtp_operation_dump, 
101309
 
+       cmd_test_message_smtp_operation_execute 
101310
 
+};
101311
 
+
101312
 
+/* Test_message_mailbox operation */
101313
 
+
101314
 
+static bool cmd_test_message_mailbox_operation_dump
101315
 
+       (const struct sieve_operation *op,
101316
 
+               const struct sieve_dumptime_env *denv, sieve_size_t *address);
101317
 
+static int cmd_test_message_mailbox_operation_execute
101318
 
+       (const struct sieve_operation *op, 
101319
 
+               const struct sieve_runtime_env *renv, sieve_size_t *address);
101320
 
+
101321
 
+const struct sieve_operation test_message_mailbox_operation = { 
101322
 
+       "TEST_MESSAGE_MAILBOX",
101323
 
+       &testsuite_extension, 
101324
 
+       TESTSUITE_OPERATION_TEST_MESSAGE_MAILBOX,
101325
 
+       cmd_test_message_mailbox_operation_dump, 
101326
 
+       cmd_test_message_mailbox_operation_execute 
101327
 
+};
101328
 
+
101329
 
+/*
101330
 
+ * Compiler context data
101331
 
+ */
101332
 
101333
 
+enum test_message_source {
101334
 
+       MSG_SOURCE_SMTP, 
101335
 
+       MSG_SOURCE_MAILBOX,
101336
 
+       MSG_SOURCE_LAST
101337
 
+};
101338
 
+
101339
 
+const struct sieve_operation *test_message_operations[] = {
101340
 
+       &test_message_smtp_operation,
101341
 
+       &test_message_mailbox_operation
101342
 
+};
101343
 
+
101344
 
+struct cmd_test_message_context_data {
101345
 
+       enum test_message_source msg_source;
101346
 
+       const char *folder;
101347
 
+};
101348
 
+
101349
 
+#define CMD_TEST_MESSAGE_ERROR_DUP_TAG \
101350
 
+       "exactly one of the ':smtp' or ':folder' tags must be specified " \
101351
 
+       "for the test_message command, but more were found"
101352
 
+
101353
 
+/* 
101354
 
+ * Command tags 
101355
 
+ */
101356
 
101357
 
+static bool cmd_test_message_validate_smtp_tag
101358
 
+       (struct sieve_validator *valdtr, struct sieve_ast_argument **arg, 
101359
 
+               struct sieve_command_context *cmd);
101360
 
+static bool cmd_test_message_validate_folder_tag
101361
 
+       (struct sieve_validator *valdtr, struct sieve_ast_argument **arg, 
101362
 
+               struct sieve_command_context *cmd);
101363
 
+
101364
 
+static const struct sieve_argument test_message_smtp_tag = { 
101365
 
+       "smtp", 
101366
 
+       NULL, NULL,
101367
 
+       cmd_test_message_validate_smtp_tag,
101368
 
+       NULL, NULL 
101369
 
+};
101370
 
+
101371
 
+static const struct sieve_argument test_message_folder_tag = { 
101372
 
+       "folder", 
101373
 
+       NULL, NULL, 
101374
 
+       cmd_test_message_validate_folder_tag,
101375
 
+       NULL, NULL 
101376
 
+};
101377
 
+
101378
 
+static bool cmd_test_message_registered
101379
 
+(struct sieve_validator *valdtr, struct sieve_command_registration *cmd_reg) 
101380
 
+{
101381
 
+       /* Register our tags */
101382
 
+       sieve_validator_register_tag(valdtr, cmd_reg, &test_message_folder_tag, 0);     
101383
 
+       sieve_validator_register_tag(valdtr, cmd_reg, &test_message_smtp_tag, 0);       
101384
 
+
101385
 
+       return TRUE;
101386
 
+}
101387
 
+
101388
 
+static struct cmd_test_message_context_data *cmd_test_message_validate_tag
101389
 
+(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, 
101390
 
+       struct sieve_command_context *cmd)
101391
 
+{
101392
 
+       struct cmd_test_message_context_data *ctx_data = 
101393
 
+               (struct cmd_test_message_context_data *) cmd->data;     
101394
 
+       
101395
 
+       if ( ctx_data != NULL ) {
101396
 
+               sieve_argument_validate_error
101397
 
+                       (valdtr, *arg, CMD_TEST_MESSAGE_ERROR_DUP_TAG);
101398
 
+               return NULL;            
101399
 
+       }
101400
 
+       
101401
 
+       ctx_data = p_new
101402
 
+               (sieve_command_pool(cmd), struct cmd_test_message_context_data, 1);
101403
 
+       cmd->data = ctx_data;
101404
 
+       
101405
 
+       /* Delete this tag */
101406
 
+       *arg = sieve_ast_arguments_detach(*arg, 1);
101407
 
+
101408
 
+       return ctx_data;
101409
 
+}
101410
 
+
101411
 
+static bool cmd_test_message_validate_smtp_tag
101412
 
+(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, 
101413
 
+       struct sieve_command_context *cmd)
101414
 
+{
101415
 
+       struct cmd_test_message_context_data *ctx_data = 
101416
 
+               cmd_test_message_validate_tag(valdtr, arg, cmd);
101417
 
+
101418
 
+       /* Return value is NULL on error */
101419
 
+       if ( ctx_data == NULL ) return FALSE;
101420
 
+       
101421
 
+       /* Assign chosen message source */
101422
 
+       ctx_data->msg_source = MSG_SOURCE_SMTP;
101423
 
+                       
101424
 
+       return TRUE;
101425
 
+}
101426
 
+
101427
 
+static bool cmd_test_message_validate_folder_tag
101428
 
+(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, 
101429
 
+       struct sieve_command_context *cmd)
101430
 
+{
101431
 
+       struct sieve_ast_argument *tag = *arg;
101432
 
+       struct cmd_test_message_context_data *ctx_data = 
101433
 
+               cmd_test_message_validate_tag(valdtr, arg, cmd);
101434
 
+       
101435
 
+       /* Return value is NULL on error */
101436
 
+       if ( ctx_data == NULL ) return FALSE;
101437
 
+
101438
 
+       /* Assign chose message source */
101439
 
+       ctx_data->msg_source = MSG_SOURCE_MAILBOX;
101440
 
+       
101441
 
+       /* Check syntax:
101442
 
+        *   :folder string
101443
 
+        */
101444
 
+       if ( !sieve_validate_tag_parameter
101445
 
+               (valdtr, cmd, tag, *arg, SAAT_STRING) ) {
101446
 
+               return FALSE;
101447
 
+       }
101448
 
+
101449
 
+       /* Skip parameter */
101450
 
+       *arg = sieve_ast_argument_next(*arg);
101451
 
+                       
101452
 
+       return TRUE;
101453
 
+}
101454
 
+
101455
 
+/* 
101456
 
+ * Validation 
101457
 
+ */
101458
 
+
101459
 
+static bool cmd_test_message_validate
101460
 
+(struct sieve_validator *valdtr, struct sieve_command_context *cmd) 
101461
 
+{
101462
 
+       struct sieve_ast_argument *arg = cmd->first_positional;
101463
 
+       
101464
 
+       if ( cmd->data == NULL ) {
101465
 
+               sieve_command_validate_error(valdtr, cmd, 
101466
 
+                       "the test_message command requires either the :smtp or the :mailbox tag "
101467
 
+                       "to be specified");
101468
 
+               return FALSE;           
101469
 
+       }
101470
 
+               
101471
 
+       if ( !sieve_validate_positional_argument
101472
 
+               (valdtr, cmd, arg, "index", 1, SAAT_NUMBER) ) {
101473
 
+               return FALSE;
101474
 
+       }
101475
 
+       
101476
 
+       return sieve_validator_argument_activate(valdtr, cmd, arg, FALSE);
101477
 
+}
101478
 
+
101479
 
+/* 
101480
 
+ * Code generation 
101481
 
+ */
101482
 
+
101483
 
+static bool cmd_test_message_generate
101484
 
+(const struct sieve_codegen_env *cgenv, struct sieve_command_context *cmd)
101485
 
+{
101486
 
+       struct cmd_test_message_context_data *ctx_data =
101487
 
+               (struct cmd_test_message_context_data *) cmd->data; 
101488
 
+
101489
 
+       i_assert( ctx_data->msg_source < MSG_SOURCE_LAST );
101490
 
+       
101491
 
+       /* Emit operation */
101492
 
+       sieve_operation_emit_code(cgenv->sbin, 
101493
 
+               test_message_operations[ctx_data->msg_source]);
101494
 
+
101495
 
+       /* Emit is_test flag */
101496
 
+       sieve_binary_emit_byte(cgenv->sbin, ( cmd->ast_node->type == SAT_TEST ));
101497
 
+               
101498
 
+       /* Generate arguments */
101499
 
+       if ( !sieve_generate_arguments(cgenv, cmd, NULL) )
101500
 
+               return FALSE;
101501
 
+
101502
 
+       return TRUE;
101503
 
+}
101504
 
+
101505
 
+/* 
101506
 
+ * Code dump
101507
 
+ */
101508
 
101509
 
+static bool cmd_test_message_smtp_operation_dump
101510
 
+(const struct sieve_operation *op ATTR_UNUSED,
101511
 
+       const struct sieve_dumptime_env *denv, sieve_size_t *address)
101512
 
+{
101513
 
+       unsigned int is_test;
101514
 
+
101515
 
+    if ( !sieve_binary_read_byte(denv->sbin, address, &is_test) )
101516
 
+               return FALSE;
101517
 
+
101518
 
+       sieve_code_dumpf(denv, "TEST_MESSAGE_SMTP (%s):", 
101519
 
+               ( is_test ? "TEST" : "COMMAND" ));
101520
 
+       
101521
 
+       sieve_code_descend(denv);
101522
 
+       
101523
 
+       return sieve_opr_number_dump(denv, address, "index");
101524
 
+}
101525
 
+
101526
 
+static bool cmd_test_message_mailbox_operation_dump
101527
 
+(const struct sieve_operation *op ATTR_UNUSED,
101528
 
+       const struct sieve_dumptime_env *denv, sieve_size_t *address)
101529
 
+{
101530
 
+       unsigned int is_test;
101531
 
+
101532
 
+    if ( !sieve_binary_read_byte(denv->sbin, address, &is_test) )
101533
 
+               return FALSE;
101534
 
+
101535
 
+       sieve_code_dumpf(denv, "TEST_MESSAGE_MAILBOX (%s):",
101536
 
+               ( is_test ? "TEST" : "COMMAND" ));
101537
 
+       
101538
 
+       sieve_code_descend(denv);
101539
 
+
101540
 
+       return 
101541
 
+               sieve_opr_string_dump(denv, address, "folder") &&
101542
 
+               sieve_opr_number_dump(denv, address, "index");
101543
 
+}
101544
 
+
101545
 
+/*
101546
 
+ * Intepretation
101547
 
+ */
101548
 
101549
 
+static int cmd_test_message_smtp_operation_execute
101550
 
+(const struct sieve_operation *op ATTR_UNUSED,
101551
 
+       const struct sieve_runtime_env *renv, sieve_size_t *address)
101552
 
+{
101553
 
+       sieve_number_t msg_index;
101554
 
+    unsigned int is_test = -1;
101555
 
+       bool result;
101556
 
+
101557
 
+       /* 
101558
 
+        * Read operands 
101559
 
+        */
101560
 
+
101561
 
+       /* Is test */
101562
 
+
101563
 
+    if ( !sieve_binary_read_byte(renv->sbin, address, &is_test) ) {
101564
 
+               sieve_runtime_trace_error(renv, "invalid is_test flag");
101565
 
+               return SIEVE_EXEC_BIN_CORRUPT;
101566
 
+       }
101567
 
+
101568
 
+       /* Index */
101569
 
+
101570
 
+       if ( !sieve_opr_number_read(renv, address, &msg_index) ) {
101571
 
+               sieve_runtime_trace_error(renv, "invalid index operand");
101572
 
+               return SIEVE_EXEC_BIN_CORRUPT;
101573
 
+       }
101574
 
+
101575
 
+       /*
101576
 
+        * Perform operation
101577
 
+        */
101578
 
+               
101579
 
+       sieve_runtime_trace(renv, "TEST_MESSAGE_SMTP (%s) [%d]", 
101580
 
+               ( is_test ? "TEST" : "COMMAND" ), msg_index);
101581
 
+
101582
 
+       result = testsuite_smtp_get(renv, msg_index);
101583
 
+
101584
 
+       if ( is_test ) {
101585
 
+               sieve_interpreter_set_test_result(renv->interp, result);
101586
 
+               return SIEVE_EXEC_OK;
101587
 
+       }
101588
 
+
101589
 
+       if ( !result )
101590
 
+               testsuite_test_failf("no outgoing SMTP message with index %d", msg_index);
101591
 
+
101592
 
+       return SIEVE_EXEC_OK;
101593
 
+}
101594
 
+
101595
 
+static int cmd_test_message_mailbox_operation_execute
101596
 
+(const struct sieve_operation *op ATTR_UNUSED,
101597
 
+       const struct sieve_runtime_env *renv, sieve_size_t *address)
101598
 
+{
101599
 
+       string_t *folder;
101600
 
+       sieve_number_t msg_index;
101601
 
+       unsigned int is_test = -1;
101602
 
+       bool result;
101603
 
+
101604
 
+       /*
101605
 
+        * Read operands
101606
 
+        */
101607
 
+
101608
 
+       /* Is test */
101609
 
+    if ( !sieve_binary_read_byte(renv->sbin, address, &is_test) ) {
101610
 
+               sieve_runtime_trace_error(renv, "invalid is_test flag");
101611
 
+               return SIEVE_EXEC_BIN_CORRUPT;
101612
 
+       }
101613
 
+
101614
 
+       /* Folder */
101615
 
+       if ( !sieve_opr_string_read(renv, address, &folder) ) {
101616
 
+               sieve_runtime_trace_error(renv, "invalid folder operand");
101617
 
+               return SIEVE_EXEC_BIN_CORRUPT;
101618
 
+       }
101619
 
+       
101620
 
+       /* Index */
101621
 
+       if ( !sieve_opr_number_read(renv, address, &msg_index) ) {
101622
 
+               sieve_runtime_trace_error(renv, "invalid index operand");
101623
 
+               return SIEVE_EXEC_BIN_CORRUPT;
101624
 
+       }
101625
 
+
101626
 
+       /*
101627
 
+        * Perform operation
101628
 
+        */
101629
 
+               
101630
 
+       sieve_runtime_trace(renv, "TEST_MESSAGE_MAILBOX (%s) \"%s\" [%d]", 
101631
 
+               ( is_test ? "TEST" : "COMMAND" ), str_c(folder), msg_index);
101632
 
+
101633
 
+       result = testsuite_mailstore_mail_index(renv, str_c(folder), msg_index);
101634
 
+
101635
 
+       if ( is_test ) {
101636
 
+               sieve_interpreter_set_test_result(renv->interp, result);
101637
 
+               return SIEVE_EXEC_OK;
101638
 
+       }
101639
 
+
101640
 
+       if ( !result )
101641
 
+               testsuite_test_failf("no outgoing SMTP message with index %d", msg_index);
101642
 
+
101643
 
+       return SIEVE_EXEC_OK;
101644
 
+}
101645
 
+
101646
 
+
101647
 
+
101648
 
+
101649
 
+
101650
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/testsuite/cmd-test-result-print.c dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/cmd-test-result-print.c
101651
 
--- dovecot-1.2.4/dovecot-libsieve/src/testsuite/cmd-test-result-print.c        1970-01-01 01:00:00.000000000 +0100
101652
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/cmd-test-result-print.c 2009-01-06 00:15:52.000000000 +0100
101653
 
@@ -0,0 +1,82 @@
101654
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
101655
 
+ */
101656
 
+
101657
 
+#include "sieve-common.h"
101658
 
+#include "sieve-script.h"
101659
 
+#include "sieve-commands.h"
101660
 
+#include "sieve-validator.h"
101661
 
+#include "sieve-generator.h"
101662
 
+#include "sieve-interpreter.h"
101663
 
+#include "sieve-code.h"
101664
 
+#include "sieve-binary.h"
101665
 
+#include "sieve-dump.h"
101666
 
+#include "sieve.h"
101667
 
+
101668
 
+#include "testsuite-common.h"
101669
 
+#include "testsuite-result.h"
101670
 
+
101671
 
+/*
101672
 
+ * Test_result_execute command
101673
 
+ *
101674
 
+ * Syntax:   
101675
 
+ *   test_result_execute
101676
 
+ */
101677
 
+
101678
 
+static bool cmd_test_result_print_generate
101679
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx);
101680
 
+
101681
 
+const struct sieve_command cmd_test_result_print = { 
101682
 
+       "test_result_print", 
101683
 
+       SCT_COMMAND, 
101684
 
+       0, 0, FALSE, FALSE,
101685
 
+       NULL, NULL, NULL,
101686
 
+       cmd_test_result_print_generate, 
101687
 
+       NULL 
101688
 
+};
101689
 
+
101690
 
+/* 
101691
 
+ * Operation 
101692
 
+ */
101693
 
+
101694
 
+static int cmd_test_result_print_operation_execute
101695
 
+       (const struct sieve_operation *op, 
101696
 
+               const struct sieve_runtime_env *renv, sieve_size_t *address);
101697
 
+
101698
 
+const struct sieve_operation test_result_print_operation = { 
101699
 
+       "TEST_RESULT_PRINT",
101700
 
+       &testsuite_extension, 
101701
 
+       TESTSUITE_OPERATION_TEST_RESULT_PRINT,
101702
 
+       NULL, 
101703
 
+       cmd_test_result_print_operation_execute 
101704
 
+};
101705
 
+
101706
 
+/* 
101707
 
+ * Code generation 
101708
 
+ */
101709
 
+
101710
 
+static bool cmd_test_result_print_generate
101711
 
+(const struct sieve_codegen_env *cgenv, 
101712
 
+       struct sieve_command_context *tst ATTR_UNUSED)
101713
 
+{
101714
 
+       sieve_operation_emit_code(cgenv->sbin, &test_result_print_operation);
101715
 
+
101716
 
+       return TRUE;
101717
 
+}
101718
 
+
101719
 
+/*
101720
 
+ * Intepretation
101721
 
+ */
101722
 
+
101723
 
+static int cmd_test_result_print_operation_execute
101724
 
+(const struct sieve_operation *op ATTR_UNUSED,
101725
 
+       const struct sieve_runtime_env *renv, 
101726
 
+       sieve_size_t *address ATTR_UNUSED)
101727
 
+{
101728
 
+       testsuite_result_print(renv);
101729
 
+
101730
 
+       return SIEVE_EXEC_OK;
101731
 
+}
101732
 
+
101733
 
+
101734
 
+
101735
 
+
101736
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/testsuite/cmd-test-result-reset.c dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/cmd-test-result-reset.c
101737
 
--- dovecot-1.2.4/dovecot-libsieve/src/testsuite/cmd-test-result-reset.c        1970-01-01 01:00:00.000000000 +0100
101738
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/cmd-test-result-reset.c 2009-02-11 21:38:58.000000000 +0100
101739
 
@@ -0,0 +1,84 @@
101740
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
101741
 
+ */
101742
 
+
101743
 
+#include "sieve-common.h"
101744
 
+#include "sieve-script.h"
101745
 
+#include "sieve-commands.h"
101746
 
+#include "sieve-validator.h"
101747
 
+#include "sieve-generator.h"
101748
 
+#include "sieve-interpreter.h"
101749
 
+#include "sieve-code.h"
101750
 
+#include "sieve-binary.h"
101751
 
+#include "sieve-dump.h"
101752
 
+#include "sieve.h"
101753
 
+
101754
 
+#include "testsuite-common.h"
101755
 
+#include "testsuite-result.h"
101756
 
+#include "testsuite-smtp.h"
101757
 
+
101758
 
+/*
101759
 
+ * Test_result_execute command
101760
 
+ *
101761
 
+ * Syntax:   
101762
 
+ *   test_result_execute
101763
 
+ */
101764
 
+
101765
 
+static bool cmd_test_result_reset_generate
101766
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx);
101767
 
+
101768
 
+const struct sieve_command cmd_test_result_reset = { 
101769
 
+       "test_result_reset", 
101770
 
+       SCT_COMMAND, 
101771
 
+       0, 0, FALSE, FALSE,
101772
 
+       NULL, NULL, NULL,
101773
 
+       cmd_test_result_reset_generate, 
101774
 
+       NULL 
101775
 
+};
101776
 
+
101777
 
+/* 
101778
 
+ * Operation 
101779
 
+ */
101780
 
+
101781
 
+static int cmd_test_result_reset_operation_execute
101782
 
+       (const struct sieve_operation *op, 
101783
 
+               const struct sieve_runtime_env *renv, sieve_size_t *address);
101784
 
+
101785
 
+const struct sieve_operation test_result_reset_operation = { 
101786
 
+       "TEST_RESULT_RESET",
101787
 
+       &testsuite_extension, 
101788
 
+       TESTSUITE_OPERATION_TEST_RESULT_RESET,
101789
 
+       NULL, 
101790
 
+       cmd_test_result_reset_operation_execute 
101791
 
+};
101792
 
+
101793
 
+/* 
101794
 
+ * Code generation 
101795
 
+ */
101796
 
+
101797
 
+static bool cmd_test_result_reset_generate
101798
 
+(const struct sieve_codegen_env *cgenv, 
101799
 
+       struct sieve_command_context *tst ATTR_UNUSED)
101800
 
+{
101801
 
+       sieve_operation_emit_code(cgenv->sbin, &test_result_reset_operation);
101802
 
+
101803
 
+       return TRUE;
101804
 
+}
101805
 
+
101806
 
+/*
101807
 
+ * Intepretation
101808
 
+ */
101809
 
+
101810
 
+static int cmd_test_result_reset_operation_execute
101811
 
+(const struct sieve_operation *op ATTR_UNUSED,
101812
 
+       const struct sieve_runtime_env *renv,
101813
 
+       sieve_size_t *address ATTR_UNUSED)
101814
 
+{
101815
 
+       testsuite_result_reset(renv);
101816
 
+       testsuite_smtp_reset();
101817
 
+
101818
 
+       return SIEVE_EXEC_OK;
101819
 
+}
101820
 
+
101821
 
+
101822
 
+
101823
 
+
101824
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/testsuite/cmd-test-set.c dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/cmd-test-set.c
101825
 
--- dovecot-1.2.4/dovecot-libsieve/src/testsuite/cmd-test-set.c 1970-01-01 01:00:00.000000000 +0100
101826
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/cmd-test-set.c  2009-01-06 00:15:52.000000000 +0100
101827
 
@@ -0,0 +1,160 @@
101828
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
101829
 
+ */
101830
 
+
101831
 
+#include "lib.h"
101832
 
+#include "ioloop.h"
101833
 
+#include "str-sanitize.h"
101834
 
+#include "istream.h"
101835
 
+#include "istream-header-filter.h"
101836
 
+
101837
 
+#include "sieve-common.h"
101838
 
+#include "sieve-commands.h"
101839
 
+#include "sieve-code.h"
101840
 
+#include "sieve-actions.h"
101841
 
+#include "sieve-validator.h" 
101842
 
+#include "sieve-generator.h"
101843
 
+#include "sieve-interpreter.h"
101844
 
+#include "sieve-code-dumper.h"
101845
 
+#include "sieve-result.h"
101846
 
+
101847
 
+#include "testsuite-common.h"
101848
 
+#include "testsuite-objects.h"
101849
 
+
101850
 
+#include <stdio.h>
101851
 
+
101852
 
+/* 
101853
 
+ * Test_set command 
101854
 
+ * 
101855
 
+ * Syntax
101856
 
+ *   test_set <testsuite object (member): string> <value: string>
101857
 
+ */
101858
 
+
101859
 
+static bool cmd_test_set_validate
101860
 
+       (struct sieve_validator *validator, struct sieve_command_context *cmd);
101861
 
+static bool cmd_test_set_generate
101862
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx);
101863
 
+
101864
 
+const struct sieve_command cmd_test_set = { 
101865
 
+       "test_set", 
101866
 
+       SCT_COMMAND,
101867
 
+       2, 0, FALSE, FALSE, 
101868
 
+       NULL, NULL,
101869
 
+       cmd_test_set_validate, 
101870
 
+       cmd_test_set_generate, 
101871
 
+       NULL 
101872
 
+};
101873
 
+
101874
 
+/* 
101875
 
+ * Test_set operation 
101876
 
+ */
101877
 
+
101878
 
+static bool cmd_test_set_operation_dump
101879
 
+       (const struct sieve_operation *op,
101880
 
+               const struct sieve_dumptime_env *denv, sieve_size_t *address);
101881
 
+static int cmd_test_set_operation_execute
101882
 
+       (const struct sieve_operation *op, 
101883
 
+               const struct sieve_runtime_env *renv, sieve_size_t *address);
101884
 
+
101885
 
+const struct sieve_operation test_set_operation = { 
101886
 
+       "TEST_SET",
101887
 
+       &testsuite_extension, 
101888
 
+       TESTSUITE_OPERATION_TEST_SET,
101889
 
+       cmd_test_set_operation_dump, 
101890
 
+       cmd_test_set_operation_execute 
101891
 
+};
101892
 
+
101893
 
+/* 
101894
 
+ * Validation 
101895
 
+ */
101896
 
101897
 
+static bool cmd_test_set_validate
101898
 
+(struct sieve_validator *valdtr, struct sieve_command_context *cmd) 
101899
 
+{
101900
 
+       struct sieve_ast_argument *arg = cmd->first_positional;
101901
 
+
101902
 
+       /* Check arguments */
101903
 
+       
101904
 
+       if ( !sieve_validate_positional_argument
101905
 
+               (valdtr, cmd, arg, "object", 1, SAAT_STRING) ) {
101906
 
+               return FALSE;
101907
 
+       }
101908
 
+       
101909
 
+       if ( !testsuite_object_argument_activate(valdtr, arg, cmd) )
101910
 
+               return FALSE;
101911
 
+       
101912
 
+       arg = sieve_ast_argument_next(arg);
101913
 
+       
101914
 
+       if ( !sieve_validate_positional_argument
101915
 
+               (valdtr, cmd, arg, "value", 2, SAAT_STRING) ) {
101916
 
+               return FALSE;
101917
 
+       }
101918
 
+       
101919
 
+       return sieve_validator_argument_activate(valdtr, cmd, arg, FALSE);
101920
 
+}
101921
 
+
101922
 
+/*
101923
 
+ * Code generation
101924
 
+ */
101925
 
101926
 
+static bool cmd_test_set_generate
101927
 
+(const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx) 
101928
 
+{
101929
 
+       sieve_operation_emit_code(cgenv->sbin, &test_set_operation);
101930
 
+
101931
 
+       /* Generate arguments */
101932
 
+       return sieve_generate_arguments(cgenv, ctx, NULL);
101933
 
+}
101934
 
+
101935
 
+/* 
101936
 
+ * Code dump
101937
 
+ */
101938
 
101939
 
+static bool cmd_test_set_operation_dump
101940
 
+(const struct sieve_operation *op ATTR_UNUSED,
101941
 
+       const struct sieve_dumptime_env *denv, sieve_size_t *address)
101942
 
+{
101943
 
+       sieve_code_dumpf(denv, "TEST SET:");
101944
 
+       sieve_code_descend(denv);
101945
 
+
101946
 
+       return 
101947
 
+               testsuite_object_dump(denv, address) &&
101948
 
+               sieve_opr_string_dump(denv, address, "value");
101949
 
+}
101950
 
+
101951
 
+/*
101952
 
+ * Intepretation
101953
 
+ */
101954
 
+
101955
 
+static int cmd_test_set_operation_execute
101956
 
+(const struct sieve_operation *op ATTR_UNUSED,
101957
 
+       const struct sieve_runtime_env *renv, sieve_size_t *address)
101958
 
+{
101959
 
+       const struct testsuite_object *object;
101960
 
+       string_t *value;
101961
 
+       int member_id;
101962
 
+
101963
 
+       if ( (object=testsuite_object_read_member(renv->sbin, address, &member_id)) 
101964
 
+               == NULL ) {
101965
 
+               sieve_runtime_trace_error(renv, "invalid testsuite object member");
101966
 
+               return SIEVE_EXEC_BIN_CORRUPT;
101967
 
+       }
101968
 
+
101969
 
+       if ( !sieve_opr_string_read(renv, address, &value) ) {
101970
 
+               sieve_runtime_trace_error(renv, "invalid string operand");
101971
 
+               return SIEVE_EXEC_BIN_CORRUPT;
101972
 
+       }
101973
 
+
101974
 
+       sieve_runtime_trace(renv, "TEST SET command (%s = \"%s\")", 
101975
 
+               testsuite_object_member_name(object, member_id), str_c(value));
101976
 
+       
101977
 
+       if ( object->set_member == NULL ) {
101978
 
+               sieve_runtime_trace_error(renv, "unimplemented testsuite object");
101979
 
+               return SIEVE_EXEC_FAILURE;
101980
 
+       }
101981
 
+               
101982
 
+       object->set_member(renv, member_id, value);     
101983
 
+       return SIEVE_EXEC_OK;
101984
 
+}
101985
 
+
101986
 
+
101987
 
+
101988
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/testsuite/ext-testsuite.c dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/ext-testsuite.c
101989
 
--- dovecot-1.2.4/dovecot-libsieve/src/testsuite/ext-testsuite.c        1970-01-01 01:00:00.000000000 +0100
101990
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/ext-testsuite.c 2009-08-21 00:52:15.000000000 +0200
101991
 
@@ -0,0 +1,146 @@
101992
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
101993
 
+ */
101994
 
+
101995
 
+/* Extension testsuite
101996
 
+ * -------------------
101997
 
+ *
101998
 
+ * Authors: Stephan Bosch
101999
 
+ * Specification: vendor-specific 
102000
 
+ *   (FIXME: provide specification for test authors)
102001
 
+ * Implementation: very basic
102002
 
+ * Status: under development
102003
 
+ * Purpose: This custom extension is used to add sieve commands and tests that 
102004
 
+ *          act the Sieve engine and on the test suite itself. This practically 
102005
 
+ *          provides the means to completely control and thereby test the Sieve 
102006
 
+ *          compiler and interpreter. This extension transforms the basic Sieve 
102007
 
+ *          language into something much more powerful and suitable to perform 
102008
 
+ *          complex self-test operations. Of course, this extension is only 
102009
 
+ *          available (as vnd.dovecot.testsuite) when the sieve engine is used
102010
 
+ *          from within the testsuite commandline tool. Test scripts have the
102011
 
+ *          extension .svtest by convention to distinguish them from any normal
102012
 
+ *          sieve scripts that may reside in the same directory. 
102013
 
+ *
102014
 
+ * WARNING: Although this code can serve as an example on how to write extensions 
102015
 
+ *          to the Sieve interpreter, it is generally _NOT_ to be used as a source 
102016
 
+ *          for ideas on new Sieve extensions. Many of the commands and tests that 
102017
 
+ *          this extension introduces conflict with the goal and the implied 
102018
 
+ *          restrictions of the Sieve language. These restrictions were put in 
102019
 
+ *          place with good reason. Therefore, do _NOT_ export functionality 
102020
 
+ *          provided by this testsuite extension to your custom extensions that are 
102021
 
+ *          to be put to general use. 
102022
 
+ *
102023
 
+ *          Thank you.
102024
 
+ */
102025
 
+
102026
 
+#include <stdio.h>
102027
 
+
102028
 
+#include "sieve-common.h"
102029
 
+
102030
 
+#include "sieve-code.h"
102031
 
+#include "sieve-extensions.h"
102032
 
+#include "sieve-commands.h"
102033
 
+#include "sieve-validator.h"
102034
 
+#include "sieve-generator.h"
102035
 
+#include "sieve-interpreter.h"
102036
 
+#include "sieve-result.h"
102037
 
+
102038
 
+#include "testsuite-common.h"
102039
 
+#include "testsuite-arguments.h"
102040
 
+
102041
 
+/* 
102042
 
+ * Operations 
102043
 
+ */
102044
 
+
102045
 
+const struct sieve_operation *testsuite_operations[] = { 
102046
 
+       &test_operation, 
102047
 
+       &test_finish_operation,
102048
 
+       &test_fail_operation, 
102049
 
+       &test_set_operation,
102050
 
+       &test_script_compile_operation,
102051
 
+       &test_script_run_operation,
102052
 
+       &test_error_operation,
102053
 
+       &test_result_operation,
102054
 
+       &test_result_execute_operation,
102055
 
+       &test_result_reset_operation,
102056
 
+       &test_result_print_operation,
102057
 
+       &test_message_smtp_operation,
102058
 
+       &test_message_mailbox_operation,
102059
 
+       &test_mailbox_create_operation,
102060
 
+       &test_mailbox_delete_operation,
102061
 
+       &test_binary_load_operation,
102062
 
+       &test_binary_save_operation
102063
 
+};
102064
 
+
102065
 
+/* 
102066
 
+ * Operands 
102067
 
+ */
102068
 
+
102069
 
+const struct sieve_operand *testsuite_operands[] = { 
102070
 
+       &testsuite_object_operand,
102071
 
+       &testsuite_substitution_operand
102072
 
+};
102073
 
+    
102074
 
+/* 
102075
 
+ * Extension
102076
 
+ */
102077
 
+
102078
 
+/* Forward declarations */
102079
 
+
102080
 
+static bool ext_testsuite_validator_load(struct sieve_validator *valdtr);
102081
 
+static bool ext_testsuite_generator_load(const struct sieve_codegen_env *cgenv);
102082
 
+static bool ext_testsuite_binary_load(struct sieve_binary *sbin);
102083
 
+
102084
 
+/* Extension object */
102085
 
+
102086
 
+static int ext_my_id = -1;
102087
 
+
102088
 
+const struct sieve_extension testsuite_extension = { 
102089
 
+       "vnd.dovecot.testsuite", 
102090
 
+       &ext_my_id,
102091
 
+       NULL, NULL,
102092
 
+       ext_testsuite_validator_load,
102093
 
+       ext_testsuite_generator_load,
102094
 
+       NULL,
102095
 
+       ext_testsuite_binary_load, 
102096
 
+       NULL, NULL,
102097
 
+       SIEVE_EXT_DEFINE_OPERATIONS(testsuite_operations),
102098
 
+       SIEVE_EXT_DEFINE_OPERANDS(testsuite_operands)
102099
 
+};
102100
 
+
102101
 
+/* Extension implementation */
102102
 
+
102103
 
+static bool ext_testsuite_validator_load(struct sieve_validator *valdtr)
102104
 
+{
102105
 
+       sieve_validator_register_command(valdtr, &cmd_test);
102106
 
+       sieve_validator_register_command(valdtr, &cmd_test_fail);
102107
 
+       sieve_validator_register_command(valdtr, &cmd_test_set);
102108
 
+       sieve_validator_register_command(valdtr, &cmd_test_result_print);
102109
 
+       sieve_validator_register_command(valdtr, &cmd_test_result_reset);
102110
 
+       sieve_validator_register_command(valdtr, &cmd_test_message);
102111
 
+       sieve_validator_register_command(valdtr, &cmd_test_mailbox);
102112
 
+       sieve_validator_register_command(valdtr, &cmd_test_binary);
102113
 
+
102114
 
+       sieve_validator_register_command(valdtr, &tst_test_script_compile);
102115
 
+       sieve_validator_register_command(valdtr, &tst_test_script_run);
102116
 
+       sieve_validator_register_command(valdtr, &tst_test_error);
102117
 
+       sieve_validator_register_command(valdtr, &tst_test_result);     
102118
 
+       sieve_validator_register_command(valdtr, &tst_test_result_execute);     
102119
 
+
102120
 
+       sieve_validator_argument_override(valdtr, SAT_VAR_STRING,
102121
 
+               &testsuite_string_argument);
102122
 
+
102123
 
+       return testsuite_validator_context_initialize(valdtr);
102124
 
+}
102125
 
+
102126
 
+static bool ext_testsuite_generator_load(const struct sieve_codegen_env *cgenv)
102127
 
+{
102128
 
+       return testsuite_generator_context_initialize(cgenv->gentr);
102129
 
+}
102130
 
+
102131
 
+static bool ext_testsuite_binary_load(struct sieve_binary *sbin ATTR_UNUSED)
102132
 
+{
102133
 
+       return TRUE;
102134
 
+}
102135
 
+
102136
 
+
102137
 
+
102138
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/testsuite/Makefile.am dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/Makefile.am
102139
 
--- dovecot-1.2.4/dovecot-libsieve/src/testsuite/Makefile.am    1970-01-01 01:00:00.000000000 +0100
102140
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/Makefile.am     2009-08-21 00:52:15.000000000 +0200
102141
 
@@ -0,0 +1,75 @@
102142
 
+noinst_PROGRAMS = testsuite
102143
 
+
102144
 
+AM_CPPFLAGS = \
102145
 
+       -I../lib-sieve \
102146
 
+       -I../lib-sieve-tool \
102147
 
+       -I$(dovecot_incdir) \
102148
 
+       -I$(dovecot_incdir)/src/lib \
102149
 
+       -I$(dovecot_incdir)/src/lib-mail \
102150
 
+       -I$(dovecot_incdir)/src/lib-index \
102151
 
+       -I$(dovecot_incdir)/src/lib-storage
102152
 
+
102153
 
+testsuite_LDFLAGS = -export-dynamic
102154
 
+
102155
 
+libs = \
102156
 
+       $(top_srcdir)/src/lib-sieve/libsieve.la \
102157
 
+       $(top_srcdir)/src/lib-sieve-tool/libsieve-tool.la \
102158
 
+       $(STORAGE_LIBS)
102159
 
+
102160
 
+ldadd = \
102161
 
+       $(libs) \
102162
 
+       $(LIBICONV) \
102163
 
+       $(RAND_LIBS) \
102164
 
+       $(MODULE_LIBS)
102165
 
+
102166
 
+testsuite_LDADD = $(ldadd)
102167
 
+testsuite_DEPENDENCIES = $(libs)
102168
 
+
102169
 
+commands = \
102170
 
+       cmd-test.c \
102171
 
+       cmd-test-fail.c \
102172
 
+       cmd-test-set.c \
102173
 
+       cmd-test-result-reset.c \
102174
 
+       cmd-test-result-print.c \
102175
 
+       cmd-test-message.c \
102176
 
+       cmd-test-mailbox.c \
102177
 
+       cmd-test-binary.c
102178
 
+
102179
 
+
102180
 
+tests = \
102181
 
+       tst-test-script-compile.c \
102182
 
+       tst-test-script-run.c \
102183
 
+       tst-test-error.c \
102184
 
+       tst-test-result.c \
102185
 
+       tst-test-result-execute.c
102186
 
+
102187
 
+testsuite_SOURCES = \
102188
 
+       testsuite-common.c \
102189
 
+       testsuite-objects.c \
102190
 
+       testsuite-substitutions.c \
102191
 
+       testsuite-arguments.c \
102192
 
+       testsuite-message.c \
102193
 
+       testsuite-log.c \
102194
 
+       testsuite-script.c \
102195
 
+       testsuite-result.c \
102196
 
+       testsuite-smtp.c \
102197
 
+       testsuite-mailstore.c \
102198
 
+       testsuite-binary.c \
102199
 
+       $(commands) \
102200
 
+       $(tests) \
102201
 
+       ext-testsuite.c \
102202
 
+       testsuite.c
102203
 
+
102204
 
+noinst_HEADERS = \
102205
 
+       testsuite-common.h \
102206
 
+       testsuite-objects.h \
102207
 
+       testsuite-substitutions.h \
102208
 
+       testsuite-arguments.h \
102209
 
+       testsuite-message.h \
102210
 
+       testsuite-log.h \
102211
 
+       testsuite-script.h \
102212
 
+       testsuite-result.h \
102213
 
+       testsuite-smtp.h \
102214
 
+       testsuite-mailstore.h \
102215
 
+       testsuite-binary.h
102216
 
+
102217
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/testsuite/Makefile.in dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/Makefile.in
102218
 
--- dovecot-1.2.4/dovecot-libsieve/src/testsuite/Makefile.in    1970-01-01 01:00:00.000000000 +0100
102219
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/Makefile.in     2009-08-21 00:55:44.000000000 +0200
102220
 
@@ -0,0 +1,562 @@
102221
 
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
102222
 
+# @configure_input@
102223
 
+
102224
 
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
102225
 
+# 2003, 2004, 2005, 2006, 2007, 2008  Free Software Foundation, Inc.
102226
 
+# This Makefile.in is free software; the Free Software Foundation
102227
 
+# gives unlimited permission to copy and/or distribute it,
102228
 
+# with or without modifications, as long as this notice is preserved.
102229
 
+
102230
 
+# This program is distributed in the hope that it will be useful,
102231
 
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
102232
 
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
102233
 
+# PARTICULAR PURPOSE.
102234
 
+
102235
 
+@SET_MAKE@
102236
 
+
102237
 
+
102238
 
+VPATH = @srcdir@
102239
 
+pkgdatadir = $(datadir)/@PACKAGE@
102240
 
+pkglibdir = $(libdir)/@PACKAGE@
102241
 
+pkgincludedir = $(includedir)/@PACKAGE@
102242
 
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
102243
 
+install_sh_DATA = $(install_sh) -c -m 644
102244
 
+install_sh_PROGRAM = $(install_sh) -c
102245
 
+install_sh_SCRIPT = $(install_sh) -c
102246
 
+INSTALL_HEADER = $(INSTALL_DATA)
102247
 
+transform = $(program_transform_name)
102248
 
+NORMAL_INSTALL = :
102249
 
+PRE_INSTALL = :
102250
 
+POST_INSTALL = :
102251
 
+NORMAL_UNINSTALL = :
102252
 
+PRE_UNINSTALL = :
102253
 
+POST_UNINSTALL = :
102254
 
+build_triplet = @build@
102255
 
+host_triplet = @host@
102256
 
+noinst_PROGRAMS = testsuite$(EXEEXT)
102257
 
+subdir = src/testsuite
102258
 
+DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
102259
 
+       $(srcdir)/Makefile.in
102260
 
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
102261
 
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
102262
 
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
102263
 
+       $(ACLOCAL_M4)
102264
 
+mkinstalldirs = $(install_sh) -d
102265
 
+CONFIG_HEADER = $(top_builddir)/dummy-config.h \
102266
 
+       $(top_builddir)/dsieve-config.h
102267
 
+CONFIG_CLEAN_FILES =
102268
 
+PROGRAMS = $(noinst_PROGRAMS)
102269
 
+am__objects_1 = cmd-test.$(OBJEXT) cmd-test-fail.$(OBJEXT) \
102270
 
+       cmd-test-set.$(OBJEXT) cmd-test-result-reset.$(OBJEXT) \
102271
 
+       cmd-test-result-print.$(OBJEXT) cmd-test-message.$(OBJEXT) \
102272
 
+       cmd-test-mailbox.$(OBJEXT) cmd-test-binary.$(OBJEXT)
102273
 
+am__objects_2 = tst-test-script-compile.$(OBJEXT) \
102274
 
+       tst-test-script-run.$(OBJEXT) tst-test-error.$(OBJEXT) \
102275
 
+       tst-test-result.$(OBJEXT) tst-test-result-execute.$(OBJEXT)
102276
 
+am_testsuite_OBJECTS = testsuite-common.$(OBJEXT) \
102277
 
+       testsuite-objects.$(OBJEXT) testsuite-substitutions.$(OBJEXT) \
102278
 
+       testsuite-arguments.$(OBJEXT) testsuite-message.$(OBJEXT) \
102279
 
+       testsuite-log.$(OBJEXT) testsuite-script.$(OBJEXT) \
102280
 
+       testsuite-result.$(OBJEXT) testsuite-smtp.$(OBJEXT) \
102281
 
+       testsuite-mailstore.$(OBJEXT) testsuite-binary.$(OBJEXT) \
102282
 
+       $(am__objects_1) $(am__objects_2) ext-testsuite.$(OBJEXT) \
102283
 
+       testsuite.$(OBJEXT)
102284
 
+testsuite_OBJECTS = $(am_testsuite_OBJECTS)
102285
 
+am__DEPENDENCIES_1 =
102286
 
+am__DEPENDENCIES_2 = $(top_srcdir)/src/lib-sieve/libsieve.la \
102287
 
+       $(top_srcdir)/src/lib-sieve-tool/libsieve-tool.la \
102288
 
+       $(am__DEPENDENCIES_1)
102289
 
+am__DEPENDENCIES_3 = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1) \
102290
 
+       $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
102291
 
+testsuite_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
102292
 
+       $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
102293
 
+       $(testsuite_LDFLAGS) $(LDFLAGS) -o $@
102294
 
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
102295
 
+depcomp = $(SHELL) $(top_srcdir)/depcomp
102296
 
+am__depfiles_maybe = depfiles
102297
 
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
102298
 
+       $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
102299
 
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
102300
 
+       --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
102301
 
+       $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
102302
 
+CCLD = $(CC)
102303
 
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
102304
 
+       --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
102305
 
+       $(LDFLAGS) -o $@
102306
 
+SOURCES = $(testsuite_SOURCES)
102307
 
+DIST_SOURCES = $(testsuite_SOURCES)
102308
 
+HEADERS = $(noinst_HEADERS)
102309
 
+ETAGS = etags
102310
 
+CTAGS = ctags
102311
 
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
102312
 
+ACLOCAL = @ACLOCAL@
102313
 
+AMTAR = @AMTAR@
102314
 
+AR = @AR@
102315
 
+AUTOCONF = @AUTOCONF@
102316
 
+AUTOHEADER = @AUTOHEADER@
102317
 
+AUTOMAKE = @AUTOMAKE@
102318
 
+AWK = @AWK@
102319
 
+CC = @CC@
102320
 
+CCDEPMODE = @CCDEPMODE@
102321
 
+CFLAGS = @CFLAGS@
102322
 
+CPP = @CPP@
102323
 
+CPPFLAGS = @CPPFLAGS@
102324
 
+CYGPATH_W = @CYGPATH_W@
102325
 
+DEFS = @DEFS@
102326
 
+DEPDIR = @DEPDIR@
102327
 
+DSYMUTIL = @DSYMUTIL@
102328
 
+DUMPBIN = @DUMPBIN@
102329
 
+ECHO_C = @ECHO_C@
102330
 
+ECHO_N = @ECHO_N@
102331
 
+ECHO_T = @ECHO_T@
102332
 
+EGREP = @EGREP@
102333
 
+EXEEXT = @EXEEXT@
102334
 
+FGREP = @FGREP@
102335
 
+GREP = @GREP@
102336
 
+INSTALL = @INSTALL@
102337
 
+INSTALL_DATA = @INSTALL_DATA@
102338
 
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
102339
 
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
102340
 
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
102341
 
+LD = @LD@
102342
 
+LDFLAGS = @LDFLAGS@
102343
 
+LIBICONV = @LIBICONV@
102344
 
+LIBOBJS = @LIBOBJS@
102345
 
+LIBS = @LIBS@
102346
 
+LIBTOOL = @LIBTOOL@
102347
 
+LIPO = @LIPO@
102348
 
+LN_S = @LN_S@
102349
 
+LTLIBOBJS = @LTLIBOBJS@
102350
 
+MAINT = @MAINT@
102351
 
+MAKEINFO = @MAKEINFO@
102352
 
+MKDIR_P = @MKDIR_P@
102353
 
+MODULE_LIBS = @MODULE_LIBS@
102354
 
+NM = @NM@
102355
 
+NMEDIT = @NMEDIT@
102356
 
+OBJDUMP = @OBJDUMP@
102357
 
+OBJEXT = @OBJEXT@
102358
 
+OTOOL = @OTOOL@
102359
 
+OTOOL64 = @OTOOL64@
102360
 
+PACKAGE = @PACKAGE@
102361
 
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
102362
 
+PACKAGE_NAME = @PACKAGE_NAME@
102363
 
+PACKAGE_STRING = @PACKAGE_STRING@
102364
 
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
102365
 
+PACKAGE_URL = @PACKAGE_URL@
102366
 
+PACKAGE_VERSION = @PACKAGE_VERSION@
102367
 
+PATH_SEPARATOR = @PATH_SEPARATOR@
102368
 
+RAND_LIBS = @RAND_LIBS@
102369
 
+RANLIB = @RANLIB@
102370
 
+SED = @SED@
102371
 
+SET_MAKE = @SET_MAKE@
102372
 
+SHELL = @SHELL@
102373
 
+STORAGE_LIBS = @STORAGE_LIBS@
102374
 
+STRIP = @STRIP@
102375
 
+VERSION = @VERSION@
102376
 
+abs_builddir = @abs_builddir@
102377
 
+abs_srcdir = @abs_srcdir@
102378
 
+abs_top_builddir = @abs_top_builddir@
102379
 
+abs_top_srcdir = @abs_top_srcdir@
102380
 
+ac_ct_CC = @ac_ct_CC@
102381
 
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
102382
 
+am__include = @am__include@
102383
 
+am__leading_dot = @am__leading_dot@
102384
 
+am__quote = @am__quote@
102385
 
+am__tar = @am__tar@
102386
 
+am__untar = @am__untar@
102387
 
+bindir = @bindir@
102388
 
+build = @build@
102389
 
+build_alias = @build_alias@
102390
 
+build_cpu = @build_cpu@
102391
 
+build_os = @build_os@
102392
 
+build_vendor = @build_vendor@
102393
 
+builddir = @builddir@
102394
 
+datadir = @datadir@
102395
 
+datarootdir = @datarootdir@
102396
 
+docdir = @docdir@
102397
 
+dovecot_incdir = @dovecot_incdir@
102398
 
+dovecotdir = @dovecotdir@
102399
 
+dvidir = @dvidir@
102400
 
+exec_prefix = @exec_prefix@
102401
 
+host = @host@
102402
 
+host_alias = @host_alias@
102403
 
+host_cpu = @host_cpu@
102404
 
+host_os = @host_os@
102405
 
+host_vendor = @host_vendor@
102406
 
+htmldir = @htmldir@
102407
 
+includedir = @includedir@
102408
 
+infodir = @infodir@
102409
 
+install_sh = @install_sh@
102410
 
+libdir = @libdir@
102411
 
+libexecdir = @libexecdir@
102412
 
+localedir = @localedir@
102413
 
+localstatedir = @localstatedir@
102414
 
+lt_ECHO = @lt_ECHO@
102415
 
+mandir = @mandir@
102416
 
+mkdir_p = @mkdir_p@
102417
 
+moduledir = @moduledir@
102418
 
+oldincludedir = @oldincludedir@
102419
 
+pdfdir = @pdfdir@
102420
 
+prefix = @prefix@
102421
 
+program_transform_name = @program_transform_name@
102422
 
+psdir = @psdir@
102423
 
+sbindir = @sbindir@
102424
 
+sharedstatedir = @sharedstatedir@
102425
 
+srcdir = @srcdir@
102426
 
+sysconfdir = @sysconfdir@
102427
 
+target_alias = @target_alias@
102428
 
+top_build_prefix = @top_build_prefix@
102429
 
+top_builddir = @top_builddir@
102430
 
+top_srcdir = @top_srcdir@
102431
 
+AM_CPPFLAGS = \
102432
 
+       -I../lib-sieve \
102433
 
+       -I../lib-sieve-tool \
102434
 
+       -I$(dovecot_incdir) \
102435
 
+       -I$(dovecot_incdir)/src/lib \
102436
 
+       -I$(dovecot_incdir)/src/lib-mail \
102437
 
+       -I$(dovecot_incdir)/src/lib-index \
102438
 
+       -I$(dovecot_incdir)/src/lib-storage
102439
 
+
102440
 
+testsuite_LDFLAGS = -export-dynamic
102441
 
+libs = \
102442
 
+       $(top_srcdir)/src/lib-sieve/libsieve.la \
102443
 
+       $(top_srcdir)/src/lib-sieve-tool/libsieve-tool.la \
102444
 
+       $(STORAGE_LIBS)
102445
 
+
102446
 
+ldadd = \
102447
 
+       $(libs) \
102448
 
+       $(LIBICONV) \
102449
 
+       $(RAND_LIBS) \
102450
 
+       $(MODULE_LIBS)
102451
 
+
102452
 
+testsuite_LDADD = $(ldadd)
102453
 
+testsuite_DEPENDENCIES = $(libs)
102454
 
+commands = \
102455
 
+       cmd-test.c \
102456
 
+       cmd-test-fail.c \
102457
 
+       cmd-test-set.c \
102458
 
+       cmd-test-result-reset.c \
102459
 
+       cmd-test-result-print.c \
102460
 
+       cmd-test-message.c \
102461
 
+       cmd-test-mailbox.c \
102462
 
+       cmd-test-binary.c
102463
 
+
102464
 
+tests = \
102465
 
+       tst-test-script-compile.c \
102466
 
+       tst-test-script-run.c \
102467
 
+       tst-test-error.c \
102468
 
+       tst-test-result.c \
102469
 
+       tst-test-result-execute.c
102470
 
+
102471
 
+testsuite_SOURCES = \
102472
 
+       testsuite-common.c \
102473
 
+       testsuite-objects.c \
102474
 
+       testsuite-substitutions.c \
102475
 
+       testsuite-arguments.c \
102476
 
+       testsuite-message.c \
102477
 
+       testsuite-log.c \
102478
 
+       testsuite-script.c \
102479
 
+       testsuite-result.c \
102480
 
+       testsuite-smtp.c \
102481
 
+       testsuite-mailstore.c \
102482
 
+       testsuite-binary.c \
102483
 
+       $(commands) \
102484
 
+       $(tests) \
102485
 
+       ext-testsuite.c \
102486
 
+       testsuite.c
102487
 
+
102488
 
+noinst_HEADERS = \
102489
 
+       testsuite-common.h \
102490
 
+       testsuite-objects.h \
102491
 
+       testsuite-substitutions.h \
102492
 
+       testsuite-arguments.h \
102493
 
+       testsuite-message.h \
102494
 
+       testsuite-log.h \
102495
 
+       testsuite-script.h \
102496
 
+       testsuite-result.h \
102497
 
+       testsuite-smtp.h \
102498
 
+       testsuite-mailstore.h \
102499
 
+       testsuite-binary.h
102500
 
+
102501
 
+all: all-am
102502
 
+
102503
 
+.SUFFIXES:
102504
 
+.SUFFIXES: .c .lo .o .obj
102505
 
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
102506
 
+       @for dep in $?; do \
102507
 
+         case '$(am__configure_deps)' in \
102508
 
+           *$$dep*) \
102509
 
+             ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
102510
 
+               && { if test -f $@; then exit 0; else break; fi; }; \
102511
 
+             exit 1;; \
102512
 
+         esac; \
102513
 
+       done; \
102514
 
+       echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign  src/testsuite/Makefile'; \
102515
 
+       cd $(top_srcdir) && \
102516
 
+         $(AUTOMAKE) --foreign  src/testsuite/Makefile
102517
 
+.PRECIOUS: Makefile
102518
 
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
102519
 
+       @case '$?' in \
102520
 
+         *config.status*) \
102521
 
+           cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
102522
 
+         *) \
102523
 
+           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
102524
 
+           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
102525
 
+       esac;
102526
 
+
102527
 
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
102528
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
102529
 
+
102530
 
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
102531
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
102532
 
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
102533
 
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
102534
 
+
102535
 
+clean-noinstPROGRAMS:
102536
 
+       @list='$(noinst_PROGRAMS)'; for p in $$list; do \
102537
 
+         f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
102538
 
+         echo " rm -f $$p $$f"; \
102539
 
+         rm -f $$p $$f ; \
102540
 
+       done
102541
 
+testsuite$(EXEEXT): $(testsuite_OBJECTS) $(testsuite_DEPENDENCIES) 
102542
 
+       @rm -f testsuite$(EXEEXT)
102543
 
+       $(testsuite_LINK) $(testsuite_OBJECTS) $(testsuite_LDADD) $(LIBS)
102544
 
+
102545
 
+mostlyclean-compile:
102546
 
+       -rm -f *.$(OBJEXT)
102547
 
+
102548
 
+distclean-compile:
102549
 
+       -rm -f *.tab.c
102550
 
+
102551
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd-test-binary.Po@am__quote@
102552
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd-test-fail.Po@am__quote@
102553
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd-test-mailbox.Po@am__quote@
102554
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd-test-message.Po@am__quote@
102555
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd-test-result-print.Po@am__quote@
102556
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd-test-result-reset.Po@am__quote@
102557
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd-test-set.Po@am__quote@
102558
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd-test.Po@am__quote@
102559
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext-testsuite.Po@am__quote@
102560
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testsuite-arguments.Po@am__quote@
102561
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testsuite-binary.Po@am__quote@
102562
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testsuite-common.Po@am__quote@
102563
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testsuite-log.Po@am__quote@
102564
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testsuite-mailstore.Po@am__quote@
102565
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testsuite-message.Po@am__quote@
102566
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testsuite-objects.Po@am__quote@
102567
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testsuite-result.Po@am__quote@
102568
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testsuite-script.Po@am__quote@
102569
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testsuite-smtp.Po@am__quote@
102570
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testsuite-substitutions.Po@am__quote@
102571
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testsuite.Po@am__quote@
102572
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tst-test-error.Po@am__quote@
102573
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tst-test-result-execute.Po@am__quote@
102574
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tst-test-result.Po@am__quote@
102575
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tst-test-script-compile.Po@am__quote@
102576
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tst-test-script-run.Po@am__quote@
102577
 
+
102578
 
+.c.o:
102579
 
+@am__fastdepCC_TRUE@   $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
102580
 
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
102581
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
102582
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
102583
 
+@am__fastdepCC_FALSE@  $(COMPILE) -c $<
102584
 
+
102585
 
+.c.obj:
102586
 
+@am__fastdepCC_TRUE@   $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
102587
 
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
102588
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
102589
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
102590
 
+@am__fastdepCC_FALSE@  $(COMPILE) -c `$(CYGPATH_W) '$<'`
102591
 
+
102592
 
+.c.lo:
102593
 
+@am__fastdepCC_TRUE@   $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
102594
 
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
102595
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
102596
 
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
102597
 
+@am__fastdepCC_FALSE@  $(LTCOMPILE) -c -o $@ $<
102598
 
+
102599
 
+mostlyclean-libtool:
102600
 
+       -rm -f *.lo
102601
 
+
102602
 
+clean-libtool:
102603
 
+       -rm -rf .libs _libs
102604
 
+
102605
 
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
102606
 
+       list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
102607
 
+       unique=`for i in $$list; do \
102608
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
102609
 
+         done | \
102610
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
102611
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
102612
 
+       mkid -fID $$unique
102613
 
+tags: TAGS
102614
 
+
102615
 
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
102616
 
+               $(TAGS_FILES) $(LISP)
102617
 
+       tags=; \
102618
 
+       here=`pwd`; \
102619
 
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
102620
 
+       unique=`for i in $$list; do \
102621
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
102622
 
+         done | \
102623
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
102624
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
102625
 
+       if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
102626
 
+         test -n "$$unique" || unique=$$empty_fix; \
102627
 
+         $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
102628
 
+           $$tags $$unique; \
102629
 
+       fi
102630
 
+ctags: CTAGS
102631
 
+CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
102632
 
+               $(TAGS_FILES) $(LISP)
102633
 
+       tags=; \
102634
 
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
102635
 
+       unique=`for i in $$list; do \
102636
 
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
102637
 
+         done | \
102638
 
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
102639
 
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
102640
 
+       test -z "$(CTAGS_ARGS)$$tags$$unique" \
102641
 
+         || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
102642
 
+            $$tags $$unique
102643
 
+
102644
 
+GTAGS:
102645
 
+       here=`$(am__cd) $(top_builddir) && pwd` \
102646
 
+         && cd $(top_srcdir) \
102647
 
+         && gtags -i $(GTAGS_ARGS) $$here
102648
 
+
102649
 
+distclean-tags:
102650
 
+       -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
102651
 
+
102652
 
+distdir: $(DISTFILES)
102653
 
+       @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
102654
 
+       topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
102655
 
+       list='$(DISTFILES)'; \
102656
 
+         dist_files=`for file in $$list; do echo $$file; done | \
102657
 
+         sed -e "s|^$$srcdirstrip/||;t" \
102658
 
+             -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
102659
 
+       case $$dist_files in \
102660
 
+         */*) $(MKDIR_P) `echo "$$dist_files" | \
102661
 
+                          sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
102662
 
+                          sort -u` ;; \
102663
 
+       esac; \
102664
 
+       for file in $$dist_files; do \
102665
 
+         if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
102666
 
+         if test -d $$d/$$file; then \
102667
 
+           dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
102668
 
+           if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
102669
 
+             cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
102670
 
+           fi; \
102671
 
+           cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
102672
 
+         else \
102673
 
+           test -f $(distdir)/$$file \
102674
 
+           || cp -p $$d/$$file $(distdir)/$$file \
102675
 
+           || exit 1; \
102676
 
+         fi; \
102677
 
+       done
102678
 
+check-am: all-am
102679
 
+check: check-am
102680
 
+all-am: Makefile $(PROGRAMS) $(HEADERS)
102681
 
+installdirs:
102682
 
+install: install-am
102683
 
+install-exec: install-exec-am
102684
 
+install-data: install-data-am
102685
 
+uninstall: uninstall-am
102686
 
+
102687
 
+install-am: all-am
102688
 
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
102689
 
+
102690
 
+installcheck: installcheck-am
102691
 
+install-strip:
102692
 
+       $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
102693
 
+         install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
102694
 
+         `test -z '$(STRIP)' || \
102695
 
+           echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
102696
 
+mostlyclean-generic:
102697
 
+
102698
 
+clean-generic:
102699
 
+
102700
 
+distclean-generic:
102701
 
+       -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
102702
 
+
102703
 
+maintainer-clean-generic:
102704
 
+       @echo "This command is intended for maintainers to use"
102705
 
+       @echo "it deletes files that may require special tools to rebuild."
102706
 
+clean: clean-am
102707
 
+
102708
 
+clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \
102709
 
+       mostlyclean-am
102710
 
+
102711
 
+distclean: distclean-am
102712
 
+       -rm -rf ./$(DEPDIR)
102713
 
+       -rm -f Makefile
102714
 
+distclean-am: clean-am distclean-compile distclean-generic \
102715
 
+       distclean-tags
102716
 
+
102717
 
+dvi: dvi-am
102718
 
+
102719
 
+dvi-am:
102720
 
+
102721
 
+html: html-am
102722
 
+
102723
 
+info: info-am
102724
 
+
102725
 
+info-am:
102726
 
+
102727
 
+install-data-am:
102728
 
+
102729
 
+install-dvi: install-dvi-am
102730
 
+
102731
 
+install-exec-am:
102732
 
+
102733
 
+install-html: install-html-am
102734
 
+
102735
 
+install-info: install-info-am
102736
 
+
102737
 
+install-man:
102738
 
+
102739
 
+install-pdf: install-pdf-am
102740
 
+
102741
 
+install-ps: install-ps-am
102742
 
+
102743
 
+installcheck-am:
102744
 
+
102745
 
+maintainer-clean: maintainer-clean-am
102746
 
+       -rm -rf ./$(DEPDIR)
102747
 
+       -rm -f Makefile
102748
 
+maintainer-clean-am: distclean-am maintainer-clean-generic
102749
 
+
102750
 
+mostlyclean: mostlyclean-am
102751
 
+
102752
 
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
102753
 
+       mostlyclean-libtool
102754
 
+
102755
 
+pdf: pdf-am
102756
 
+
102757
 
+pdf-am:
102758
 
+
102759
 
+ps: ps-am
102760
 
+
102761
 
+ps-am:
102762
 
+
102763
 
+uninstall-am:
102764
 
+
102765
 
+.MAKE: install-am install-strip
102766
 
+
102767
 
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
102768
 
+       clean-libtool clean-noinstPROGRAMS ctags distclean \
102769
 
+       distclean-compile distclean-generic distclean-libtool \
102770
 
+       distclean-tags distdir dvi dvi-am html html-am info info-am \
102771
 
+       install install-am install-data install-data-am install-dvi \
102772
 
+       install-dvi-am install-exec install-exec-am install-html \
102773
 
+       install-html-am install-info install-info-am install-man \
102774
 
+       install-pdf install-pdf-am install-ps install-ps-am \
102775
 
+       install-strip installcheck installcheck-am installdirs \
102776
 
+       maintainer-clean maintainer-clean-generic mostlyclean \
102777
 
+       mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
102778
 
+       pdf pdf-am ps ps-am tags uninstall uninstall-am
102779
 
+
102780
 
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
102781
 
+# Otherwise a system limit (for SysV at least) may be exceeded.
102782
 
+.NOEXPORT:
102783
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/testsuite/testsuite-arguments.c dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/testsuite-arguments.c
102784
 
--- dovecot-1.2.4/dovecot-libsieve/src/testsuite/testsuite-arguments.c  1970-01-01 01:00:00.000000000 +0100
102785
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/testsuite-arguments.c   2009-01-06 00:15:52.000000000 +0100
102786
 
@@ -0,0 +1,192 @@
102787
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
102788
 
+ */
102789
 
+
102790
 
+#include "lib.h"
102791
 
+#include "str.h"
102792
 
+#include "str-sanitize.h"
102793
 
+#include "array.h"
102794
 
+
102795
 
+#include "sieve-common.h"
102796
 
+#include "sieve-ast.h"
102797
 
+#include "sieve-commands.h"
102798
 
+#include "sieve-code.h"
102799
 
+#include "sieve-validator.h"
102800
 
+#include "sieve-generator.h"
102801
 
+#include "sieve-dump.h"
102802
 
+
102803
 
+#include "testsuite-common.h"
102804
 
+#include "testsuite-substitutions.h"
102805
 
+#include "testsuite-arguments.h"
102806
 
+
102807
 
+#include <ctype.h>
102808
 
+
102809
 
+/* 
102810
 
+ * Testsuite string argument 
102811
 
+ */
102812
 
+
102813
 
+static bool arg_testsuite_string_validate
102814
 
+       (struct sieve_validator *validator, struct sieve_ast_argument **arg, 
102815
 
+               struct sieve_command_context *context);
102816
 
+
102817
 
+const struct sieve_argument testsuite_string_argument = { 
102818
 
+       "@testsuite-string", 
102819
 
+       NULL, NULL,
102820
 
+       arg_testsuite_string_validate, 
102821
 
+       NULL, 
102822
 
+       sieve_arg_catenated_string_generate,
102823
 
+};
102824
 
+
102825
 
+static bool arg_testsuite_string_validate
102826
 
+(struct sieve_validator *valdtr, struct sieve_ast_argument **arg, 
102827
 
+       struct sieve_command_context *cmd)
102828
 
+{
102829
 
+       enum { ST_NONE, ST_OPEN, ST_SUBSTITUTION, ST_PARAM, ST_CLOSE } state = 
102830
 
+               ST_NONE;
102831
 
+       pool_t pool = sieve_ast_pool((*arg)->ast);
102832
 
+       struct sieve_arg_catenated_string *catstr = NULL;
102833
 
+       string_t *str = sieve_ast_argument_str(*arg);
102834
 
+       const char *p, *strstart, *substart = NULL;
102835
 
+       const char *strval = (const char *) str_data(str);
102836
 
+       const char *strend = strval + str_len(str);
102837
 
+       bool result = TRUE;
102838
 
+       string_t *subs_name = t_str_new(256);
102839
 
+       string_t *subs_param = t_str_new(256);
102840
 
+       
102841
 
+       T_BEGIN {
102842
 
+               /* Initialize substitution structure */
102843
 
+       
102844
 
+               p = strval;
102845
 
+               strstart = p;
102846
 
+               while ( result && p < strend ) {
102847
 
+                       switch ( state ) {
102848
 
+
102849
 
+                       /* Nothing found yet */
102850
 
+                       case ST_NONE:
102851
 
+                               if ( *p == '%' ) {
102852
 
+                                       substart = p;
102853
 
+                                       state = ST_OPEN;
102854
 
+                                       str_truncate(subs_name, 0);
102855
 
+                                       str_truncate(subs_param, 0);
102856
 
+                               }
102857
 
+                               p++;
102858
 
+                               break;
102859
 
+
102860
 
+                       /* Got '%' */
102861
 
+                       case ST_OPEN:
102862
 
+                               if ( *p == '{' ) {
102863
 
+                                       state = ST_SUBSTITUTION;
102864
 
+                                       p++;
102865
 
+                               } else 
102866
 
+                                       state = ST_NONE;
102867
 
+                               break;
102868
 
+
102869
 
+                       /* Got '%{' */ 
102870
 
+                       case ST_SUBSTITUTION:
102871
 
+                               state = ST_PARAM;       
102872
 
+
102873
 
+                               while ( *p != '}' && *p != ':' ) {
102874
 
+                                       if ( !i_isalnum(*p) ) {
102875
 
+                                               state = ST_NONE;
102876
 
+                                               break;
102877
 
+                                       }       
102878
 
+                                       str_append_c(subs_name, *p);
102879
 
+                                       p++;
102880
 
+                               }
102881
 
+                               break;
102882
 
+                               
102883
 
+                       /* Got '%{name' */
102884
 
+                       case ST_PARAM:
102885
 
+                               if ( *p == ':' ) {
102886
 
+                                       p++;
102887
 
+                                       while ( *p != '}' ) {
102888
 
+                                               str_append_c(subs_param, *p);
102889
 
+                                               p++;
102890
 
+                                       }
102891
 
+                               }
102892
 
+                               state = ST_CLOSE;
102893
 
+                               break;
102894
 
+
102895
 
+                       /* Finished parsing param, expecting '}' */
102896
 
+                       case ST_CLOSE:
102897
 
+                               if ( *p == '}' ) {                              
102898
 
+                                       struct sieve_ast_argument *strarg;
102899
 
+                               
102900
 
+                                       /* We now know that the substitution is valid */        
102901
 
+                                       
102902
 
+                                       if ( catstr == NULL ) {
102903
 
+                                               catstr = sieve_arg_catenated_string_create(*arg);
102904
 
+                                       }
102905
 
+                               
102906
 
+                                       /* Add the substring that is before the substitution to the 
102907
 
+                                        * variable-string AST.
102908
 
+                                        */
102909
 
+                                       if ( substart > strstart ) {
102910
 
+                                               string_t *newstr = str_new(pool, substart - strstart);
102911
 
+                                               str_append_n(newstr, strstart, substart - strstart); 
102912
 
+                                               
102913
 
+                                               strarg = sieve_ast_argument_string_create_raw
102914
 
+                                                       ((*arg)->ast, newstr, (*arg)->source_line);
102915
 
+                                               sieve_arg_catenated_string_add_element(catstr, strarg);
102916
 
+                                       
102917
 
+                                               /* Give other substitution extensions a chance to do their work */
102918
 
+                                               if ( !sieve_validator_argument_activate_super
102919
 
+                                                       (valdtr, cmd, strarg, FALSE) ) {
102920
 
+                                                       result = FALSE;
102921
 
+                                                       break;
102922
 
+                                               }
102923
 
+                                       }
102924
 
+                               
102925
 
+                                       strarg = testsuite_substitution_argument_create
102926
 
+                                               (valdtr, (*arg)->ast, (*arg)->source_line, str_c(subs_name), 
102927
 
+                                                       str_c(subs_param));
102928
 
+                                       
102929
 
+                                       if ( strarg != NULL )
102930
 
+                                               sieve_arg_catenated_string_add_element(catstr, strarg);
102931
 
+                                       else {
102932
 
+                                               sieve_argument_validate_error(valdtr, *arg, 
102933
 
+                                                       "unknown testsuite substitution type '%s'", str_c(subs_name));
102934
 
+                                       }
102935
 
+
102936
 
+                                       strstart = p + 1;
102937
 
+                                       substart = strstart;
102938
 
+
102939
 
+                                       p++;    
102940
 
+                               }
102941
 
+               
102942
 
+                               /* Finished, reset for the next substitution */ 
102943
 
+                               state = ST_NONE;
102944
 
+                       }
102945
 
+               }
102946
 
+       } T_END;
102947
 
+
102948
 
+       /* Bail out early if substitution is invalid */
102949
 
+       if ( !result ) return FALSE;
102950
 
+       
102951
 
+       /* Check whether any substitutions were found */
102952
 
+       if ( catstr == NULL ) {
102953
 
+               /* No substitutions in this string, pass it on to any other substution
102954
 
+                * extension.
102955
 
+                */
102956
 
+               return sieve_validator_argument_activate_super(valdtr, cmd, *arg, TRUE);
102957
 
+       }
102958
 
+       
102959
 
+       /* Add the final substring that comes after the last substitution to the 
102960
 
+        * variable-string AST.
102961
 
+        */
102962
 
+       if ( strend > strstart ) {
102963
 
+               struct sieve_ast_argument *strarg;
102964
 
+               string_t *newstr = str_new(pool, strend - strstart);
102965
 
+               str_append_n(newstr, strstart, strend - strstart); 
102966
 
+
102967
 
+               strarg = sieve_ast_argument_string_create_raw
102968
 
+                       ((*arg)->ast, newstr, (*arg)->source_line);
102969
 
+               sieve_arg_catenated_string_add_element(catstr, strarg);
102970
 
+                       
102971
 
+               /* Give other substitution extensions a chance to do their work */      
102972
 
+               if ( !sieve_validator_argument_activate_super
102973
 
+                       (valdtr, cmd, strarg, FALSE) )
102974
 
+                       return FALSE;
102975
 
+       }       
102976
 
+       
102977
 
+       return TRUE;
102978
 
+}
102979
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/testsuite/testsuite-arguments.h dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/testsuite-arguments.h
102980
 
--- dovecot-1.2.4/dovecot-libsieve/src/testsuite/testsuite-arguments.h  1970-01-01 01:00:00.000000000 +0100
102981
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/testsuite-arguments.h   2009-01-06 00:15:52.000000000 +0100
102982
 
@@ -0,0 +1,9 @@
102983
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
102984
 
+ */
102985
 
+
102986
 
+#ifndef __TESTSUITE_ARGUMENTS_H
102987
 
+#define __TESTSUITE_ARGUMENTS_H
102988
 
+
102989
 
+extern const struct sieve_argument testsuite_string_argument;
102990
 
+
102991
 
+#endif
102992
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/testsuite/testsuite-binary.c dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/testsuite-binary.c
102993
 
--- dovecot-1.2.4/dovecot-libsieve/src/testsuite/testsuite-binary.c     1970-01-01 01:00:00.000000000 +0100
102994
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/testsuite-binary.c      2009-08-21 00:52:15.000000000 +0200
102995
 
@@ -0,0 +1,74 @@
102996
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
102997
 
+ */
102998
 
+
102999
 
+#include "lib.h"
103000
 
+#include "mempool.h"
103001
 
+#include "imem.h"
103002
 
+#include "array.h"
103003
 
+#include "strfuncs.h"
103004
 
+#include "unlink-directory.h"
103005
 
+
103006
 
+#include "sieve.h"
103007
 
+#include "sieve-common.h" 
103008
 
+#include "sieve-error.h"
103009
 
103010
 
+#include "testsuite-common.h"
103011
 
+#include "testsuite-binary.h"
103012
 
+
103013
 
+#include <sys/stat.h>
103014
 
+#include <sys/types.h>
103015
 
+
103016
 
+/*
103017
 
+ * State
103018
 
+ */
103019
 
+
103020
 
+static char *testsuite_binary_tmp = NULL;
103021
 
+
103022
 
+/*
103023
 
+ * Initialization
103024
 
+ */
103025
 
+
103026
 
+void testsuite_binary_init(void)
103027
 
+{      
103028
 
+       testsuite_binary_tmp = i_strconcat
103029
 
+               (testsuite_tmp_dir_get(), "/binaries", NULL);
103030
 
+
103031
 
+       if ( mkdir(testsuite_binary_tmp, 0700) < 0 ) {
103032
 
+               i_fatal("failed to create temporary directory '%s': %m.", 
103033
 
+                       testsuite_binary_tmp);          
103034
 
+       }
103035
 
+}
103036
 
+
103037
 
+void testsuite_binary_deinit(void)
103038
 
+{
103039
 
+       if ( unlink_directory(testsuite_binary_tmp, TRUE) < 0 ) {
103040
 
+               i_warning("failed to remove temporary directory '%s': %m.",
103041
 
+                       testsuite_binary_tmp);
103042
 
+       }
103043
 
+       
103044
 
+       i_free(testsuite_binary_tmp);           
103045
 
+}
103046
 
+
103047
 
+void testsuite_binary_reset(void)
103048
 
+{
103049
 
+       testsuite_binary_init();
103050
 
+       testsuite_binary_deinit();
103051
 
+}
103052
 
+
103053
 
+/*
103054
 
+ * Binary Access
103055
 
+ */
103056
 
+
103057
 
+bool testsuite_binary_save(struct sieve_binary *sbin, const char *name)
103058
 
+{
103059
 
+       return sieve_save
103060
 
+    (sbin, t_strdup_printf("%s/%s.svbin", testsuite_binary_tmp, name));
103061
 
+}
103062
 
+
103063
 
+struct sieve_binary *testsuite_binary_load(const char *name)
103064
 
+{
103065
 
+       return sieve_load(t_strdup_printf("%s/%s.svbin", testsuite_binary_tmp, name));
103066
 
+}
103067
 
+
103068
 
+
103069
 
+
103070
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/testsuite/testsuite-binary.h dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/testsuite-binary.h
103071
 
--- dovecot-1.2.4/dovecot-libsieve/src/testsuite/testsuite-binary.h     1970-01-01 01:00:00.000000000 +0100
103072
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/testsuite-binary.h      2009-08-21 00:52:15.000000000 +0200
103073
 
@@ -0,0 +1,20 @@
103074
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
103075
 
+ */
103076
 
+
103077
 
+#ifndef __TESTSUITE_BINARY_H
103078
 
+#define __TESTSUITE_BINARY_H
103079
 
+
103080
 
+#include "sieve-common.h" 
103081
 
+
103082
 
+void testsuite_binary_init(void);
103083
 
+void testsuite_binary_deinit(void);
103084
 
+void testsuite_binary_reset(void);
103085
 
+
103086
 
+/*
103087
 
+ * Binary Access
103088
 
+ */
103089
 
+
103090
 
+bool testsuite_binary_save(struct sieve_binary *sbin, const char *name);
103091
 
+struct sieve_binary *testsuite_binary_load(const char *name);
103092
 
+
103093
 
+#endif /* __TESTSUITE_BINARY_H */
103094
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/testsuite/testsuite.c dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/testsuite.c
103095
 
--- dovecot-1.2.4/dovecot-libsieve/src/testsuite/testsuite.c    1970-01-01 01:00:00.000000000 +0100
103096
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/testsuite.c     2009-08-21 00:52:15.000000000 +0200
103097
 
@@ -0,0 +1,239 @@
103098
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
103099
 
+ */
103100
 
+
103101
 
+#include "lib.h"
103102
 
+#include "lib-signals.h"
103103
 
+#include "ioloop.h"
103104
 
+#include "ostream.h"
103105
 
+#include "hostpid.h"
103106
 
+#include "mail-storage.h"
103107
 
+#include "mail-namespace.h"
103108
 
+#include "env-util.h"
103109
 
+
103110
 
+#include "sieve.h"
103111
 
+#include "sieve-extensions.h"
103112
 
+#include "sieve-script.h"
103113
 
+#include "sieve-binary.h"
103114
 
+#include "sieve-result.h"
103115
 
+#include "sieve-interpreter.h"
103116
 
+
103117
 
+#include "mail-raw.h"
103118
 
+#include "sieve-tool.h"
103119
 
+
103120
 
+#include "testsuite-common.h"
103121
 
+#include "testsuite-result.h"
103122
 
+#include "testsuite-message.h"
103123
 
+#include "testsuite-smtp.h"
103124
 
+#include "testsuite-mailstore.h"
103125
 
+
103126
 
+#include <stdio.h>
103127
 
+#include <stdlib.h>
103128
 
+#include <unistd.h>
103129
 
+#include <fcntl.h>
103130
 
+#include <pwd.h>
103131
 
+
103132
 
+const struct sieve_script_env *testsuite_scriptenv;
103133
 
+
103134
 
+/*
103135
 
+ * Configuration
103136
 
+ */
103137
 
+
103138
 
+#define DEFAULT_SENDMAIL_PATH "/usr/lib/sendmail"
103139
 
+#define DEFAULT_ENVELOPE_SENDER "MAILER-DAEMON"
103140
 
+
103141
 
+/*
103142
 
+ * Testsuite initialization 
103143
 
+ */
103144
 
+
103145
 
+static void testsuite_tool_init(const char *extensions) 
103146
 
+{
103147
 
+       sieve_tool_init();
103148
 
+
103149
 
+       sieve_extensions_set_string(extensions);
103150
 
+
103151
 
+       (void) sieve_extension_register(&testsuite_extension, TRUE);
103152
 
+       
103153
 
+       testsuite_init();
103154
 
+}
103155
 
+
103156
 
+static void testsuite_tool_deinit(void)
103157
 
+{
103158
 
+       testsuite_deinit();
103159
 
+       
103160
 
+       sieve_tool_deinit();
103161
 
+}
103162
 
+
103163
 
+/*
103164
 
+ * Testsuite execution
103165
 
+ */
103166
 
+
103167
 
+static void print_help(void)
103168
 
+{
103169
 
+       printf(
103170
 
+"Usage: testsuite [-d <dump filename>] <scriptfile>\n"
103171
 
+       );
103172
 
+}
103173
 
+
103174
 
+static int testsuite_run
103175
 
+(struct sieve_binary *sbin, const struct sieve_message_data *msgdata, 
103176
 
+       const struct sieve_script_env *senv, struct sieve_error_handler *ehandler)
103177
 
+{
103178
 
+       struct sieve_interpreter *interp;
103179
 
+       struct sieve_result *result;
103180
 
+       int ret = 0;
103181
 
+
103182
 
+       /* Create the interpreter */
103183
 
+       if ( (interp=sieve_interpreter_create(sbin, ehandler)) == NULL )
103184
 
+               return SIEVE_EXEC_BIN_CORRUPT;
103185
 
+
103186
 
+       /* Reset execution status */
103187
 
+       if ( senv->exec_status != NULL )
103188
 
+               memset(senv->exec_status, 0, sizeof(*senv->exec_status));
103189
 
+
103190
 
+       /* Run the interpreter */
103191
 
+       result = testsuite_result_get();
103192
 
+       sieve_result_ref(result);
103193
 
+       ret = sieve_interpreter_run(interp, msgdata, senv, result);
103194
 
+       sieve_result_unref(&result);
103195
 
+
103196
 
+       /* Free the interpreter */
103197
 
+       sieve_interpreter_free(&interp);
103198
 
+
103199
 
+       return ret;
103200
 
+}
103201
 
+
103202
 
+int main(int argc, char **argv) 
103203
 
+{
103204
 
+       const char *scriptfile, *dumpfile, *extensions; 
103205
 
+       const char *user;
103206
 
+       int i, ret;
103207
 
+       struct sieve_binary *sbin;
103208
 
+       const char *sieve_dir;
103209
 
+       bool trace = FALSE;
103210
 
+
103211
 
+       /* Parse arguments */
103212
 
+       scriptfile = dumpfile = extensions = NULL;
103213
 
+       for (i = 1; i < argc; i++) {
103214
 
+               if (strcmp(argv[i], "-d") == 0) {
103215
 
+                       /* dump file */
103216
 
+                       i++;
103217
 
+                       if (i == argc)
103218
 
+                               i_fatal("Missing -d argument");
103219
 
+                       dumpfile = argv[i];
103220
 
+               } else if (strcmp(argv[i], "-x") == 0) {
103221
 
+            /* extensions */
103222
 
+            i++;
103223
 
+            if (i == argc) {
103224
 
+                print_help();
103225
 
+                i_fatal("Missing -x argument");
103226
 
+            }
103227
 
+            extensions = argv[i];
103228
 
+#ifdef SIEVE_RUNTIME_TRACE
103229
 
+               } else if (strcmp(argv[i], "-t") == 0) {
103230
 
+                       /* runtime trace */
103231
 
+                       trace = TRUE;
103232
 
+#endif
103233
 
+               } else if ( scriptfile == NULL ) {
103234
 
+                       scriptfile = argv[i];
103235
 
+               } else {
103236
 
+                       print_help();
103237
 
+                       i_fatal("Unknown argument: %s", argv[i]);
103238
 
+               }
103239
 
+       }
103240
 
+       
103241
 
+       if ( scriptfile == NULL ) {
103242
 
+               print_help();
103243
 
+               i_fatal("Missing <scriptfile> argument");
103244
 
+       }
103245
 
+
103246
 
+       printf("Test case: %s:\n\n", scriptfile);
103247
 
+
103248
 
+       /* Initialize testsuite */
103249
 
+       testsuite_tool_init(extensions);
103250
 
+
103251
 
+       /* Initialize environment */
103252
 
+       sieve_dir = strrchr(scriptfile, '/');
103253
 
+       if ( sieve_dir == NULL )
103254
 
+               sieve_dir= "./";
103255
 
+       else
103256
 
+               sieve_dir = t_strdup_until(scriptfile, sieve_dir+1);
103257
 
+
103258
 
+       /* Currently needed for include (FIXME) */
103259
 
+       env_put(t_strconcat("SIEVE_DIR=", sieve_dir, "included", NULL));
103260
 
+       env_put(t_strconcat("SIEVE_GLOBAL_DIR=", sieve_dir, "included-global", NULL));
103261
 
+
103262
 
+       /* Compile sieve script */
103263
 
+       if ( (sbin = sieve_tool_script_compile(scriptfile, NULL)) != NULL ) {
103264
 
+               struct sieve_error_handler *ehandler;
103265
 
+               struct sieve_script_env scriptenv;
103266
 
+               const char *home = getenv("HOME");
103267
 
+
103268
 
+               /* Dump script */
103269
 
+               sieve_tool_dump_binary_to(sbin, dumpfile);
103270
 
+       
103271
 
+               /* Initialize mail storages */
103272
 
+               mail_users_init(getenv("AUTH_SOCKET_PATH"), getenv("DEBUG") != NULL);
103273
 
+               mail_storage_init();
103274
 
+               mail_storage_register_all();
103275
 
+               mailbox_list_register_all();
103276
 
+
103277
 
+               /* Initialize message environment */
103278
 
+               user = sieve_tool_get_user();
103279
 
+               testsuite_mailstore_init(user, home);
103280
 
+               testsuite_message_init(user);
103281
 
+
103282
 
+               memset(&scriptenv, 0, sizeof(scriptenv));
103283
 
+               scriptenv.namespaces = testsuite_mailstore_get_namespace();
103284
 
+               scriptenv.default_mailbox = "INBOX";
103285
 
+               scriptenv.hostname = "testsuite.example.com";
103286
 
+               scriptenv.postmaster_address = "postmaster@example.com";
103287
 
+               scriptenv.username = user;
103288
 
+               scriptenv.smtp_open = testsuite_smtp_open;
103289
 
+               scriptenv.smtp_close = testsuite_smtp_close;
103290
 
+               scriptenv.trace_stream = ( trace ? o_stream_create_fd(1, 0, FALSE) : NULL );
103291
 
+
103292
 
+               testsuite_scriptenv = &scriptenv;
103293
 
+
103294
 
+               testsuite_result_init();
103295
 
+
103296
 
+               /* Run the test */
103297
 
+               ehandler = sieve_stderr_ehandler_create(0);
103298
 
+               ret = testsuite_run(sbin, &testsuite_msgdata, &scriptenv, ehandler);
103299
 
+               sieve_error_handler_unref(&ehandler);
103300
 
+
103301
 
+               switch ( ret ) {
103302
 
+               case SIEVE_EXEC_OK:
103303
 
+                       break;
103304
 
+               case SIEVE_EXEC_FAILURE:
103305
 
+               case SIEVE_EXEC_KEEP_FAILED:
103306
 
+                       testsuite_testcase_fail("execution aborted");
103307
 
+                       break;
103308
 
+               case SIEVE_EXEC_BIN_CORRUPT:
103309
 
+                       testsuite_testcase_fail("binary corrupt");
103310
 
+                       break;
103311
 
+               default:
103312
 
+                       testsuite_testcase_fail("unknown execution exit code");
103313
 
+               }
103314
 
+
103315
 
+               sieve_close(&sbin);
103316
 
+
103317
 
+               if ( scriptenv.trace_stream != NULL )
103318
 
+                       o_stream_unref(&scriptenv.trace_stream);
103319
 
+
103320
 
+               /* De-initialize message environment */
103321
 
+               testsuite_message_deinit();
103322
 
+               testsuite_mailstore_deinit();
103323
 
+               testsuite_result_deinit();
103324
 
+
103325
 
+               /* De-initialize mail storages */
103326
 
+               mail_storage_deinit();
103327
 
+               mail_users_deinit();
103328
 
+       } else {
103329
 
+               testsuite_testcase_fail("failed to compile testcase script");
103330
 
+       }
103331
 
+
103332
 
+       /* De-initialize testsuite */
103333
 
+       testsuite_tool_deinit();  
103334
 
+
103335
 
+       return testsuite_testcase_result();
103336
 
+}
103337
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/testsuite/testsuite-common.c dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/testsuite-common.c
103338
 
--- dovecot-1.2.4/dovecot-libsieve/src/testsuite/testsuite-common.c     1970-01-01 01:00:00.000000000 +0100
103339
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/testsuite-common.c      2009-08-21 01:22:51.000000000 +0200
103340
 
@@ -0,0 +1,250 @@
103341
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
103342
 
+ */
103343
 
+
103344
 
+#include "lib.h"
103345
 
+#include "str.h"
103346
 
+#include "string.h"
103347
 
+#include "ostream.h"
103348
 
+#include "hash.h"
103349
 
+#include "mail-storage.h"
103350
 
+#include "env-util.h"
103351
 
+#include "unlink-directory.h"
103352
 
+
103353
 
+#include "mail-raw.h"
103354
 
+
103355
 
+#include "sieve-common.h"
103356
 
+#include "sieve-code.h"
103357
 
+#include "sieve-message.h"
103358
 
+#include "sieve-commands.h"
103359
 
+#include "sieve-extensions.h"
103360
 
+#include "sieve-validator.h"
103361
 
+#include "sieve-generator.h"
103362
 
+#include "sieve-interpreter.h"
103363
 
+#include "sieve-result.h"
103364
 
+#include "sieve-dump.h"
103365
 
+
103366
 
+#include "testsuite-common.h"
103367
 
+#include "testsuite-objects.h"
103368
 
+#include "testsuite-log.h"
103369
 
+#include "testsuite-script.h"
103370
 
+#include "testsuite-binary.h"
103371
 
+#include "testsuite-result.h"
103372
 
+#include "testsuite-smtp.h"
103373
 
+
103374
 
+#include <stdlib.h>
103375
 
+#include <string.h>
103376
 
+#include <fcntl.h>
103377
 
+#include <unistd.h>
103378
 
+#include <time.h>
103379
 
+#include <sys/stat.h>
103380
 
+#include <sys/types.h>
103381
 
+
103382
 
+/*
103383
 
+ * Global data
103384
 
+ */
103385
 
+
103386
 
+/* Test context */
103387
 
+
103388
 
+static string_t *test_name;
103389
 
+unsigned int test_index;
103390
 
+unsigned int test_failures;
103391
 
+
103392
 
+/* 
103393
 
+ * Validator context 
103394
 
+ */
103395
 
+
103396
 
+bool testsuite_validator_context_initialize(struct sieve_validator *valdtr)
103397
 
+{
103398
 
+       pool_t pool = sieve_validator_pool(valdtr);
103399
 
+       struct testsuite_validator_context *ctx = 
103400
 
+               p_new(pool, struct testsuite_validator_context, 1);
103401
 
+       
103402
 
+       /* Setup object registry */
103403
 
+       ctx->object_registrations = sieve_validator_object_registry_create(valdtr);
103404
 
+       testsuite_register_core_objects(ctx);
103405
 
+       
103406
 
+       sieve_validator_extension_set_context(valdtr, &testsuite_extension, ctx);
103407
 
+
103408
 
+       return TRUE;
103409
 
+}
103410
 
+
103411
 
+struct testsuite_validator_context *testsuite_validator_context_get
103412
 
+(struct sieve_validator *valdtr)
103413
 
+{
103414
 
+       return (struct testsuite_validator_context *)
103415
 
+               sieve_validator_extension_get_context(valdtr, &testsuite_extension);
103416
 
+}
103417
 
+
103418
 
+/* 
103419
 
+ * Generator context 
103420
 
+ */
103421
 
+
103422
 
+bool testsuite_generator_context_initialize(struct sieve_generator *gentr)
103423
 
+{
103424
 
+       pool_t pool = sieve_generator_pool(gentr);
103425
 
+       struct sieve_binary *sbin = sieve_generator_get_binary(gentr);
103426
 
+       struct testsuite_generator_context *ctx = 
103427
 
+               p_new(pool, struct testsuite_generator_context, 1);
103428
 
+       
103429
 
+       /* Setup exit jumplist */
103430
 
+       ctx->exit_jumps = sieve_jumplist_create(pool, sbin);
103431
 
+       
103432
 
+       sieve_generator_extension_set_context(gentr, &testsuite_extension, ctx);
103433
 
+
103434
 
+       return TRUE;
103435
 
+}
103436
 
+
103437
 
+/*
103438
 
+ * Test context
103439
 
+ */
103440
 
103441
 
+static void testsuite_test_context_init(void)
103442
 
+{
103443
 
+       test_name = str_new(default_pool, 128);
103444
 
+       test_index = 0; 
103445
 
+       test_failures = 0;
103446
 
+}
103447
 
+
103448
 
+void testsuite_test_start(string_t *name)
103449
 
+{
103450
 
+       str_truncate(test_name, 0);
103451
 
+       str_append_str(test_name, name);
103452
 
+
103453
 
+       test_index++;
103454
 
+}
103455
 
+
103456
 
+void testsuite_test_fail(string_t *reason)
103457
 
+{
103458
 
+       testsuite_test_fail_cstr(str_c(reason));
103459
 
+}
103460
 
+
103461
 
+void testsuite_test_failf(const char *fmt, ...)
103462
 
+{
103463
 
+       va_list args;
103464
 
+       va_start(args, fmt);
103465
 
+
103466
 
+       testsuite_test_fail_cstr(t_strdup_vprintf(fmt, args));
103467
 
+
103468
 
+       va_end(args);
103469
 
+}
103470
 
+
103471
 
+void testsuite_test_fail_cstr(const char *reason)
103472
 
+{      
103473
 
+       if ( str_len(test_name) == 0 ) {
103474
 
+               if ( reason == NULL || *reason == '\0' )
103475
 
+                       printf("%2d: Test FAILED\n", test_index);
103476
 
+               else
103477
 
+                       printf("%2d: Test FAILED: %s\n", test_index, reason);
103478
 
+       } else {
103479
 
+               if ( reason == NULL || *reason == '\0' )
103480
 
+                       printf("%2d: Test '%s' FAILED\n", test_index, str_c(test_name));
103481
 
+               else
103482
 
+                       printf("%2d: Test '%s' FAILED: %s\n", test_index, 
103483
 
+                               str_c(test_name), reason);
103484
 
+       }
103485
 
+
103486
 
+       str_truncate(test_name, 0);
103487
 
+
103488
 
+       test_failures++;
103489
 
+}
103490
 
+
103491
 
+void testsuite_testcase_fail(const char *reason)
103492
 
+{      
103493
 
+       if ( reason == NULL || *reason == '\0' )
103494
 
+               printf("XX: Test CASE FAILED\n");
103495
 
+       else
103496
 
+               printf("XX: Test CASE FAILED: %s\n", reason);
103497
 
+
103498
 
+       test_failures++;
103499
 
+}
103500
 
+
103501
 
+void testsuite_test_succeed(string_t *reason)
103502
 
+{
103503
 
+       if ( str_len(test_name) == 0 ) {
103504
 
+               if ( reason == NULL || str_len(reason) == 0 )
103505
 
+                       printf("%2d: Test SUCCEEDED\n", test_index);
103506
 
+               else
103507
 
+                       printf("%2d: Test SUCCEEDED: %s\n", test_index, str_c(reason));
103508
 
+       } else {
103509
 
+               if ( reason == NULL || str_len(reason) == 0 )
103510
 
+                       printf("%2d: Test '%s' SUCCEEDED\n", test_index, str_c(test_name));
103511
 
+               else
103512
 
+                       printf("%2d: Test '%s' SUCCEEDED: %s\n", test_index, 
103513
 
+                               str_c(test_name), str_c(reason));
103514
 
+       }
103515
 
+       str_truncate(test_name, 0);
103516
 
+}
103517
 
+
103518
 
+static void testsuite_test_context_deinit(void)
103519
 
+{
103520
 
+       str_free(&test_name);
103521
 
+}
103522
 
+
103523
 
+int testsuite_testcase_result(void)
103524
 
+{
103525
 
+       if ( test_failures > 0 ) {
103526
 
+               printf("\nFAIL: %d of %d tests failed.\n\n", test_failures, test_index);
103527
 
+               return 1;
103528
 
+       }
103529
 
+
103530
 
+       printf("\nPASS: %d tests succeeded.\n\n", test_index);
103531
 
+       return 0;
103532
 
+}
103533
 
+
103534
 
+/*
103535
 
+ * Testsuite temporary directory
103536
 
+ */
103537
 
+
103538
 
+static char *testsuite_tmp_dir;
103539
 
+
103540
 
+static void testsuite_tmp_dir_init(void)
103541
 
+{
103542
 
+       testsuite_tmp_dir = i_strdup_printf
103543
 
+               ("/tmp/dsieve-testsuite.%s.%s", dec2str(time(NULL)), dec2str(getpid()));
103544
 
+
103545
 
+       if ( mkdir(testsuite_tmp_dir, 0700) < 0 ) {
103546
 
+               i_fatal("failed to create temporary directory '%s': %m.", 
103547
 
+                       testsuite_tmp_dir);             
103548
 
+       }
103549
 
+}
103550
 
+
103551
 
+static void testsuite_tmp_dir_deinit(void)
103552
 
+{
103553
 
+       if ( unlink_directory(testsuite_tmp_dir, TRUE) < 0 )
103554
 
+               i_warning("failed to remove temporary directory '%s': %m.",
103555
 
+                       testsuite_tmp_dir);
103556
 
+
103557
 
+       i_free(testsuite_tmp_dir);
103558
 
+}
103559
 
+
103560
 
+const char *testsuite_tmp_dir_get(void)
103561
 
+{
103562
 
+       return testsuite_tmp_dir;
103563
 
+}
103564
 
+
103565
 
+/*
103566
 
+ * Main testsuite init/deinit
103567
 
+ */
103568
 
+
103569
 
+void testsuite_init(void)
103570
 
+{
103571
 
+       testsuite_test_context_init();
103572
 
+       testsuite_log_init();
103573
 
+       testsuite_tmp_dir_init();
103574
 
+       
103575
 
+       testsuite_script_init();
103576
 
+       testsuite_binary_init();
103577
 
+       testsuite_smtp_init();
103578
 
+}
103579
 
+
103580
 
+void testsuite_deinit(void)
103581
 
+{
103582
 
+       testsuite_smtp_deinit();
103583
 
+       testsuite_binary_deinit();
103584
 
+       testsuite_script_deinit();
103585
 
+       
103586
 
+       testsuite_tmp_dir_deinit();
103587
 
+       testsuite_log_deinit();
103588
 
+       testsuite_test_context_deinit();
103589
 
+}
103590
 
+
103591
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/testsuite/testsuite-common.h dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/testsuite-common.h
103592
 
--- dovecot-1.2.4/dovecot-libsieve/src/testsuite/testsuite-common.h     1970-01-01 01:00:00.000000000 +0100
103593
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/testsuite-common.h      2009-08-21 00:52:15.000000000 +0200
103594
 
@@ -0,0 +1,143 @@
103595
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
103596
 
+ */
103597
 
+
103598
 
+#ifndef __TESTSUITE_COMMON_H
103599
 
+#define __TESTSUITE_COMMON_H
103600
 
+
103601
 
+#include "sieve-common.h"
103602
 
+
103603
 
+/*
103604
 
+ * Extension
103605
 
+ */
103606
 
+
103607
 
+extern const struct sieve_extension testsuite_extension;
103608
 
+
103609
 
+extern const struct sieve_script_env *testsuite_scriptenv;
103610
 
+
103611
 
+/* 
103612
 
+ * Validator context 
103613
 
+ */
103614
 
+
103615
 
+struct testsuite_validator_context {
103616
 
+       struct sieve_validator_object_registry *object_registrations;
103617
 
+};
103618
 
+
103619
 
+bool testsuite_validator_context_initialize(struct sieve_validator *valdtr);
103620
 
+struct testsuite_validator_context *testsuite_validator_context_get
103621
 
+       (struct sieve_validator *valdtr);
103622
 
+
103623
 
+/* 
103624
 
+ * Generator context 
103625
 
+ */
103626
 
+
103627
 
+struct testsuite_generator_context {
103628
 
+       struct sieve_jumplist *exit_jumps;
103629
 
+};
103630
 
+
103631
 
+bool testsuite_generator_context_initialize(struct sieve_generator *gentr);
103632
 
+
103633
 
+/*
103634
 
+ * Commands
103635
 
+ */
103636
 
+
103637
 
+extern const struct sieve_command cmd_test;
103638
 
+extern const struct sieve_command cmd_test_fail;
103639
 
+extern const struct sieve_command cmd_test_set;
103640
 
+extern const struct sieve_command cmd_test_result_reset;
103641
 
+extern const struct sieve_command cmd_test_result_print;
103642
 
+extern const struct sieve_command cmd_test_message;
103643
 
+extern const struct sieve_command cmd_test_mailbox;
103644
 
+extern const struct sieve_command cmd_test_binary;
103645
 
+
103646
 
+/*
103647
 
+ * Tests
103648
 
+ */
103649
 
+
103650
 
+extern const struct sieve_command tst_test_script_compile;
103651
 
+extern const struct sieve_command tst_test_script_run;
103652
 
+extern const struct sieve_command tst_test_error;
103653
 
+extern const struct sieve_command tst_test_result;
103654
 
+extern const struct sieve_command tst_test_result_execute;
103655
 
+
103656
 
+/* 
103657
 
+ * Operations 
103658
 
+ */
103659
 
+
103660
 
+enum testsuite_operation_code {
103661
 
+       TESTSUITE_OPERATION_TEST,
103662
 
+       TESTSUITE_OPERATION_TEST_FINISH,
103663
 
+       TESTSUITE_OPERATION_TEST_FAIL,
103664
 
+       TESTSUITE_OPERATION_TEST_SET,
103665
 
+       TESTSUITE_OPERATION_TEST_SCRIPT_COMPILE,
103666
 
+       TESTSUITE_OPERATION_TEST_SCRIPT_RUN,
103667
 
+       TESTSUITE_OPERATION_TEST_ERROR,
103668
 
+       TESTSUITE_OPERATION_TEST_RESULT,
103669
 
+       TESTSUITE_OPERATION_TEST_RESULT_EXECUTE,
103670
 
+       TESTSUITE_OPERATION_TEST_RESULT_RESET,
103671
 
+       TESTSUITE_OPERATION_TEST_RESULT_PRINT,
103672
 
+       TESTSUITE_OPERATION_TEST_MESSAGE_SMTP,
103673
 
+       TESTSUITE_OPERATION_TEST_MESSAGE_MAILBOX,
103674
 
+       TESTSUITE_OPERATION_TEST_MAILBOX_CREATE,
103675
 
+       TESTSUITE_OPERATION_TEST_MAILBOX_DELETE,
103676
 
+       TESTSUITE_OPERATION_TEST_BINARY_LOAD,
103677
 
+       TESTSUITE_OPERATION_TEST_BINARY_SAVE,
103678
 
+};
103679
 
+
103680
 
+extern const struct sieve_operation test_operation;
103681
 
+extern const struct sieve_operation test_finish_operation;
103682
 
+extern const struct sieve_operation test_fail_operation;
103683
 
+extern const struct sieve_operation test_set_operation;
103684
 
+extern const struct sieve_operation test_script_compile_operation;
103685
 
+extern const struct sieve_operation test_script_run_operation;
103686
 
+extern const struct sieve_operation test_error_operation;
103687
 
+extern const struct sieve_operation test_result_operation;
103688
 
+extern const struct sieve_operation test_result_execute_operation;
103689
 
+extern const struct sieve_operation test_result_reset_operation;
103690
 
+extern const struct sieve_operation test_result_print_operation;
103691
 
+extern const struct sieve_operation test_message_smtp_operation;
103692
 
+extern const struct sieve_operation test_message_mailbox_operation;
103693
 
+extern const struct sieve_operation test_mailbox_create_operation;
103694
 
+extern const struct sieve_operation test_mailbox_delete_operation;
103695
 
+extern const struct sieve_operation test_binary_load_operation;
103696
 
+extern const struct sieve_operation test_binary_save_operation;
103697
 
+
103698
 
+/* 
103699
 
+ * Operands 
103700
 
+ */
103701
 
+
103702
 
+extern const struct sieve_operand testsuite_object_operand;
103703
 
+extern const struct sieve_operand testsuite_substitution_operand;
103704
 
+
103705
 
+enum testsuite_operand_code {
103706
 
+       TESTSUITE_OPERAND_OBJECT,
103707
 
+       TESTSUITE_OPERAND_SUBSTITUTION
103708
 
+};
103709
 
+
103710
 
+/* 
103711
 
+ * Test context 
103712
 
+ */
103713
 
+
103714
 
+void testsuite_test_start(string_t *name);
103715
 
+void testsuite_test_fail(string_t *reason);
103716
 
+void testsuite_test_failf(const char *fmt, ...) ATTR_FORMAT(1, 2);
103717
 
+void testsuite_test_fail_cstr(const char *reason);
103718
 
+
103719
 
+void testsuite_test_succeed(string_t *reason);
103720
 
+
103721
 
+void testsuite_testcase_fail(const char *reason);
103722
 
+int testsuite_testcase_result(void);
103723
 
+
103724
 
+/*
103725
 
+ * Testsuite temporary directory
103726
 
+ */
103727
 
103728
 
+const char *testsuite_tmp_dir_get(void);
103729
 
+
103730
 
+/* 
103731
 
+ * Testsuite init/deinit 
103732
 
+ */
103733
 
+
103734
 
+void testsuite_init(void);
103735
 
+void testsuite_deinit(void);
103736
 
+
103737
 
+#endif /* __TESTSUITE_COMMON_H */
103738
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/testsuite/testsuite-log.c dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/testsuite-log.c
103739
 
--- dovecot-1.2.4/dovecot-libsieve/src/testsuite/testsuite-log.c        1970-01-01 01:00:00.000000000 +0100
103740
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/testsuite-log.c 2009-07-21 01:22:08.000000000 +0200
103741
 
@@ -0,0 +1,125 @@
103742
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
103743
 
+ */
103744
 
+
103745
 
+#include "lib.h"
103746
 
+#include "array.h"
103747
 
+
103748
 
+#include "sieve-common.h"
103749
 
+#include "sieve-error-private.h"
103750
 
+
103751
 
+#include "testsuite-log.h"
103752
 
+
103753
 
+/* 
103754
 
+ * Testsuite error handler
103755
 
+ */
103756
 
+
103757
 
+struct sieve_error_handler *testsuite_log_ehandler = NULL;
103758
 
+
103759
 
+struct _testsuite_log_message {
103760
 
+       const char *location;
103761
 
+       const char *message;
103762
 
+};
103763
 
+
103764
 
+bool _testsuite_log_stdout = FALSE;
103765
 
+
103766
 
+unsigned int _testsuite_log_error_index = 0;
103767
 
+
103768
 
+static pool_t _testsuite_logmsg_pool = NULL;
103769
 
+ARRAY_DEFINE(_testsuite_log_errors, struct _testsuite_log_message);
103770
 
+
103771
 
+static void _testsuite_log_verror
103772
 
+(struct sieve_error_handler *ehandler ATTR_UNUSED, const char *location,
103773
 
+       const char *fmt, va_list args)
103774
 
+{
103775
 
+       pool_t pool = _testsuite_logmsg_pool;
103776
 
+       struct _testsuite_log_message msg;
103777
 
+
103778
 
+       if ( _testsuite_log_stdout )    
103779
 
+       {
103780
 
+               va_list args_copy;
103781
 
+               VA_COPY(args_copy, args);
103782
 
+               printf("error: %s: %s.\n", location, t_strdup_vprintf(fmt, args_copy));
103783
 
+       }
103784
 
+       
103785
 
+       msg.location = p_strdup(pool, location);
103786
 
+       msg.message = p_strdup_vprintf(pool, fmt, args);
103787
 
+
103788
 
+       array_append(&_testsuite_log_errors, &msg, 1);  
103789
 
+}
103790
 
+
103791
 
+static struct sieve_error_handler *_testsuite_log_ehandler_create(void)
103792
 
+{
103793
 
+       pool_t pool;
103794
 
+       struct sieve_error_handler *ehandler;
103795
 
+
103796
 
+       /* Pool is not strictly necessary, but other handler types will need a pool,
103797
 
+        * so this one will have one too.
103798
 
+        */
103799
 
+       pool = pool_alloconly_create
103800
 
+               ("testsuite_log_handler", sizeof(struct sieve_error_handler));
103801
 
+       ehandler = p_new(pool, struct sieve_error_handler, 1);
103802
 
+       sieve_error_handler_init(ehandler, pool, 0);
103803
 
+
103804
 
+       ehandler->verror = _testsuite_log_verror;
103805
 
+
103806
 
+       return ehandler;
103807
 
+}
103808
 
+
103809
 
+void testsuite_log_clear_messages(void)
103810
 
+{
103811
 
+       if ( _testsuite_logmsg_pool != NULL ) {
103812
 
+               if ( array_count(&_testsuite_log_errors) == 0 )
103813
 
+                       return;
103814
 
+               pool_unref(&_testsuite_logmsg_pool);
103815
 
+       }
103816
 
+
103817
 
+       _testsuite_logmsg_pool = pool_alloconly_create
103818
 
+               ("testsuite_log_messages", 8192);
103819
 
+       
103820
 
+       p_array_init(&_testsuite_log_errors, _testsuite_logmsg_pool, 128);      
103821
 
+
103822
 
+       sieve_error_handler_reset(testsuite_log_ehandler);
103823
 
+}
103824
 
+
103825
 
+void testsuite_log_get_error_init(void)
103826
 
+{
103827
 
+       _testsuite_log_error_index = 0;
103828
 
+}
103829
 
+
103830
 
+const char *testsuite_log_get_error_next(bool location)
103831
 
+{
103832
 
+       const struct _testsuite_log_message *msg;
103833
 
+
103834
 
+       if ( _testsuite_log_error_index >= array_count(&_testsuite_log_errors) )
103835
 
+               return NULL;
103836
 
+
103837
 
+       msg = array_idx(&_testsuite_log_errors, _testsuite_log_error_index++);
103838
 
+
103839
 
+       if ( location ) 
103840
 
+               return msg->location;
103841
 
+
103842
 
+       return msg->message;            
103843
 
+}
103844
 
+
103845
 
+void testsuite_log_init(void)
103846
 
+{
103847
 
+       testsuite_log_ehandler = _testsuite_log_ehandler_create();      
103848
 
+       sieve_error_handler_accept_infolog(testsuite_log_ehandler, TRUE);
103849
 
+
103850
 
+       sieve_system_ehandler_set(testsuite_log_ehandler);
103851
 
+
103852
 
+       testsuite_log_clear_messages();
103853
 
+}
103854
 
+
103855
 
+void testsuite_log_deinit(void)
103856
 
+{
103857
 
+       sieve_system_ehandler_reset();
103858
 
+
103859
 
+       sieve_error_handler_unref(&testsuite_log_ehandler);
103860
 
+
103861
 
+       pool_unref(&_testsuite_logmsg_pool);
103862
 
+}
103863
 
+
103864
 
+
103865
 
+
103866
 
+
103867
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/testsuite/testsuite-log.h dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/testsuite-log.h
103868
 
--- dovecot-1.2.4/dovecot-libsieve/src/testsuite/testsuite-log.h        1970-01-01 01:00:00.000000000 +0100
103869
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/testsuite-log.h 2009-01-06 00:15:52.000000000 +0100
103870
 
@@ -0,0 +1,18 @@
103871
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
103872
 
+ */
103873
 
+
103874
 
+#ifndef __TESTSUITE_LOG_H
103875
 
+#define __TESTSUITE_LOG_H
103876
 
+
103877
 
+#include "sieve-common.h"
103878
 
+
103879
 
+extern struct sieve_error_handler *testsuite_log_ehandler;
103880
 
+
103881
 
+void testsuite_log_init(void);
103882
 
+void testsuite_log_deinit(void);
103883
 
+
103884
 
+void testsuite_log_clear_messages(void);
103885
 
+void testsuite_log_get_error_init(void);
103886
 
+const char *testsuite_log_get_error_next(bool location);
103887
 
+
103888
 
+#endif /* __TESTSUITE_LOG_H */
103889
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/testsuite/testsuite-mailstore.c dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/testsuite-mailstore.c
103890
 
--- dovecot-1.2.4/dovecot-libsieve/src/testsuite/testsuite-mailstore.c  1970-01-01 01:00:00.000000000 +0100
103891
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/testsuite-mailstore.c   2009-08-02 09:44:14.000000000 +0200
103892
 
@@ -0,0 +1,181 @@
103893
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
103894
 
+ */
103895
 
+
103896
 
+#include "lib.h"
103897
 
+#include "mempool.h"
103898
 
+#include "imem.h"
103899
 
+#include "array.h"
103900
 
+#include "unlink-directory.h"
103901
 
+#include "env-util.h"
103902
 
+#include "mail-namespace.h"
103903
 
+#include "mail-storage.h"
103904
 
+
103905
 
+#include "sieve-common.h" 
103906
 
+#include "sieve-error.h"
103907
 
+#include "sieve-interpreter.h"
103908
 
103909
 
+#include "testsuite-message.h"
103910
 
+#include "testsuite-common.h"
103911
 
+#include "testsuite-smtp.h"
103912
 
+
103913
 
+#include "testsuite-mailstore.h"
103914
 
+
103915
 
+#include <sys/stat.h>
103916
 
+#include <sys/types.h>
103917
 
+
103918
 
+/*
103919
 
+ * Forward declarations
103920
 
+ */
103921
 
+
103922
 
+static void testsuite_mailstore_close(void);
103923
 
+
103924
 
+/*
103925
 
+ * State
103926
 
+ */
103927
 
+
103928
 
+static char *testsuite_mailstore_tmp = NULL;
103929
 
+static struct mail_user *testsuite_mailstore_user = NULL;
103930
 
+
103931
 
+static char *testsuite_mailstore_folder = NULL;
103932
 
+static struct mailbox *testsuite_mailstore_box = NULL;
103933
 
+static struct mailbox_transaction_context *testsuite_mailstore_trans = NULL;
103934
 
+static struct mail *testsuite_mailstore_mail = NULL;
103935
 
+
103936
 
+/*
103937
 
+ * Initialization
103938
 
+ */
103939
 
+
103940
 
+void testsuite_mailstore_init(const char *user, const char *home)
103941
 
+{      
103942
 
+       testsuite_mailstore_tmp = i_strconcat
103943
 
+               (testsuite_tmp_dir_get(), "/mailstore", NULL);
103944
 
+
103945
 
+       if ( mkdir(testsuite_mailstore_tmp, 0700) < 0 ) {
103946
 
+               i_fatal("failed to create temporary directory '%s': %m.", 
103947
 
+                       testsuite_mailstore_tmp);               
103948
 
+       }
103949
 
+
103950
 
+       env_put(t_strdup_printf("NAMESPACE_1=maildir:%s", testsuite_mailstore_tmp));
103951
 
+       env_put("NAMESPACE_1_INBOX=1");
103952
 
+       env_put("NAMESPACE_1_LIST=1");
103953
 
+       env_put("NAMESPACE_1_SEP=.");
103954
 
+       env_put("NAMESPACE_1_SUBSCRIPTIONS=1");
103955
 
+
103956
 
+       testsuite_mailstore_user = mail_user_init(user);
103957
 
+       mail_user_set_home(testsuite_mailstore_user, home);
103958
 
+       if (mail_namespaces_init(testsuite_mailstore_user) < 0)
103959
 
+               i_fatal("Namespace initialization failed");     
103960
 
+}
103961
 
+
103962
 
+void testsuite_mailstore_deinit(void)
103963
 
+{
103964
 
+       testsuite_mailstore_close();
103965
 
+
103966
 
+       /* De-initialize mail user object */
103967
 
+       if ( testsuite_mailstore_user != NULL )
103968
 
+               mail_user_unref(&testsuite_mailstore_user);
103969
 
+
103970
 
+       if ( unlink_directory(testsuite_mailstore_tmp, TRUE) < 0 ) {
103971
 
+               i_warning("failed to remove temporary directory '%s': %m.",
103972
 
+                       testsuite_mailstore_tmp);
103973
 
+       }
103974
 
+       
103975
 
+       i_free(testsuite_mailstore_tmp);                
103976
 
+}
103977
 
+
103978
 
+void testsuite_mailstore_reset(void)
103979
 
+{
103980
 
+}
103981
 
+
103982
 
+/*
103983
 
+ * Mailbox Access
103984
 
+ */
103985
 
+
103986
 
+struct mail_namespace *testsuite_mailstore_get_namespace(void)
103987
 
+{
103988
 
+       return testsuite_mailstore_user->namespaces;
103989
 
+}
103990
 
+
103991
 
+bool testsuite_mailstore_mailbox_create
103992
 
+(const struct sieve_runtime_env *renv ATTR_UNUSED, const char *folder)
103993
 
+{
103994
 
+       struct mail_storage *storage = testsuite_mailstore_user->namespaces->storage;
103995
 
+
103996
 
+       /* Try creating it */
103997
 
+       if ( mail_storage_mailbox_create(storage, folder, FALSE) < 0 )
103998
 
+               return FALSE;
103999
 
+
104000
 
+       return TRUE;
104001
 
+}
104002
 
+
104003
 
+static void testsuite_mailstore_close(void)
104004
 
+{
104005
 
+       if ( testsuite_mailstore_mail != NULL )
104006
 
+               mail_free(&testsuite_mailstore_mail);
104007
 
+
104008
 
+       if ( testsuite_mailstore_trans != NULL )
104009
 
+               mailbox_transaction_rollback(&testsuite_mailstore_trans);
104010
 
+               
104011
 
+       if ( testsuite_mailstore_box != NULL )
104012
 
+               mailbox_close(&testsuite_mailstore_box);
104013
 
+
104014
 
+       if ( testsuite_mailstore_folder != NULL )
104015
 
+               i_free(testsuite_mailstore_folder);
104016
 
+}
104017
 
+
104018
 
+static struct mail *testsuite_mailstore_open(const char *folder)
104019
 
+{
104020
 
+       enum mailbox_open_flags open_flags = 
104021
 
+               MAILBOX_OPEN_FAST | MAILBOX_OPEN_KEEP_RECENT | 
104022
 
+               MAILBOX_OPEN_SAVEONLY | MAILBOX_OPEN_POST_SESSION;
104023
 
+       struct mail_storage *storage = testsuite_mailstore_user->namespaces->storage;
104024
 
+       struct mailbox *box;
104025
 
+       struct mailbox_transaction_context *t;
104026
 
+
104027
 
+       if ( testsuite_mailstore_mail == NULL ) {
104028
 
+               testsuite_mailstore_close();
104029
 
+       } else if ( testsuite_mailstore_folder != NULL 
104030
 
+               && strcmp(folder, testsuite_mailstore_folder) != 0  ) {
104031
 
+               testsuite_mailstore_close();    
104032
 
+       } else {
104033
 
+               return testsuite_mailstore_mail;
104034
 
+       }
104035
 
+
104036
 
+       box = mailbox_open(&storage, folder, NULL, open_flags);
104037
 
+       if ( box == NULL ) {
104038
 
+               sieve_sys_error("testsuite: failed to open mailbox '%s'", folder);
104039
 
+               return NULL;    
104040
 
+       }
104041
 
+       
104042
 
+       /* Sync mailbox */
104043
 
+
104044
 
+       if ( mailbox_sync(box, MAILBOX_SYNC_FLAG_FULL_READ, 0, NULL) < 0 ) {
104045
 
+               sieve_sys_error("testsuite: failed to sync mailbox '%s'", folder);
104046
 
+               return NULL;
104047
 
+       }
104048
 
+
104049
 
+       /* Start transaction */
104050
 
+
104051
 
+       t = mailbox_transaction_begin(box, 0);
104052
 
+
104053
 
+       testsuite_mailstore_folder = i_strdup(folder);
104054
 
+       testsuite_mailstore_box = box;
104055
 
+       testsuite_mailstore_trans = t;
104056
 
+       testsuite_mailstore_mail = mail_alloc(t, 0, NULL);
104057
 
+
104058
 
+       return testsuite_mailstore_mail;
104059
 
+}
104060
 
+
104061
 
+bool testsuite_mailstore_mail_index
104062
 
+(const struct sieve_runtime_env *renv, const char *folder, unsigned int index)
104063
 
+{
104064
 
+       struct mail *mail = testsuite_mailstore_open(folder);
104065
 
+
104066
 
+       if ( mail == NULL )
104067
 
+               return FALSE;
104068
 
+
104069
 
+       mail_set_seq(mail, index+1);
104070
 
+       testsuite_message_set_mail(renv, mail);
104071
 
+
104072
 
+       return TRUE;
104073
 
+}
104074
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/testsuite/testsuite-mailstore.h dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/testsuite-mailstore.h
104075
 
--- dovecot-1.2.4/dovecot-libsieve/src/testsuite/testsuite-mailstore.h  1970-01-01 01:00:00.000000000 +0100
104076
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/testsuite-mailstore.h   2009-07-31 17:34:58.000000000 +0200
104077
 
@@ -0,0 +1,34 @@
104078
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
104079
 
+ */
104080
 
+
104081
 
+#ifndef __TESTSUITE_MAILSTORE_H
104082
 
+#define __TESTSUITE_MAILSTORE_H
104083
 
+
104084
 
+#include "sieve-common.h" 
104085
 
+
104086
 
+/*
104087
 
+ * Initialization
104088
 
+ */
104089
 
+
104090
 
+void testsuite_mailstore_init(const char *user, const char *home);
104091
 
+void testsuite_mailstore_deinit(void);
104092
 
+void testsuite_mailstore_reset(void);
104093
 
+
104094
 
+/* 
104095
 
+ * Namespace
104096
 
+ */
104097
 
+
104098
 
+struct mail_namespace *testsuite_mailstore_get_namespace(void);
104099
 
+
104100
 
+/*
104101
 
+ * Mailbox Access
104102
 
+ */
104103
 
+
104104
 
+bool testsuite_mailstore_mailbox_create
104105
 
+       (const struct sieve_runtime_env *renv ATTR_UNUSED, const char *folder);
104106
 
+
104107
 
+bool testsuite_mailstore_mail_index
104108
 
+       (const struct sieve_runtime_env *renv, const char *folder, 
104109
 
+               unsigned int index);
104110
 
+
104111
 
+#endif /* __TESTSUITE_MAILSTORE */
104112
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/testsuite/testsuite-message.c dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/testsuite-message.c
104113
 
--- dovecot-1.2.4/dovecot-libsieve/src/testsuite/testsuite-message.c    1970-01-01 01:00:00.000000000 +0100
104114
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/testsuite-message.c     2009-08-21 00:52:15.000000000 +0200
104115
 
@@ -0,0 +1,184 @@
104116
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
104117
 
+ */
104118
 
+
104119
 
+#include "lib.h"
104120
 
+#include "str.h"
104121
 
+#include "istream.h"
104122
 
+#include "mail-storage.h"
104123
 
+
104124
 
+#include "mail-raw.h"
104125
 
+
104126
 
+#include "sieve-common.h"
104127
 
+#include "sieve-message.h"
104128
 
+#include "sieve-interpreter.h"
104129
 
+
104130
 
+#include "testsuite-common.h"
104131
 
+#include "testsuite-message.h"
104132
 
+
104133
 
+/* 
104134
 
+ * Testsuite message environment 
104135
 
+ */
104136
 
104137
 
+struct sieve_message_data testsuite_msgdata;
104138
 
+
104139
 
+static const char *testsuite_user;
104140
 
+static struct mail_raw *_raw_message;
104141
 
+
104142
 
+static const char *_default_message_data = 
104143
 
+"From: stephan@rename-it.nl\n"
104144
 
+"To: sirius@drunksnipers.com\n"
104145
 
+"Subject: Frop!\n"
104146
 
+"\n"
104147
 
+"Friep!\n";
104148
 
+
104149
 
+static string_t *envelope_from;
104150
 
+static string_t *envelope_to;
104151
 
+static string_t *envelope_auth;
104152
 
+
104153
 
+pool_t message_pool;
104154
 
+
104155
 
+static void _testsuite_message_set_data(struct mail *mail)
104156
 
+{
104157
 
+       const char *recipient = NULL, *sender = NULL;
104158
 
+       
104159
 
+       /* 
104160
 
+        * Collect necessary message data 
104161
 
+        */
104162
 
+        
104163
 
+       /* Get recipient address */ 
104164
 
+       (void)mail_get_first_header(mail, "Envelope-To", &recipient);
104165
 
+       if ( recipient == NULL )
104166
 
+               (void)mail_get_first_header(mail, "To", &recipient);
104167
 
+       if ( recipient == NULL ) 
104168
 
+               recipient = "recipient@example.com";
104169
 
+       
104170
 
+       /* Get sender address */
104171
 
+       (void)mail_get_first_header(mail, "Return-path", &sender);
104172
 
+       if ( sender == NULL ) 
104173
 
+               (void)mail_get_first_header(mail, "Sender", &sender);
104174
 
+       if ( sender == NULL ) 
104175
 
+               (void)mail_get_first_header(mail, "From", &sender);
104176
 
+       if ( sender == NULL ) 
104177
 
+               sender = "sender@example.com";
104178
 
+
104179
 
+       memset(&testsuite_msgdata, 0, sizeof(testsuite_msgdata));       
104180
 
+       testsuite_msgdata.mail = mail;
104181
 
+       testsuite_msgdata.auth_user = testsuite_user;
104182
 
+       testsuite_msgdata.return_path = sender;
104183
 
+       testsuite_msgdata.to_address = recipient;
104184
 
+
104185
 
+       (void)mail_get_first_header(mail, "Message-ID", &testsuite_msgdata.id);
104186
 
+}
104187
 
+
104188
 
+void testsuite_message_init(const char *user)
104189
 
+{              
104190
 
+       message_pool = pool_alloconly_create("testsuite_message", 6096);
104191
 
+
104192
 
+       string_t *default_message = str_new(message_pool, 1024);
104193
 
+       str_append(default_message, _default_message_data);
104194
 
+
104195
 
+       testsuite_user = user;
104196
 
+       mail_raw_init(user);
104197
 
+       _raw_message = mail_raw_open_data(default_message);
104198
 
+       _testsuite_message_set_data(_raw_message->mail);
104199
 
+
104200
 
+       envelope_to = str_new(message_pool, 256);
104201
 
+       envelope_from = str_new(message_pool, 256);
104202
 
+       envelope_auth = str_new(message_pool, 256);
104203
 
+}
104204
 
+
104205
 
+void testsuite_message_set_string
104206
 
+(const struct sieve_runtime_env *renv, string_t *message)
104207
 
+{
104208
 
+       mail_raw_close(_raw_message);
104209
 
+
104210
 
+       _raw_message = mail_raw_open_data(message);
104211
 
+
104212
 
+       _testsuite_message_set_data(_raw_message->mail);
104213
 
+
104214
 
+       sieve_message_context_flush(renv->msgctx);
104215
 
+
104216
 
+       /*{ 
104217
 
+               const unsigned char *data;
104218
 
+               struct istream *input;
104219
 
+               size_t size;
104220
 
+               int ret;
104221
 
+
104222
 
+               if (mail_get_stream(_raw_message->mail, NULL, NULL, &input) < 0)
104223
 
+               return;
104224
 
+
104225
 
+               while ((ret = i_stream_read_data(input, &data, &size, 0)) > 0) {
104226
 
+                       if (write(1, data, size) == 0)
104227
 
+                               break;
104228
 
+                       i_stream_skip(input, size);
104229
 
+               }
104230
 
+    }*/
104231
 
+}
104232
 
+
104233
 
+void testsuite_message_set_file
104234
 
+(const struct sieve_runtime_env *renv, const char *file_path)
104235
 
+{
104236
 
+       mail_raw_close(_raw_message);
104237
 
+        
104238
 
+       _raw_message = mail_raw_open_file(file_path);
104239
 
+
104240
 
+       _testsuite_message_set_data(_raw_message->mail);
104241
 
+
104242
 
+       sieve_message_context_flush(renv->msgctx);
104243
 
+}
104244
 
+
104245
 
+void testsuite_message_set_mail
104246
 
+(const struct sieve_runtime_env *renv, struct mail *mail)
104247
 
+{
104248
 
+       _testsuite_message_set_data(mail);
104249
 
+
104250
 
+       sieve_message_context_flush(renv->msgctx);
104251
 
+}
104252
 
+       
104253
 
+void testsuite_message_deinit(void)
104254
 
+{
104255
 
+       mail_raw_close(_raw_message);
104256
 
+       mail_raw_deinit();
104257
 
+
104258
 
+       pool_unref(&message_pool);
104259
 
+}
104260
 
+
104261
 
+void testsuite_envelope_set_sender
104262
 
+(const struct sieve_runtime_env *renv, const char *value)
104263
 
+{
104264
 
+       str_truncate(envelope_from, 0);
104265
 
+
104266
 
+       if ( value != NULL )
104267
 
+               str_append(envelope_from, value);
104268
 
+
104269
 
+       testsuite_msgdata.return_path = str_c(envelope_from);
104270
 
+
104271
 
+       sieve_message_context_flush(renv->msgctx);
104272
 
+}
104273
 
+
104274
 
+void testsuite_envelope_set_recipient
104275
 
+(const struct sieve_runtime_env *renv, const char *value)
104276
 
+{
104277
 
+       str_truncate(envelope_to, 0);
104278
 
+
104279
 
+       if ( value != NULL )
104280
 
+               str_append(envelope_to, value);
104281
 
+
104282
 
+       testsuite_msgdata.to_address = str_c(envelope_to);
104283
 
+
104284
 
+       sieve_message_context_flush(renv->msgctx);
104285
 
+}
104286
 
+
104287
 
+void testsuite_envelope_set_auth_user
104288
 
+(const struct sieve_runtime_env *renv, const char *value)
104289
 
+{
104290
 
+       str_truncate(envelope_auth, 0);
104291
 
+
104292
 
+       if ( value != NULL )
104293
 
+               str_append(envelope_auth, value);
104294
 
+
104295
 
+       testsuite_msgdata.auth_user = str_c(envelope_auth);
104296
 
+
104297
 
+       sieve_message_context_flush(renv->msgctx);
104298
 
+} 
104299
 
104300
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/testsuite/testsuite-message.h dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/testsuite-message.h
104301
 
--- dovecot-1.2.4/dovecot-libsieve/src/testsuite/testsuite-message.h    1970-01-01 01:00:00.000000000 +0100
104302
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/testsuite-message.h     2009-07-31 17:34:58.000000000 +0200
104303
 
@@ -0,0 +1,28 @@
104304
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
104305
 
+ */
104306
 
+
104307
 
+#ifndef __TESTSUITE_MESSAGE_H
104308
 
+#define __TESTSUITE_MESSAGE_H
104309
 
+
104310
 
+#include "sieve-common.h"
104311
 
+
104312
 
+extern struct sieve_message_data testsuite_msgdata;
104313
 
+
104314
 
+void testsuite_message_init(const char *user);
104315
 
+void testsuite_message_deinit(void);
104316
 
+
104317
 
+void testsuite_message_set_string
104318
 
+       (const struct sieve_runtime_env *renv, string_t *message);
104319
 
+void testsuite_message_set_file
104320
 
+       (const struct sieve_runtime_env *renv, const char *file_path);
104321
 
+void testsuite_message_set_mail
104322
 
+       (const struct sieve_runtime_env *renv, struct mail *mail);
104323
 
+
104324
 
+void testsuite_envelope_set_sender
104325
 
+       (const struct sieve_runtime_env *renv, const char *value);
104326
 
+void testsuite_envelope_set_recipient
104327
 
+       (const struct sieve_runtime_env *renv, const char *value);
104328
 
+void testsuite_envelope_set_auth_user
104329
 
+       (const struct sieve_runtime_env *renv, const char *value);
104330
 
+
104331
 
+#endif /* __TESTSUITE_MESSAGE_H */
104332
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/testsuite/testsuite-objects.c dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/testsuite-objects.c
104333
 
--- dovecot-1.2.4/dovecot-libsieve/src/testsuite/testsuite-objects.c    1970-01-01 01:00:00.000000000 +0100
104334
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/testsuite-objects.c     2009-07-21 00:46:10.000000000 +0200
104335
 
@@ -0,0 +1,335 @@
104336
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
104337
 
+ */
104338
 
+
104339
 
+#include "lib.h"
104340
 
+#include "string.h"
104341
 
+#include "ostream.h"
104342
 
+#include "hash.h"
104343
 
+#include "mail-storage.h"
104344
 
+
104345
 
+#include "sieve.h"
104346
 
+#include "sieve-code.h"
104347
 
+#include "sieve-commands.h"
104348
 
+#include "sieve-extensions.h"
104349
 
+#include "sieve-validator.h"
104350
 
+#include "sieve-generator.h"
104351
 
+#include "sieve-binary.h"
104352
 
+#include "sieve-dump.h"
104353
 
+
104354
 
+#include "testsuite-common.h"
104355
 
+#include "testsuite-objects.h"
104356
 
+#include "testsuite-message.h"
104357
 
104358
 
+/* 
104359
 
+ * Testsuite core objects
104360
 
+ */
104361
 
104362
 
+enum testsuite_object_code {
104363
 
+       TESTSUITE_OBJECT_MESSAGE,
104364
 
+       TESTSUITE_OBJECT_ENVELOPE
104365
 
+};
104366
 
+
104367
 
+const struct testsuite_object *testsuite_core_objects[] = {
104368
 
+       &message_testsuite_object, &envelope_testsuite_object
104369
 
+};
104370
 
+
104371
 
+const unsigned int testsuite_core_objects_count =
104372
 
+       N_ELEMENTS(testsuite_core_objects);
104373
 
+
104374
 
+/* 
104375
 
+ * Testsuite object registry
104376
 
+ */
104377
 
104378
 
+void testsuite_object_register
104379
 
+(struct sieve_validator *valdtr, const struct testsuite_object *tobj) 
104380
 
+{
104381
 
+       struct testsuite_validator_context *ctx = testsuite_validator_context_get
104382
 
+               (valdtr);
104383
 
+       
104384
 
+       sieve_validator_object_registry_add
104385
 
+               (ctx->object_registrations, &tobj->object);
104386
 
+}
104387
 
+
104388
 
+const struct testsuite_object *testsuite_object_find
104389
 
+(struct sieve_validator *valdtr, const char *identifier) 
104390
 
+{
104391
 
+       struct testsuite_validator_context *ctx = testsuite_validator_context_get
104392
 
+               (valdtr);
104393
 
+       const struct sieve_object *object = 
104394
 
+               sieve_validator_object_registry_find
104395
 
+                       (ctx->object_registrations, identifier);
104396
 
+
104397
 
+       return (const struct testsuite_object *) object;
104398
 
+}
104399
 
+
104400
 
+void testsuite_register_core_objects
104401
 
+       (struct testsuite_validator_context *ctx)
104402
 
+{
104403
 
+       unsigned int i;
104404
 
+       
104405
 
+       /* Register core testsuite objects */
104406
 
+       for ( i = 0; i < testsuite_core_objects_count; i++ ) {
104407
 
+               sieve_validator_object_registry_add
104408
 
+                       (ctx->object_registrations, &(testsuite_core_objects[i]->object));
104409
 
+       }
104410
 
+}
104411
 
104412
 
+/* 
104413
 
+ * Testsuite object code
104414
 
+ */ 
104415
 
104416
 
+const struct sieve_operand_class sieve_testsuite_object_operand_class = 
104417
 
+       { "testsuite object" };
104418
 
+
104419
 
+static const struct sieve_extension_objects core_testsuite_objects =
104420
 
+       SIEVE_EXT_DEFINE_OBJECTS(testsuite_core_objects);
104421
 
+
104422
 
+const struct sieve_operand testsuite_object_operand = { 
104423
 
+       "testsuite-object",
104424
 
+       &testsuite_extension, 
104425
 
+       TESTSUITE_OPERAND_OBJECT, 
104426
 
+       &sieve_testsuite_object_operand_class,
104427
 
+       &core_testsuite_objects
104428
 
+};
104429
 
+
104430
 
+static void testsuite_object_emit
104431
 
+(struct sieve_binary *sbin, const struct testsuite_object *obj,
104432
 
+       int member_id)
104433
 
+{ 
104434
 
+       sieve_opr_object_emit(sbin, &obj->object);
104435
 
+       
104436
 
+       if ( obj->get_member_id != NULL ) {
104437
 
+               (void) sieve_binary_emit_byte(sbin, (unsigned char) member_id);
104438
 
+       }
104439
 
+}
104440
 
+
104441
 
+const struct testsuite_object *testsuite_object_read
104442
 
+(struct sieve_binary *sbin, sieve_size_t *address)
104443
 
+{
104444
 
+       const struct sieve_operand *operand = sieve_operand_read(sbin, address);
104445
 
+       
104446
 
+       return (const struct testsuite_object *) sieve_opr_object_read_data
104447
 
+               (sbin, operand, &sieve_testsuite_object_operand_class, address);
104448
 
+}
104449
 
+
104450
 
+const struct testsuite_object *testsuite_object_read_member
104451
 
+(struct sieve_binary *sbin, sieve_size_t *address, int *member_id)
104452
 
+{
104453
 
+       const struct testsuite_object *object;
104454
 
+               
104455
 
+       if ( (object = testsuite_object_read(sbin, address)) == NULL )
104456
 
+               return NULL;
104457
 
+               
104458
 
+       *member_id = -1;
104459
 
+       if ( object->get_member_id != NULL ) {
104460
 
+               if ( !sieve_binary_read_code(sbin, address, member_id) ) 
104461
 
+                       return NULL;
104462
 
+       }
104463
 
+       
104464
 
+       return object;
104465
 
+}
104466
 
+
104467
 
+const char *testsuite_object_member_name
104468
 
+(const struct testsuite_object *object, int member_id)
104469
 
+{
104470
 
+       const char *member = NULL;
104471
 
+
104472
 
+       if ( object->get_member_id != NULL ) {
104473
 
+               if ( object->get_member_name != NULL )
104474
 
+                       member = object->get_member_name(member_id);
104475
 
+       } else 
104476
 
+               return object->object.identifier;
104477
 
+               
104478
 
+       if ( member == NULL )   
104479
 
+               return t_strdup_printf("%s.%d", object->object.identifier, member_id);
104480
 
+       
104481
 
+       return t_strdup_printf("%s.%s", object->object.identifier, member);
104482
 
+}
104483
 
+
104484
 
+bool testsuite_object_dump
104485
 
+(const struct sieve_dumptime_env *denv, sieve_size_t *address)
104486
 
+{
104487
 
+       const struct testsuite_object *object;
104488
 
+       int member_id;
104489
 
+
104490
 
+       sieve_code_mark(denv);
104491
 
+               
104492
 
+       if ( (object = testsuite_object_read_member(denv->sbin, address, &member_id)) 
104493
 
+               == NULL )
104494
 
+               return FALSE;
104495
 
+       
104496
 
+       sieve_code_dumpf(denv, "%s: %s",
104497
 
+               sieve_testsuite_object_operand_class.name, 
104498
 
+               testsuite_object_member_name(object, member_id));
104499
 
+       
104500
 
+       return TRUE;
104501
 
+}
104502
 
+
104503
 
+/* 
104504
 
+ * Testsuite object argument
104505
 
+ */
104506
 
104507
 
+static bool arg_testsuite_object_generate
104508
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, 
104509
 
+               struct sieve_command_context *cmd);
104510
 
+
104511
 
+const struct sieve_argument testsuite_object_argument = { 
104512
 
+       "testsuite-object", 
104513
 
+       NULL, NULL, NULL, NULL,
104514
 
+       arg_testsuite_object_generate 
104515
 
+};
104516
 
104517
 
+struct testsuite_object_argctx {
104518
 
+       const struct testsuite_object *object;
104519
 
+       int member;
104520
 
+};
104521
 
+
104522
 
+bool testsuite_object_argument_activate
104523
 
+(struct sieve_validator *valdtr, struct sieve_ast_argument *arg,
104524
 
+       struct sieve_command_context *cmd) 
104525
 
+{
104526
 
+       const char *objname = sieve_ast_argument_strc(arg);
104527
 
+       const struct testsuite_object *object;
104528
 
+       int member_id;
104529
 
+       const char *member;
104530
 
+       struct testsuite_object_argctx *ctx;
104531
 
+       
104532
 
+       /* Parse the object specifier */
104533
 
+       
104534
 
+       member = strchr(objname, '.');
104535
 
+       if ( member != NULL ) {
104536
 
+               objname = t_strdup_until(objname, member);
104537
 
+               member++;
104538
 
+       }
104539
 
+       
104540
 
+       /* Find the object */
104541
 
+       
104542
 
+       object = testsuite_object_find(valdtr, objname);
104543
 
+       if ( object == NULL ) {
104544
 
+               sieve_argument_validate_error(valdtr, arg, 
104545
 
+                       "unknown testsuite object '%s'", objname);
104546
 
+               return FALSE;
104547
 
+       }
104548
 
+       
104549
 
+       /* Find the object member */
104550
 
+       
104551
 
+       member_id = -1;
104552
 
+       if ( member != NULL ) {
104553
 
+               if ( object->get_member_id == NULL || 
104554
 
+                       (member_id=object->get_member_id(member)) == -1 ) {
104555
 
+                       sieve_argument_validate_error(valdtr, arg, 
104556
 
+                               "member '%s' does not exist for testsuite object '%s'", member, objname);
104557
 
+                       return FALSE;
104558
 
+               }
104559
 
+       }
104560
 
+       
104561
 
+       /* Assign argument context */
104562
 
+       
104563
 
+       ctx = p_new(sieve_command_pool(cmd), struct testsuite_object_argctx, 1);
104564
 
+       ctx->object = object;
104565
 
+       ctx->member = member_id;
104566
 
+       
104567
 
+       arg->argument = &testsuite_object_argument;
104568
 
+       arg->context = (void *) ctx;
104569
 
+       
104570
 
+       return TRUE;
104571
 
+}
104572
 
+
104573
 
+static bool arg_testsuite_object_generate
104574
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, 
104575
 
+       struct sieve_command_context *cmd ATTR_UNUSED)
104576
 
+{
104577
 
+       struct testsuite_object_argctx *ctx = 
104578
 
+               (struct testsuite_object_argctx *) arg->context;
104579
 
+       
104580
 
+       testsuite_object_emit(cgenv->sbin, ctx->object, ctx->member);
104581
 
+               
104582
 
+       return TRUE;
104583
 
+}
104584
 
+
104585
 
+/* 
104586
 
+ * Testsuite core object implementation
104587
 
+ */
104588
 
104589
 
+static bool tsto_message_set_member
104590
 
+       (const struct sieve_runtime_env *renv, int id, string_t *value);
104591
 
+
104592
 
+static int tsto_envelope_get_member_id(const char *identifier);
104593
 
+static const char *tsto_envelope_get_member_name(int id);
104594
 
+static bool tsto_envelope_set_member
104595
 
+       (const struct sieve_runtime_env *renv, int id, string_t *value);
104596
 
+
104597
 
+const struct testsuite_object message_testsuite_object = { 
104598
 
+       SIEVE_OBJECT("message", &testsuite_object_operand, TESTSUITE_OBJECT_MESSAGE),
104599
 
+       NULL, NULL, 
104600
 
+       tsto_message_set_member, 
104601
 
+       NULL
104602
 
+};
104603
 
+
104604
 
+const struct testsuite_object envelope_testsuite_object = { 
104605
 
+       SIEVE_OBJECT("envelope", &testsuite_object_operand, TESTSUITE_OBJECT_ENVELOPE),
104606
 
+       tsto_envelope_get_member_id, 
104607
 
+       tsto_envelope_get_member_name,
104608
 
+       tsto_envelope_set_member, 
104609
 
+       NULL
104610
 
+};
104611
 
+
104612
 
+enum testsuite_object_envelope_field {
104613
 
+       TESTSUITE_OBJECT_ENVELOPE_FROM,
104614
 
+       TESTSUITE_OBJECT_ENVELOPE_TO,
104615
 
+       TESTSUITE_OBJECT_ENVELOPE_AUTH_USER
104616
 
+};
104617
 
+
104618
 
+static bool tsto_message_set_member
104619
 
+(const struct sieve_runtime_env *renv, int id, string_t *value) 
104620
 
+{
104621
 
+       if ( id != -1 ) return FALSE;
104622
 
+       
104623
 
+       testsuite_message_set_string(renv, value);
104624
 
+       
104625
 
+       return TRUE;
104626
 
+}
104627
 
+
104628
 
+static int tsto_envelope_get_member_id(const char *identifier)
104629
 
+{
104630
 
+       if ( strcasecmp(identifier, "from") == 0 )
104631
 
+               return TESTSUITE_OBJECT_ENVELOPE_FROM;
104632
 
+       if ( strcasecmp(identifier, "to") == 0 )
104633
 
+               return TESTSUITE_OBJECT_ENVELOPE_TO;
104634
 
+       if ( strcasecmp(identifier, "auth") == 0 )
104635
 
+               return TESTSUITE_OBJECT_ENVELOPE_AUTH_USER;     
104636
 
+       
104637
 
+       return -1;
104638
 
+}
104639
 
+
104640
 
+static const char *tsto_envelope_get_member_name(int id) 
104641
 
+{
104642
 
+       switch ( id ) {
104643
 
+       case TESTSUITE_OBJECT_ENVELOPE_FROM: 
104644
 
+               return "from";
104645
 
+       case TESTSUITE_OBJECT_ENVELOPE_TO: 
104646
 
+               return "to";
104647
 
+       case TESTSUITE_OBJECT_ENVELOPE_AUTH_USER: 
104648
 
+               return "auth";
104649
 
+       }
104650
 
+       
104651
 
+       return NULL;
104652
 
+}
104653
 
+
104654
 
+static bool tsto_envelope_set_member
104655
 
+(const struct sieve_runtime_env *renv, int id, string_t *value)
104656
 
+{
104657
 
+       switch ( id ) {
104658
 
+       case TESTSUITE_OBJECT_ENVELOPE_FROM: 
104659
 
+               testsuite_envelope_set_sender(renv, str_c(value));
104660
 
+               return TRUE;
104661
 
+       case TESTSUITE_OBJECT_ENVELOPE_TO:
104662
 
+               testsuite_envelope_set_recipient(renv, str_c(value));
104663
 
+               return TRUE;
104664
 
+       case TESTSUITE_OBJECT_ENVELOPE_AUTH_USER: 
104665
 
+               testsuite_envelope_set_auth_user(renv, str_c(value));
104666
 
+               return TRUE;
104667
 
+       }
104668
 
+       
104669
 
+       return FALSE;
104670
 
+}
104671
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/testsuite/testsuite-objects.h dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/testsuite-objects.h
104672
 
--- dovecot-1.2.4/dovecot-libsieve/src/testsuite/testsuite-objects.h    1970-01-01 01:00:00.000000000 +0100
104673
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/testsuite-objects.h     2009-01-06 00:15:52.000000000 +0100
104674
 
@@ -0,0 +1,75 @@
104675
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
104676
 
+ */
104677
 
+
104678
 
+#ifndef __TESTSUITE_OBJECTS_H
104679
 
+#define __TESTSUITE_OBJECTS_H
104680
 
+
104681
 
+#include "sieve-common.h"
104682
 
+#include "sieve-objects.h"
104683
 
+
104684
 
+#include "testsuite-common.h"
104685
 
+
104686
 
+/* 
104687
 
+ * Testsuite object operand 
104688
 
+ */
104689
 
+
104690
 
+struct testsuite_object_operand_interface {
104691
 
+       struct sieve_extension_objects testsuite_objects;
104692
 
+};
104693
 
+
104694
 
+extern const struct sieve_operand_class testsuite_object_oprclass;
104695
 
+
104696
 
+/* 
104697
 
+ * Testsuite object access 
104698
 
+ */
104699
 
+
104700
 
+struct testsuite_object {
104701
 
+       struct sieve_object object;
104702
 
+       
104703
 
+       int (*get_member_id)(const char *identifier);
104704
 
+       const char *(*get_member_name)(int id);
104705
 
+
104706
 
+       bool (*set_member)(const struct sieve_runtime_env *renv, int id, string_t *value);
104707
 
+       string_t *(*get_member)(const struct sieve_runtime_env *renv, int id);
104708
 
+};
104709
 
+
104710
 
+/* 
104711
 
+ * Testsuite object registration 
104712
 
+ */
104713
 
+
104714
 
+const struct testsuite_object *testsuite_object_find
104715
 
+       (struct sieve_validator *valdtr, const char *identifier);
104716
 
+void testsuite_object_register
104717
 
+       (struct sieve_validator *valdtr, const struct testsuite_object *tobj);          
104718
 
+void testsuite_register_core_objects
104719
 
+       (struct testsuite_validator_context *ctx);
104720
 
+               
104721
 
+/* 
104722
 
+ * Testsuite object argument 
104723
 
+ */            
104724
 
+       
104725
 
+bool testsuite_object_argument_activate
104726
 
+       (struct sieve_validator *valdtr, struct sieve_ast_argument *arg,
104727
 
+               struct sieve_command_context *cmd);             
104728
 
+               
104729
 
+/* 
104730
 
+ * Testsuite object code 
104731
 
+ */
104732
 
+
104733
 
+const struct testsuite_object *testsuite_object_read
104734
 
+  (struct sieve_binary *sbin, sieve_size_t *address);
104735
 
+const struct testsuite_object *testsuite_object_read_member
104736
 
+  (struct sieve_binary *sbin, sieve_size_t *address, int *member_id);
104737
 
+const char *testsuite_object_member_name
104738
 
+       (const struct testsuite_object *object, int member_id);
104739
 
+bool testsuite_object_dump
104740
 
+       (const struct sieve_dumptime_env *denv, sieve_size_t *address);
104741
 
+
104742
 
+/* 
104743
 
+ * Testsuite core objects 
104744
 
+ */
104745
 
+
104746
 
+extern const struct testsuite_object message_testsuite_object;
104747
 
+extern const struct testsuite_object envelope_testsuite_object;
104748
 
+
104749
 
+#endif /* __TESTSUITE_OBJECTS_H */
104750
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/testsuite/testsuite-result.c dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/testsuite-result.c
104751
 
--- dovecot-1.2.4/dovecot-libsieve/src/testsuite/testsuite-result.c     1970-01-01 01:00:00.000000000 +0100
104752
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/testsuite-result.c      2009-07-21 02:18:49.000000000 +0200
104753
 
@@ -0,0 +1,91 @@
104754
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
104755
 
+ */
104756
 
+
104757
 
+#include "lib.h"
104758
 
+#include "ostream.h"
104759
 
+
104760
 
+#include "sieve-common.h"
104761
 
+#include "sieve-error.h"
104762
 
+#include "sieve-actions.h"
104763
 
+#include "sieve-interpreter.h"
104764
 
+#include "sieve-result.h"
104765
 
+
104766
 
+#include "testsuite-common.h"
104767
 
+#include "testsuite-log.h"
104768
 
+#include "testsuite-message.h"
104769
 
+
104770
 
+#include "testsuite-result.h"
104771
 
+
104772
 
+static struct sieve_result *_testsuite_result;
104773
 
+
104774
 
+void testsuite_result_init(void)
104775
 
+{
104776
 
+       _testsuite_result = sieve_result_create
104777
 
+               (&testsuite_msgdata, testsuite_scriptenv, testsuite_log_ehandler);
104778
 
+}
104779
 
+
104780
 
+void testsuite_result_deinit(void)
104781
 
+{
104782
 
+       if ( _testsuite_result != NULL ) {
104783
 
+               sieve_result_unref(&_testsuite_result);
104784
 
+       }
104785
 
+}
104786
 
+
104787
 
+void testsuite_result_reset
104788
 
+(const struct sieve_runtime_env *renv)
104789
 
+{
104790
 
+       if ( _testsuite_result != NULL ) {
104791
 
+               sieve_result_unref(&_testsuite_result);
104792
 
+       }
104793
 
+
104794
 
+       _testsuite_result = sieve_result_create
104795
 
+               (&testsuite_msgdata, testsuite_scriptenv, testsuite_log_ehandler);
104796
 
+       sieve_interpreter_set_result(renv->interp, _testsuite_result);
104797
 
+}
104798
 
+
104799
 
+struct sieve_result *testsuite_result_get(void)
104800
 
+{
104801
 
+       return _testsuite_result;
104802
 
+}
104803
 
+
104804
 
+struct sieve_result_iterate_context *testsuite_result_iterate_init(void)
104805
 
+{
104806
 
+       if ( _testsuite_result == NULL )
104807
 
+               return NULL;
104808
 
+
104809
 
+       return sieve_result_iterate_init(_testsuite_result);
104810
 
+}
104811
 
+
104812
 
+bool testsuite_result_execute(const struct sieve_runtime_env *renv)
104813
 
+{
104814
 
+       int ret;
104815
 
+
104816
 
+       if ( _testsuite_result == NULL ) {
104817
 
+               sieve_runtime_error(renv, sieve_error_script_location(renv->script,0),
104818
 
+                       "testsuite: no result evaluated yet");
104819
 
+               return FALSE;
104820
 
+       }
104821
 
+
104822
 
+       testsuite_log_clear_messages();
104823
 
+
104824
 
+       /* Execute the result */        
104825
 
+       ret=sieve_result_execute(_testsuite_result, NULL);
104826
 
+       
104827
 
+       return ( ret > 0 );
104828
 
+}
104829
 
+
104830
 
+void testsuite_result_print
104831
 
+(const struct sieve_runtime_env *renv)
104832
 
+{
104833
 
+       struct ostream *out;
104834
 
+       
104835
 
+       out = o_stream_create_fd(1, 0, FALSE);  
104836
 
+
104837
 
+       o_stream_send_str(out, "\n--");
104838
 
+       sieve_result_print(_testsuite_result, renv->scriptenv, out, NULL);
104839
 
+       o_stream_send_str(out, "--\n\n");
104840
 
+
104841
 
+       o_stream_destroy(&out); 
104842
 
+}
104843
 
+
104844
 
+
104845
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/testsuite/testsuite-result.h dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/testsuite-result.h
104846
 
--- dovecot-1.2.4/dovecot-libsieve/src/testsuite/testsuite-result.h     1970-01-01 01:00:00.000000000 +0100
104847
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/testsuite-result.h      2009-02-11 21:38:58.000000000 +0100
104848
 
@@ -0,0 +1,22 @@
104849
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
104850
 
+ */
104851
 
+
104852
 
+#ifndef __TESTSUITE_RESULT_H
104853
 
+#define __TESTSUITE_RESULT_H
104854
 
+
104855
 
+void testsuite_result_init(void);
104856
 
+void testsuite_result_deinit(void);
104857
 
+
104858
 
+void testsuite_result_reset    
104859
 
+       (const struct sieve_runtime_env *renv);
104860
 
+
104861
 
+struct sieve_result *testsuite_result_get(void);
104862
 
+
104863
 
+struct sieve_result_iterate_context *testsuite_result_iterate_init(void);
104864
 
+
104865
 
+bool testsuite_result_execute(const struct sieve_runtime_env *renv);
104866
 
+
104867
 
+void testsuite_result_print
104868
 
+       (const struct sieve_runtime_env *renv ATTR_UNUSED);
104869
 
+
104870
 
+#endif /* __TESTSUITE_RESULT_H */
104871
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/testsuite/testsuite-script.c dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/testsuite-script.c
104872
 
--- dovecot-1.2.4/dovecot-libsieve/src/testsuite/testsuite-script.c     1970-01-01 01:00:00.000000000 +0100
104873
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/testsuite-script.c      2009-08-21 01:23:03.000000000 +0200
104874
 
@@ -0,0 +1,127 @@
104875
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
104876
 
+ */
104877
 
+
104878
 
+#include "lib.h"
104879
 
+#include "env-util.h"
104880
 
+
104881
 
+#include "sieve.h"
104882
 
+#include "sieve-common.h"
104883
 
+#include "sieve-script.h"
104884
 
+#include "sieve-binary.h"
104885
 
+#include "sieve-interpreter.h"
104886
 
+#include "sieve-result.h"
104887
 
+
104888
 
+#include "testsuite-common.h"
104889
 
+#include "testsuite-log.h"
104890
 
+#include "testsuite-result.h"
104891
 
+
104892
 
+#include "testsuite-script.h"
104893
 
+
104894
 
+/*
104895
 
+ * Tested script environment
104896
 
+ */ 
104897
 
+
104898
 
+struct sieve_binary *_testsuite_compiled_script;
104899
 
+
104900
 
+void testsuite_script_init(void)
104901
 
+{
104902
 
+       _testsuite_compiled_script = NULL;
104903
 
+}
104904
 
+
104905
 
+void testsuite_script_deinit(void)
104906
 
+{
104907
 
+       if ( _testsuite_compiled_script != NULL ) {
104908
 
+               sieve_binary_unref(&_testsuite_compiled_script);
104909
 
+       }
104910
 
+}
104911
 
+
104912
 
+bool testsuite_script_compile(const char *script_path)
104913
 
+{
104914
 
+       struct sieve_binary *sbin;
104915
 
+       const char *sieve_dir;
104916
 
+
104917
 
+       testsuite_log_clear_messages();
104918
 
+
104919
 
+       /* Initialize environment */
104920
 
+       sieve_dir = strrchr(script_path, '/');
104921
 
+       if ( sieve_dir == NULL )
104922
 
+               sieve_dir= "./";
104923
 
+       else
104924
 
+               sieve_dir = t_strdup_until(script_path, sieve_dir+1);
104925
 
+
104926
 
+       /* Currently needed for include (FIXME) */
104927
 
+       env_put(t_strconcat("SIEVE_DIR=", sieve_dir, "included", NULL));
104928
 
+       env_put(t_strconcat("SIEVE_GLOBAL_DIR=", sieve_dir, "included-global", NULL));
104929
 
+       
104930
 
+
104931
 
+       if ( (sbin = sieve_compile(script_path, NULL, testsuite_log_ehandler)) == NULL )
104932
 
+               return FALSE;
104933
 
+
104934
 
+       if ( _testsuite_compiled_script != NULL ) {
104935
 
+               sieve_binary_unref(&_testsuite_compiled_script);
104936
 
+       }
104937
 
+
104938
 
+       _testsuite_compiled_script = sbin;
104939
 
+
104940
 
+       return TRUE;
104941
 
+}
104942
 
+
104943
 
+bool testsuite_script_run(const struct sieve_runtime_env *renv)
104944
 
+{
104945
 
+       struct sieve_script_env scriptenv;
104946
 
+       struct sieve_result *result;
104947
 
+       struct sieve_interpreter *interp;
104948
 
+       int ret;
104949
 
+
104950
 
+       if ( _testsuite_compiled_script == NULL ) {
104951
 
+               sieve_runtime_error(renv, sieve_error_script_location(renv->script,0),
104952
 
+                       "testsuite: no script compiled yet");
104953
 
+               return FALSE;
104954
 
+       }
104955
 
+
104956
 
+       testsuite_log_clear_messages();
104957
 
+
104958
 
+       /* Compose script execution environment */
104959
 
+       memset(&scriptenv, 0, sizeof(scriptenv));
104960
 
+       scriptenv.default_mailbox = "INBOX";
104961
 
+       scriptenv.namespaces = NULL;
104962
 
+       scriptenv.username = "user";
104963
 
+       scriptenv.hostname = "host.example.com";
104964
 
+       scriptenv.postmaster_address = "postmaster@example.com";
104965
 
+       scriptenv.smtp_open = NULL;
104966
 
+       scriptenv.smtp_close = NULL;
104967
 
+       scriptenv.duplicate_mark = NULL;
104968
 
+       scriptenv.duplicate_check = NULL;
104969
 
+       
104970
 
+       result = testsuite_result_get();
104971
 
+
104972
 
+       /* Execute the script */
104973
 
+       interp=sieve_interpreter_create
104974
 
+               (_testsuite_compiled_script, testsuite_log_ehandler);
104975
 
+       
104976
 
+       if ( interp == NULL )
104977
 
+               return SIEVE_EXEC_BIN_CORRUPT;
104978
 
+               
104979
 
+       ret = sieve_interpreter_run
104980
 
+               (interp, renv->msgdata, &scriptenv, result);
104981
 
+
104982
 
+       sieve_interpreter_free(&interp);
104983
 
+
104984
 
+       return ( ret > 0 );
104985
 
+}
104986
 
+
104987
 
+struct sieve_binary *testsuite_script_get_binary(void)
104988
 
+{
104989
 
+       return _testsuite_compiled_script;
104990
 
+}
104991
 
+
104992
 
+void testsuite_script_set_binary(struct sieve_binary *sbin)
104993
 
+{
104994
 
+       if ( _testsuite_compiled_script != NULL ) {
104995
 
+               sieve_binary_unref(&_testsuite_compiled_script);
104996
 
+       }
104997
 
+
104998
 
+       _testsuite_compiled_script = sbin;
104999
 
+       sieve_binary_ref(sbin);
105000
 
+}
105001
 
+
105002
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/testsuite/testsuite-script.h dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/testsuite-script.h
105003
 
--- dovecot-1.2.4/dovecot-libsieve/src/testsuite/testsuite-script.h     1970-01-01 01:00:00.000000000 +0100
105004
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/testsuite-script.h      2009-08-21 00:52:15.000000000 +0200
105005
 
@@ -0,0 +1,18 @@
105006
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
105007
 
+ */
105008
 
+
105009
 
+#ifndef __TESTSUITE_SCRIPT_H
105010
 
+#define __TESTSUITE_SCRIPT_H
105011
 
+
105012
 
+#include "sieve-common.h"
105013
 
+
105014
 
+void testsuite_script_init(void);
105015
 
+void testsuite_script_deinit(void);
105016
 
+
105017
 
+bool testsuite_script_compile(const char *script_path);
105018
 
+bool testsuite_script_run(const struct sieve_runtime_env *renv);
105019
 
+
105020
 
+struct sieve_binary *testsuite_script_get_binary(void);
105021
 
+void testsuite_script_set_binary(struct sieve_binary *sbin);
105022
 
+
105023
 
+#endif /* __TESTSUITE_SCRIPT_H */
105024
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/testsuite/testsuite-smtp.c dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/testsuite-smtp.c
105025
 
--- dovecot-1.2.4/dovecot-libsieve/src/testsuite/testsuite-smtp.c       1970-01-01 01:00:00.000000000 +0100
105026
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/testsuite-smtp.c        2009-07-21 00:49:18.000000000 +0200
105027
 
@@ -0,0 +1,129 @@
105028
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
105029
 
+ */
105030
 
+
105031
 
+#include "lib.h"
105032
 
+#include "array.h"
105033
 
+#include "unlink-directory.h"
105034
 
+
105035
 
+#include "sieve-common.h" 
105036
 
+#include "sieve-error.h"
105037
 
+#include "sieve-interpreter.h"
105038
 
105039
 
+#include "testsuite-message.h"
105040
 
+#include "testsuite-common.h"
105041
 
+#include "testsuite-smtp.h"
105042
 
+
105043
 
+#include <sys/stat.h>
105044
 
+#include <sys/types.h>
105045
 
+
105046
 
+struct testsuite_smtp_message {
105047
 
+       const char *envelope_from;
105048
 
+       const char *envelope_to;
105049
 
+       const char *file;
105050
 
+};
105051
 
+
105052
 
+static pool_t testsuite_smtp_pool;
105053
 
+static const char *testsuite_smtp_tmp;
105054
 
+static ARRAY_DEFINE(testsuite_smtp_messages, struct testsuite_smtp_message);
105055
 
+
105056
 
+/*
105057
 
+ * Initialize
105058
 
+ */
105059
 
+
105060
 
+void testsuite_smtp_init(void)
105061
 
+{
105062
 
+       pool_t pool;
105063
 
+       
105064
 
+       testsuite_smtp_pool = pool = pool_alloconly_create("testsuite_smtp", 8192);     
105065
 
+       
105066
 
+       testsuite_smtp_tmp = p_strconcat
105067
 
+               (pool, testsuite_tmp_dir_get(), "/smtp", NULL);
105068
 
+
105069
 
+       if ( mkdir(testsuite_smtp_tmp, 0700) < 0 ) {
105070
 
+               i_fatal("failed to create temporary directory '%s': %m.", 
105071
 
+                       testsuite_smtp_tmp);            
105072
 
+       }
105073
 
+       
105074
 
+       p_array_init(&testsuite_smtp_messages, pool, 16);
105075
 
+}
105076
 
+
105077
 
+void testsuite_smtp_deinit(void)
105078
 
+{
105079
 
+       if ( unlink_directory(testsuite_smtp_tmp, TRUE) < 0 )
105080
 
+               i_warning("failed to remove temporary directory '%s': %m.",
105081
 
+                       testsuite_smtp_tmp);
105082
 
+       
105083
 
+       pool_unref(&testsuite_smtp_pool);               
105084
 
+}
105085
 
+
105086
 
+void testsuite_smtp_reset(void)
105087
 
+{
105088
 
+       testsuite_smtp_deinit();
105089
 
+       testsuite_smtp_init();
105090
 
+}
105091
 
+
105092
 
+/*
105093
 
+ * Simulated SMTP out
105094
 
+ */
105095
 
105096
 
+struct testsuite_smtp {
105097
 
+       const char *tmp_path;
105098
 
+       FILE *mfile;
105099
 
+};
105100
 
105101
 
+void *testsuite_smtp_open
105102
 
+       (const char *destination, const char *return_path, FILE **file_r)
105103
 
+{      
105104
 
+       struct testsuite_smtp_message smtp_msg;
105105
 
+       struct testsuite_smtp *smtp;
105106
 
+       unsigned int smtp_count = array_count(&testsuite_smtp_messages);
105107
 
+       
105108
 
+       smtp_msg.file = p_strdup_printf(testsuite_smtp_pool, 
105109
 
+               "%s/%d.eml", testsuite_smtp_tmp, smtp_count);
105110
 
+       smtp_msg.envelope_from = 
105111
 
+               ( return_path != NULL ? p_strdup(testsuite_smtp_pool, return_path) : NULL );
105112
 
+       smtp_msg.envelope_to = p_strdup(testsuite_smtp_pool, destination);
105113
 
+        
105114
 
+       array_append(&testsuite_smtp_messages, &smtp_msg, 1);
105115
 
+       
105116
 
+       smtp = t_new(struct testsuite_smtp, 1);
105117
 
+       smtp->tmp_path = smtp_msg.file;
105118
 
+       smtp->mfile = fopen(smtp->tmp_path, "w");
105119
 
+
105120
 
+       if ( smtp->mfile == NULL )
105121
 
+               i_fatal("failed to open tmp file for SMTP simulation.");
105122
 
+
105123
 
+       *file_r = smtp->mfile;
105124
 
+       
105125
 
+       return (void *) smtp;   
105126
 
+}
105127
 
+
105128
 
+bool testsuite_smtp_close(void *handle)
105129
 
+{
105130
 
+       struct testsuite_smtp *smtp = (struct testsuite_smtp *) handle;
105131
 
+
105132
 
+       fclose(smtp->mfile);
105133
 
+       
105134
 
+       return TRUE;
105135
 
+}
105136
 
+
105137
 
+/*
105138
 
+ * Access
105139
 
+ */
105140
 
+
105141
 
+bool testsuite_smtp_get
105142
 
+(const struct sieve_runtime_env *renv, unsigned int index)
105143
 
+{
105144
 
+       const struct testsuite_smtp_message *smtp_msg;
105145
 
+
105146
 
+       if ( index >= array_count(&testsuite_smtp_messages) )
105147
 
+               return FALSE;
105148
 
+
105149
 
+       smtp_msg = array_idx(&testsuite_smtp_messages, index);
105150
 
+
105151
 
+       testsuite_message_set_file(renv, smtp_msg->file);
105152
 
+       testsuite_envelope_set_sender(renv, smtp_msg->envelope_from);
105153
 
+       testsuite_envelope_set_recipient(renv, smtp_msg->envelope_to);
105154
 
+
105155
 
+       return TRUE;
105156
 
+}
105157
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/testsuite/testsuite-smtp.h dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/testsuite-smtp.h
105158
 
--- dovecot-1.2.4/dovecot-libsieve/src/testsuite/testsuite-smtp.h       1970-01-01 01:00:00.000000000 +0100
105159
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/testsuite-smtp.h        2009-02-14 09:54:17.000000000 +0100
105160
 
@@ -0,0 +1,26 @@
105161
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
105162
 
+ */
105163
 
105164
 
+#ifndef __TESTSUITE_SMTP_H
105165
 
+#define __TESTSUITE_SMTP_H
105166
 
105167
 
+void testsuite_smtp_init(void);
105168
 
+void testsuite_smtp_deinit(void);
105169
 
+void testsuite_smtp_reset(void);
105170
 
+
105171
 
+/*
105172
 
+ * Simulated SMTP out
105173
 
+ */
105174
 
105175
 
+void *testsuite_smtp_open
105176
 
+       (const char *destination, const char *return_path, FILE **file_r);
105177
 
+bool testsuite_smtp_close(void *handle);
105178
 
+
105179
 
+/*
105180
 
+ * Access
105181
 
+ */
105182
 
+
105183
 
+bool testsuite_smtp_get
105184
 
+       (const struct sieve_runtime_env *renv, unsigned int index);
105185
 
+
105186
 
+#endif /* __TESTSUITE_SMTP_H */
105187
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/testsuite/testsuite-substitutions.c dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/testsuite-substitutions.c
105188
 
--- dovecot-1.2.4/dovecot-libsieve/src/testsuite/testsuite-substitutions.c      1970-01-01 01:00:00.000000000 +0100
105189
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/testsuite-substitutions.c       2009-01-06 00:15:52.000000000 +0100
105190
 
@@ -0,0 +1,277 @@
105191
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
105192
 
+ */
105193
 
+
105194
 
+#include "lib.h"
105195
 
+
105196
 
+#include "sieve.h"
105197
 
+#include "sieve-code.h"
105198
 
+#include "sieve-commands.h"
105199
 
+#include "sieve-binary.h"
105200
 
+#include "sieve-generator.h"
105201
 
+#include "sieve-interpreter.h"
105202
 
+#include "sieve-dump.h"
105203
 
+
105204
 
+#include "testsuite-common.h"
105205
 
+#include "testsuite-substitutions.h"
105206
 
+
105207
 
+/*
105208
 
+ * Forward declarations
105209
 
+ */
105210
 
105211
 
+void testsuite_opr_substitution_emit
105212
 
+       (struct sieve_binary *sbin, const struct testsuite_substitution *tsub,
105213
 
+               const char *param);
105214
 
+                       
105215
 
+/*
105216
 
+ * Testsuite substitutions
105217
 
+ */
105218
 
105219
 
+/* FIXME: make this extendible */
105220
 
+
105221
 
+enum {
105222
 
+       TESTSUITE_SUBSTITUTION_FILE,
105223
 
+       TESTSUITE_SUBSTITUTION_MAILBOX,
105224
 
+       TESTSUITE_SUBSTITUTION_SMTPOUT
105225
 
+};
105226
 
+
105227
 
+static const struct testsuite_substitution testsuite_file_substitution;
105228
 
+static const struct testsuite_substitution testsuite_mailbox_substitution;
105229
 
+static const struct testsuite_substitution testsuite_smtpout_substitution;
105230
 
+
105231
 
+static const struct testsuite_substitution *substitutions[] = {
105232
 
+       &testsuite_file_substitution,
105233
 
+       &testsuite_mailbox_substitution,
105234
 
+       &testsuite_smtpout_substitution
105235
 
+};
105236
 
+
105237
 
+static const unsigned int substitutions_count = N_ELEMENTS(substitutions);
105238
 
105239
 
+static inline const struct testsuite_substitution *testsuite_substitution_get
105240
 
+(unsigned int code)
105241
 
+{
105242
 
+       if ( code > substitutions_count )
105243
 
+               return NULL;
105244
 
+       
105245
 
+       return substitutions[code];
105246
 
+}
105247
 
+
105248
 
+const struct testsuite_substitution *testsuite_substitution_find
105249
 
+(const char *identifier)
105250
 
+{
105251
 
+       unsigned int i; 
105252
 
+       
105253
 
+       for ( i = 0; i < substitutions_count; i++ ) {
105254
 
+               if ( strcasecmp(substitutions[i]->object.identifier, identifier) == 0 )
105255
 
+                       return substitutions[i];
105256
 
+       }
105257
 
+       
105258
 
+       return NULL;
105259
 
+}
105260
 
+
105261
 
+/*
105262
 
+ * Substitution argument
105263
 
+ */
105264
 
105265
 
+static bool arg_testsuite_substitution_generate
105266
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, 
105267
 
+               struct sieve_command_context *context);
105268
 
+
105269
 
+struct _testsuite_substitution_context {
105270
 
+       const struct testsuite_substitution *tsub;
105271
 
+       const char *param;
105272
 
+};
105273
 
+
105274
 
+const struct sieve_argument testsuite_substitution_argument = { 
105275
 
+       "@testsuite-substitution", 
105276
 
+       NULL, NULL, NULL, NULL,
105277
 
+       arg_testsuite_substitution_generate 
105278
 
+};
105279
 
+
105280
 
+struct sieve_ast_argument *testsuite_substitution_argument_create
105281
 
+(struct sieve_validator *validator ATTR_UNUSED, struct sieve_ast *ast, 
105282
 
+       unsigned int source_line, const char *substitution, const char *param)
105283
 
+{
105284
 
+       const struct testsuite_substitution *tsub;
105285
 
+       struct _testsuite_substitution_context *tsctx;
105286
 
+       struct sieve_ast_argument *arg;
105287
 
+       pool_t pool;
105288
 
+       
105289
 
+       tsub = testsuite_substitution_find(substitution);
105290
 
+       if ( tsub == NULL ) 
105291
 
+               return NULL;
105292
 
+       
105293
 
+       arg = sieve_ast_argument_create(ast, source_line);
105294
 
+       arg->type = SAAT_STRING;
105295
 
+       arg->argument = &testsuite_substitution_argument;
105296
 
+
105297
 
+       pool = sieve_ast_pool(ast);
105298
 
+       tsctx = p_new(pool, struct _testsuite_substitution_context, 1);
105299
 
+       tsctx->tsub = tsub;
105300
 
+       tsctx->param = p_strdup(pool, param);
105301
 
+       arg->context = (void *) tsctx;
105302
 
+       
105303
 
+       return arg;
105304
 
+}
105305
 
+
105306
 
+static bool arg_testsuite_substitution_generate
105307
 
+(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, 
105308
 
+       struct sieve_command_context *context ATTR_UNUSED)
105309
 
+{
105310
 
+       struct _testsuite_substitution_context *tsctx =  
105311
 
+               (struct _testsuite_substitution_context *) arg->context;
105312
 
+       
105313
 
+       testsuite_opr_substitution_emit(cgenv->sbin, tsctx->tsub, tsctx->param);
105314
 
+
105315
 
+       return TRUE;
105316
 
+}
105317
 
+
105318
 
+/*
105319
 
+ * Substitution operand
105320
 
+ */
105321
 
+
105322
 
+static bool opr_substitution_dump
105323
 
+       (const struct sieve_dumptime_env *denv, sieve_size_t *address, 
105324
 
+               const char *field_name);
105325
 
+static bool opr_substitution_read_value
105326
 
+       (const struct sieve_runtime_env *renv, sieve_size_t *address, string_t **str);
105327
 
+       
105328
 
+const struct sieve_opr_string_interface testsuite_substitution_interface = { 
105329
 
+       opr_substitution_dump,
105330
 
+       opr_substitution_read_value
105331
 
+};
105332
 
+               
105333
 
+const struct sieve_operand testsuite_substitution_operand = { 
105334
 
+       "test-substitution", 
105335
 
+       &testsuite_extension, 
105336
 
+       TESTSUITE_OPERAND_SUBSTITUTION,
105337
 
+       &string_class,
105338
 
+       &testsuite_substitution_interface
105339
 
+};
105340
 
+
105341
 
+void testsuite_opr_substitution_emit
105342
 
+(struct sieve_binary *sbin, const struct testsuite_substitution *tsub,
105343
 
+       const char *param) 
105344
 
+{
105345
 
+       /* Default variable storage */
105346
 
+       (void) sieve_operand_emit_code(sbin, &testsuite_substitution_operand);
105347
 
+       (void) sieve_binary_emit_unsigned(sbin, tsub->object.code);
105348
 
+       (void) sieve_binary_emit_cstring(sbin, param);
105349
 
+}
105350
 
+
105351
 
+static bool opr_substitution_dump
105352
 
+(const struct sieve_dumptime_env *denv, sieve_size_t *address,
105353
 
+       const char *field_name) 
105354
 
+{
105355
 
+       unsigned int code = 0;
105356
 
+       const struct testsuite_substitution *tsub;
105357
 
+       string_t *param; 
105358
 
+
105359
 
+       if ( !sieve_binary_read_unsigned(denv->sbin, address, &code) )
105360
 
+               return FALSE;
105361
 
+               
105362
 
+       tsub = testsuite_substitution_get(code);
105363
 
+       if ( tsub == NULL )
105364
 
+               return FALSE;   
105365
 
+                       
105366
 
+       if ( !sieve_binary_read_string(denv->sbin, address, &param) )
105367
 
+               return FALSE;
105368
 
+       
105369
 
+       if ( field_name != NULL ) 
105370
 
+               sieve_code_dumpf(denv, "%s: TEST_SUBS %%{%s:%s}", 
105371
 
+                       field_name, tsub->object.identifier, str_c(param));
105372
 
+       else
105373
 
+               sieve_code_dumpf(denv, "TEST_SUBS %%{%s:%s}", 
105374
 
+                       tsub->object.identifier, str_c(param));
105375
 
+       return TRUE;
105376
 
+}
105377
 
+
105378
 
+static bool opr_substitution_read_value
105379
 
+(const struct sieve_runtime_env *renv, sieve_size_t *address, string_t **str)
105380
 
+{ 
105381
 
+       const struct testsuite_substitution *tsub;
105382
 
+       unsigned int code = 0;
105383
 
+       string_t *param;
105384
 
+       
105385
 
+       if ( !sieve_binary_read_unsigned(renv->sbin, address, &code) )
105386
 
+               return FALSE;
105387
 
+               
105388
 
+       tsub = testsuite_substitution_get(code);
105389
 
+       if ( tsub == NULL )
105390
 
+               return FALSE;   
105391
 
+
105392
 
+       /* Parameter str can be NULL if we are requested to only skip and not 
105393
 
+        * actually read the argument.
105394
 
+        */     
105395
 
+       if ( str == NULL ) 
105396
 
+               return sieve_binary_read_string(renv->sbin, address, NULL);
105397
 
+       
105398
 
+       if ( !sieve_binary_read_string(renv->sbin, address, &param) )
105399
 
+               return FALSE;
105400
 
+                               
105401
 
+       return tsub->get_value(str_c(param), str);
105402
 
+}
105403
 
+
105404
 
+/*
105405
 
+ * Testsuite substitution definitions
105406
 
+ */
105407
 
105408
 
+static bool testsuite_file_substitution_get_value
105409
 
+       (const char *param, string_t **result); 
105410
 
+static bool testsuite_mailbox_substitution_get_value
105411
 
+       (const char *param, string_t **result); 
105412
 
+static bool testsuite_smtpout_substitution_get_value
105413
 
+       (const char *param, string_t **result); 
105414
 
105415
 
+static const struct testsuite_substitution testsuite_file_substitution = {
105416
 
+       SIEVE_OBJECT(
105417
 
+               "file", 
105418
 
+               &testsuite_substitution_operand, 
105419
 
+               TESTSUITE_SUBSTITUTION_FILE
105420
 
+       ),
105421
 
+       testsuite_file_substitution_get_value
105422
 
+};
105423
 
+
105424
 
+static const struct testsuite_substitution testsuite_mailbox_substitution = {
105425
 
+       SIEVE_OBJECT(
105426
 
+               "mailbox", 
105427
 
+               &testsuite_substitution_operand, 
105428
 
+               TESTSUITE_SUBSTITUTION_MAILBOX
105429
 
+       ),
105430
 
+       testsuite_mailbox_substitution_get_value
105431
 
+};
105432
 
+
105433
 
+static const struct testsuite_substitution testsuite_smtpout_substitution = {
105434
 
+       SIEVE_OBJECT(
105435
 
+               "smtpout",
105436
 
+               &testsuite_substitution_operand,
105437
 
+               TESTSUITE_SUBSTITUTION_SMTPOUT
105438
 
+       ),
105439
 
+       testsuite_smtpout_substitution_get_value
105440
 
+};
105441
 
105442
 
+static bool testsuite_file_substitution_get_value
105443
 
+       (const char *param, string_t **result)
105444
 
+{
105445
 
+       *result = t_str_new(256);
105446
 
+
105447
 
+       str_printfa(*result, "[FILE: %s]", param);
105448
 
+       return TRUE;
105449
 
+}
105450
 
+
105451
 
+static bool testsuite_mailbox_substitution_get_value
105452
 
+       (const char *param, string_t **result)
105453
 
+{
105454
 
+       *result = t_str_new(256);
105455
 
+
105456
 
+       str_printfa(*result, "[MAILBOX: %s]", param);
105457
 
+       return TRUE;
105458
 
+}
105459
 
+
105460
 
+static bool testsuite_smtpout_substitution_get_value
105461
 
+       (const char *param, string_t **result) 
105462
 
+{
105463
 
+       *result = t_str_new(256);
105464
 
+
105465
 
+       str_printfa(*result, "[SMTPOUT: %s]", param);
105466
 
+       return TRUE;
105467
 
+} 
105468
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/testsuite/testsuite-substitutions.h dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/testsuite-substitutions.h
105469
 
--- dovecot-1.2.4/dovecot-libsieve/src/testsuite/testsuite-substitutions.h      1970-01-01 01:00:00.000000000 +0100
105470
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/testsuite-substitutions.h       2009-01-06 00:15:52.000000000 +0100
105471
 
@@ -0,0 +1,23 @@
105472
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
105473
 
+ */
105474
 
+
105475
 
+#ifndef __TESTSUITE_SUBSTITUTIONS_H
105476
 
+#define __TESTSUITE_SUBSTITUTIONS_H
105477
 
+
105478
 
+#include "sieve-common.h"
105479
 
+#include "sieve-objects.h"
105480
 
+
105481
 
+struct testsuite_substitution {
105482
 
+       struct sieve_object object;
105483
 
+       
105484
 
+       bool (*get_value)(const char *param, string_t **result);
105485
 
+};
105486
 
+
105487
 
+const struct testsuite_substitution *testsuite_substitution_find
105488
 
+       (const char *identifier);
105489
 
+
105490
 
+struct sieve_ast_argument *testsuite_substitution_argument_create
105491
 
+       (struct sieve_validator *validator, struct sieve_ast *ast, 
105492
 
+               unsigned int source_line, const char *substitution, const char *param);
105493
 
+
105494
 
+#endif /* __TESTSUITE_SUBSTITUTIONS_H */
105495
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/testsuite/tst-test-error.c dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/tst-test-error.c
105496
 
--- dovecot-1.2.4/dovecot-libsieve/src/testsuite/tst-test-error.c       1970-01-01 01:00:00.000000000 +0100
105497
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/tst-test-error.c        2009-07-30 00:46:26.000000000 +0200
105498
 
@@ -0,0 +1,309 @@
105499
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
105500
 
+ */
105501
 
+
105502
 
+#include "sieve-common.h"
105503
 
+#include "sieve-error.h"
105504
 
+#include "sieve-script.h"
105505
 
+#include "sieve-commands.h"
105506
 
+#include "sieve-comparators.h"
105507
 
+#include "sieve-match-types.h"
105508
 
+#include "sieve-validator.h"
105509
 
+#include "sieve-generator.h"
105510
 
+#include "sieve-interpreter.h"
105511
 
+#include "sieve-code.h"
105512
 
+#include "sieve-binary.h"
105513
 
+#include "sieve-dump.h"
105514
 
+#include "sieve-match.h"
105515
 
+
105516
 
+#include "testsuite-common.h"
105517
 
+#include "testsuite-log.h"
105518
 
+
105519
 
+/*
105520
 
+ * Test_error command
105521
 
+ *
105522
 
+ * Syntax:   
105523
 
+ *   test [MATCH-TYPE] [COMPARATOR] [:index number] <key-list: string-list>
105524
 
+ */
105525
 
+
105526
 
+static bool tst_test_error_registered
105527
 
+    (struct sieve_validator *validator, struct sieve_command_registration *cmd_reg);
105528
 
+static bool tst_test_error_validate
105529
 
+       (struct sieve_validator *validator, struct sieve_command_context *cmd);
105530
 
+static bool tst_test_error_generate
105531
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx);
105532
 
+
105533
 
+const struct sieve_command tst_test_error = { 
105534
 
+       "test_error", 
105535
 
+       SCT_TEST, 
105536
 
+       1, 0, FALSE, FALSE,
105537
 
+       tst_test_error_registered, 
105538
 
+       NULL,
105539
 
+       tst_test_error_validate, 
105540
 
+       tst_test_error_generate, 
105541
 
+       NULL 
105542
 
+};
105543
 
+
105544
 
+/* 
105545
 
+ * Operation 
105546
 
+ */
105547
 
+
105548
 
+static bool tst_test_error_operation_dump
105549
 
+       (const struct sieve_operation *op,
105550
 
+               const struct sieve_dumptime_env *denv, sieve_size_t *address);
105551
 
+static int tst_test_error_operation_execute
105552
 
+       (const struct sieve_operation *op, 
105553
 
+               const struct sieve_runtime_env *renv, sieve_size_t *address);
105554
 
+
105555
 
+const struct sieve_operation test_error_operation = { 
105556
 
+       "TEST_ERROR",
105557
 
+       &testsuite_extension, 
105558
 
+       TESTSUITE_OPERATION_TEST_ERROR,
105559
 
+       tst_test_error_operation_dump, 
105560
 
+       tst_test_error_operation_execute 
105561
 
+};
105562
 
+
105563
 
+/*
105564
 
+ * Tagged arguments
105565
 
+ */ 
105566
 
+
105567
 
+/* NOTE: This will be merged with the date-index extension when it is 
105568
 
+ * implemented.
105569
 
+ */
105570
 
+
105571
 
+static bool tst_test_error_validate_index_tag
105572
 
+       (struct sieve_validator *validator, struct sieve_ast_argument **arg,
105573
 
+               struct sieve_command_context *cmd);
105574
 
+
105575
 
+static const struct sieve_argument test_error_index_tag = {
105576
 
+       "index",
105577
 
+       NULL, NULL,
105578
 
+       tst_test_error_validate_index_tag,
105579
 
+       NULL, NULL
105580
 
+};
105581
 
+
105582
 
+enum tst_test_error_optional {
105583
 
+       OPT_INDEX = SIEVE_MATCH_OPT_LAST,
105584
 
+};
105585
 
+
105586
 
+
105587
 
+/*
105588
 
+ * Argument implementation
105589
 
+ */
105590
 
+
105591
 
+static bool tst_test_error_validate_index_tag
105592
 
+(struct sieve_validator *validator, struct sieve_ast_argument **arg,
105593
 
+       struct sieve_command_context *cmd)
105594
 
+{
105595
 
+       struct sieve_ast_argument *tag = *arg;
105596
 
+
105597
 
+       /* Detach the tag itself */
105598
 
+       *arg = sieve_ast_arguments_detach(*arg,1);
105599
 
+
105600
 
+       /* Check syntax:
105601
 
+        *   :index number
105602
 
+        */
105603
 
+       if ( !sieve_validate_tag_parameter
105604
 
+               (validator, cmd, tag, *arg, SAAT_NUMBER) ) {
105605
 
+               return FALSE;
105606
 
+       }
105607
 
+
105608
 
+       /* Skip parameter */
105609
 
+       *arg = sieve_ast_argument_next(*arg);
105610
 
+       return TRUE;
105611
 
+}
105612
 
+
105613
 
+
105614
 
+/*
105615
 
+ * Command registration
105616
 
+ */
105617
 
+
105618
 
+static bool tst_test_error_registered
105619
 
+(struct sieve_validator *validator, struct sieve_command_registration *cmd_reg)
105620
 
+{
105621
 
+       /* The order of these is not significant */
105622
 
+       sieve_comparators_link_tag(validator, cmd_reg, SIEVE_MATCH_OPT_COMPARATOR);
105623
 
+       sieve_match_types_link_tags(validator, cmd_reg, SIEVE_MATCH_OPT_MATCH_TYPE);
105624
 
+
105625
 
+       sieve_validator_register_tag
105626
 
+               (validator, cmd_reg, &test_error_index_tag, OPT_INDEX);
105627
 
+
105628
 
+       return TRUE;
105629
 
+}
105630
 
+
105631
 
+/* 
105632
 
+ * Validation 
105633
 
+ */
105634
 
+
105635
 
+static bool tst_test_error_validate
105636
 
+(struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_command_context *tst) 
105637
 
+{
105638
 
+       struct sieve_ast_argument *arg = tst->first_positional;
105639
 
+       
105640
 
+       if ( !sieve_validate_positional_argument
105641
 
+               (valdtr, tst, arg, "key list", 2, SAAT_STRING_LIST) ) {
105642
 
+               return FALSE;
105643
 
+       }
105644
 
+
105645
 
+       if ( !sieve_validator_argument_activate(valdtr, tst, arg, FALSE) )
105646
 
+               return FALSE;
105647
 
+
105648
 
+       /* Validate the key argument to a specified match type */
105649
 
+       return sieve_match_type_validate
105650
 
+               (valdtr, tst, arg, &is_match_type, &i_octet_comparator);
105651
 
+}
105652
 
+
105653
 
+/* 
105654
 
+ * Code generation 
105655
 
+ */
105656
 
+
105657
 
+static inline struct testsuite_generator_context *
105658
 
+_get_generator_context(struct sieve_generator *gentr)
105659
 
+{
105660
 
+       return (struct testsuite_generator_context *) 
105661
 
+               sieve_generator_extension_get_context(gentr, &testsuite_extension);
105662
 
+}
105663
 
+
105664
 
+static bool tst_test_error_generate
105665
 
+(const struct sieve_codegen_env *cgenv, struct sieve_command_context *tst)
105666
 
+{
105667
 
+       sieve_operation_emit_code(cgenv->sbin, &test_error_operation);
105668
 
+
105669
 
+       /* Generate arguments */
105670
 
+       return sieve_generate_arguments(cgenv, tst, NULL);
105671
 
+}
105672
 
+
105673
 
+/* 
105674
 
+ * Code dump
105675
 
+ */
105676
 
105677
 
+static bool tst_test_error_operation_dump
105678
 
+(const struct sieve_operation *op ATTR_UNUSED,
105679
 
+       const struct sieve_dumptime_env *denv, sieve_size_t *address)
105680
 
+{
105681
 
+       int opt_code = 0;
105682
 
+
105683
 
+       sieve_code_dumpf(denv, "TEST_ERROR:");
105684
 
+       sieve_code_descend(denv);
105685
 
+
105686
 
+       /* Handle any optional arguments */
105687
 
+       do {
105688
 
+               if ( !sieve_match_dump_optional_operands(denv, address, &opt_code) )
105689
 
+                       return FALSE;
105690
 
+
105691
 
+               switch ( opt_code ) {
105692
 
+               case SIEVE_MATCH_OPT_END:
105693
 
+                       break;
105694
 
+               case OPT_INDEX:
105695
 
+                       if ( !sieve_opr_number_dump(denv, address, "index") )
105696
 
+                               return FALSE;
105697
 
+                       break;
105698
 
+               default:
105699
 
+                       return FALSE;
105700
 
+               }
105701
 
+       } while ( opt_code != SIEVE_MATCH_OPT_END );
105702
 
+
105703
 
+       return sieve_opr_stringlist_dump(denv, address, "key list");
105704
 
+}
105705
 
+
105706
 
+/*
105707
 
+ * Intepretation
105708
 
+ */
105709
 
+
105710
 
+static int tst_test_error_operation_execute
105711
 
+(const struct sieve_operation *op ATTR_UNUSED,
105712
 
+       const struct sieve_runtime_env *renv, sieve_size_t *address)
105713
 
+{      
105714
 
+       int opt_code = 0;
105715
 
+       bool result = TRUE;
105716
 
+       const struct sieve_comparator *cmp = &i_octet_comparator;
105717
 
+       const struct sieve_match_type *mtch = &is_match_type;
105718
 
+       struct sieve_match_context *mctx;
105719
 
+       struct sieve_coded_stringlist *key_list;
105720
 
+       bool matched;
105721
 
+       const char *error;
105722
 
+       int cur_index = 0, index = 0;
105723
 
+       int ret;
105724
 
+
105725
 
+       /*
105726
 
+        * Read operands
105727
 
+        */
105728
 
+
105729
 
+       /* Handle optional operands */
105730
 
+       do {
105731
 
+               sieve_number_t number; 
105732
 
+
105733
 
+               if ( (ret=sieve_match_read_optional_operands
105734
 
+                       (renv, address, &opt_code, &cmp, &mtch)) <= 0 )
105735
 
+                       return ret;
105736
 
+
105737
 
+               switch ( opt_code ) {
105738
 
+               case SIEVE_MATCH_OPT_END:
105739
 
+                       break;
105740
 
+               case OPT_INDEX:
105741
 
+                       if ( !sieve_opr_number_read(renv, address, &number) ) {
105742
 
+                               sieve_runtime_trace_error(renv, "invalid index operand");
105743
 
+                               return SIEVE_EXEC_BIN_CORRUPT;
105744
 
+                       }
105745
 
+                       index = (int) number;
105746
 
+                       break;
105747
 
+               default:
105748
 
+                       sieve_runtime_trace_error(renv, "invalid optional operand");
105749
 
+                       return SIEVE_EXEC_BIN_CORRUPT;
105750
 
+               }       
105751
 
+       } while ( opt_code != SIEVE_MATCH_OPT_END);
105752
 
+
105753
 
+       /* Read key-list */
105754
 
+       if ( (key_list=sieve_opr_stringlist_read(renv, address)) == NULL ) {
105755
 
+               sieve_runtime_trace_error(renv, "invalid key-list operand");
105756
 
+               return SIEVE_EXEC_BIN_CORRUPT;
105757
 
+       }
105758
 
+
105759
 
+       /*
105760
 
+        * Perform operation
105761
 
+        */
105762
 
+       
105763
 
+       sieve_runtime_trace(renv, "TEST_ERROR test (index: %d)", index);
105764
 
+
105765
 
+       testsuite_log_get_error_init();
105766
 
+
105767
 
+       /* Initialize match */
105768
 
+       mctx = sieve_match_begin(renv->interp, mtch, cmp, NULL, key_list);
105769
 
+
105770
 
+       /* Iterate through all errors to match */
105771
 
+       error = NULL;
105772
 
+       matched = FALSE;
105773
 
+       cur_index = 1;
105774
 
+       ret = 0;
105775
 
+       while ( result && !matched &&
105776
 
+               (error=testsuite_log_get_error_next(FALSE)) != NULL ) {
105777
 
+               
105778
 
+               if ( index == 0 || index == cur_index ) {
105779
 
+                       if ( (ret=sieve_match_value(mctx, error, strlen(error))) < 0 ) {
105780
 
+                               result = FALSE;
105781
 
+                               break;
105782
 
+                       }
105783
 
+               }
105784
 
+
105785
 
+               matched = ret > 0;
105786
 
+               cur_index++;
105787
 
+       }
105788
 
+
105789
 
+       /* Finish match */
105790
 
+       if ( (ret=sieve_match_end(&mctx)) < 0 )
105791
 
+               result = FALSE;
105792
 
+       else
105793
 
+               matched = ( ret > 0 || matched );
105794
 
+
105795
 
+       /* Set test result for subsequent conditional jump */
105796
 
+       if ( result ) {
105797
 
+               sieve_interpreter_set_test_result(renv->interp, matched);
105798
 
+               return SIEVE_EXEC_OK;
105799
 
+       }
105800
 
+
105801
 
+       sieve_runtime_trace_error(renv, "invalid string-list item");
105802
 
+       return SIEVE_EXEC_BIN_CORRUPT;
105803
 
+}
105804
 
+
105805
 
+
105806
 
+
105807
 
+
105808
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/testsuite/tst-test-result.c dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/tst-test-result.c
105809
 
--- dovecot-1.2.4/dovecot-libsieve/src/testsuite/tst-test-result.c      1970-01-01 01:00:00.000000000 +0100
105810
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/tst-test-result.c       2009-07-30 00:46:15.000000000 +0200
105811
 
@@ -0,0 +1,325 @@
105812
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
105813
 
+ */
105814
 
+
105815
 
+/* FIXME: this file is very similar to tst-test-error.c. Maybe it is best to 
105816
 
+ * implement errors and actions as testsuite-objects and implement a common
105817
 
+ * interface to test these.
105818
 
+ */
105819
 
+
105820
 
+#include "sieve-common.h"
105821
 
+#include "sieve-error.h"
105822
 
+#include "sieve-script.h"
105823
 
+#include "sieve-commands.h"
105824
 
+#include "sieve-actions.h"
105825
 
+#include "sieve-comparators.h"
105826
 
+#include "sieve-match-types.h"
105827
 
+#include "sieve-validator.h"
105828
 
+#include "sieve-generator.h"
105829
 
+#include "sieve-interpreter.h"
105830
 
+#include "sieve-code.h"
105831
 
+#include "sieve-binary.h"
105832
 
+#include "sieve-result.h"
105833
 
+#include "sieve-dump.h"
105834
 
+#include "sieve-match.h"
105835
 
+
105836
 
+#include "testsuite-common.h"
105837
 
+#include "testsuite-result.h"
105838
 
+
105839
 
+/*
105840
 
+ * test_result command
105841
 
+ *
105842
 
+ * Syntax:   
105843
 
+ *   test_result [MATCH-TYPE] [COMPARATOR] [:index number] 
105844
 
+ *     <key-list: string-list>
105845
 
+ */
105846
 
+
105847
 
+static bool tst_test_result_registered
105848
 
+    (struct sieve_validator *validator, struct sieve_command_registration *cmd_reg);
105849
 
+static bool tst_test_result_validate
105850
 
+       (struct sieve_validator *validator, struct sieve_command_context *cmd);
105851
 
+static bool tst_test_result_generate
105852
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx);
105853
 
+
105854
 
+const struct sieve_command tst_test_result = { 
105855
 
+       "test_result", 
105856
 
+       SCT_TEST, 
105857
 
+       1, 0, FALSE, FALSE,
105858
 
+       tst_test_result_registered, 
105859
 
+       NULL,
105860
 
+       tst_test_result_validate, 
105861
 
+       tst_test_result_generate, 
105862
 
+       NULL 
105863
 
+};
105864
 
+
105865
 
+/* 
105866
 
+ * Operation 
105867
 
+ */
105868
 
+
105869
 
+static bool tst_test_result_operation_dump
105870
 
+       (const struct sieve_operation *op,
105871
 
+               const struct sieve_dumptime_env *denv, sieve_size_t *address);
105872
 
+static int tst_test_result_operation_execute
105873
 
+       (const struct sieve_operation *op, 
105874
 
+               const struct sieve_runtime_env *renv, sieve_size_t *address);
105875
 
+
105876
 
+const struct sieve_operation test_result_operation = { 
105877
 
+       "test_result",
105878
 
+       &testsuite_extension, 
105879
 
+       TESTSUITE_OPERATION_TEST_RESULT,
105880
 
+       tst_test_result_operation_dump, 
105881
 
+       tst_test_result_operation_execute 
105882
 
+};
105883
 
+
105884
 
+/*
105885
 
+ * Tagged arguments
105886
 
+ */ 
105887
 
+
105888
 
+/* NOTE: This will be merged with the date-index extension when it is 
105889
 
+ * implemented.
105890
 
+ */
105891
 
+
105892
 
+/* FIXME: at least merge this with the test_error version of this tag */
105893
 
+
105894
 
+static bool tst_test_result_validate_index_tag
105895
 
+       (struct sieve_validator *validator, struct sieve_ast_argument **arg,
105896
 
+               struct sieve_command_context *cmd);
105897
 
+
105898
 
+static const struct sieve_argument test_result_index_tag = {
105899
 
+    "index",
105900
 
+    NULL, NULL,
105901
 
+    tst_test_result_validate_index_tag,
105902
 
+    NULL, NULL
105903
 
+};
105904
 
+
105905
 
+enum tst_test_result_optional {
105906
 
+       OPT_INDEX = SIEVE_MATCH_OPT_LAST,
105907
 
+};
105908
 
+
105909
 
+/*
105910
 
+ * Argument implementation
105911
 
+ */
105912
 
+
105913
 
+static bool tst_test_result_validate_index_tag
105914
 
+(struct sieve_validator *validator, struct sieve_ast_argument **arg,
105915
 
+       struct sieve_command_context *cmd)
105916
 
+{
105917
 
+       struct sieve_ast_argument *tag = *arg;
105918
 
+
105919
 
+       /* Detach the tag itself */
105920
 
+       *arg = sieve_ast_arguments_detach(*arg,1);
105921
 
+
105922
 
+       /* Check syntax:
105923
 
+        *   :index number
105924
 
+        */
105925
 
+       if ( !sieve_validate_tag_parameter
105926
 
+               (validator, cmd, tag, *arg, SAAT_NUMBER) ) {
105927
 
+               return FALSE;
105928
 
+       }
105929
 
+
105930
 
+       /* Skip parameter */
105931
 
+       *arg = sieve_ast_argument_next(*arg);
105932
 
+       return TRUE;
105933
 
+}
105934
 
+
105935
 
+
105936
 
+/*
105937
 
+ * Command registration
105938
 
+ */
105939
 
+
105940
 
+static bool tst_test_result_registered
105941
 
+(struct sieve_validator *validator, struct sieve_command_registration *cmd_reg)
105942
 
+{
105943
 
+       /* The order of these is not significant */
105944
 
+       sieve_comparators_link_tag(validator, cmd_reg, SIEVE_MATCH_OPT_COMPARATOR);
105945
 
+       sieve_match_types_link_tags(validator, cmd_reg, SIEVE_MATCH_OPT_MATCH_TYPE);
105946
 
+
105947
 
+       sieve_validator_register_tag
105948
 
+               (validator, cmd_reg, &test_result_index_tag, OPT_INDEX);
105949
 
+
105950
 
+       return TRUE;
105951
 
+}
105952
 
+
105953
 
+/* 
105954
 
+ * Validation 
105955
 
+ */
105956
 
+
105957
 
+static bool tst_test_result_validate
105958
 
+(struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_command_context *tst) 
105959
 
+{
105960
 
+       struct sieve_ast_argument *arg = tst->first_positional;
105961
 
+       
105962
 
+       if ( !sieve_validate_positional_argument
105963
 
+               (valdtr, tst, arg, "key list", 2, SAAT_STRING_LIST) ) {
105964
 
+               return FALSE;
105965
 
+       }
105966
 
+
105967
 
+       if ( !sieve_validator_argument_activate(valdtr, tst, arg, FALSE) )
105968
 
+               return FALSE;
105969
 
+
105970
 
+       /* Validate the key argument to a specified match type */
105971
 
+       return sieve_match_type_validate
105972
 
+               (valdtr, tst, arg, &is_match_type, &i_octet_comparator);
105973
 
+}
105974
 
+
105975
 
+/* 
105976
 
+ * Code generation 
105977
 
+ */
105978
 
+
105979
 
+static inline struct testsuite_generator_context *
105980
 
+_get_generator_context(struct sieve_generator *gentr)
105981
 
+{
105982
 
+       return (struct testsuite_generator_context *) 
105983
 
+               sieve_generator_extension_get_context(gentr, &testsuite_extension);
105984
 
+}
105985
 
+
105986
 
+static bool tst_test_result_generate
105987
 
+(const struct sieve_codegen_env *cgenv, struct sieve_command_context *tst)
105988
 
+{
105989
 
+       sieve_operation_emit_code(cgenv->sbin, &test_result_operation);
105990
 
+
105991
 
+       /* Generate arguments */
105992
 
+       return sieve_generate_arguments(cgenv, tst, NULL);
105993
 
+}
105994
 
+
105995
 
+/* 
105996
 
+ * Code dump
105997
 
+ */
105998
 
105999
 
+static bool tst_test_result_operation_dump
106000
 
+(const struct sieve_operation *op ATTR_UNUSED,
106001
 
+       const struct sieve_dumptime_env *denv, sieve_size_t *address)
106002
 
+{
106003
 
+       int opt_code = 0;
106004
 
+
106005
 
+       sieve_code_dumpf(denv, "TEST_RESULT:");
106006
 
+       sieve_code_descend(denv);
106007
 
+
106008
 
+       /* Handle any optional arguments */
106009
 
+       do {
106010
 
+               if ( !sieve_match_dump_optional_operands(denv, address, &opt_code) )
106011
 
+                       return FALSE;
106012
 
+
106013
 
+               switch ( opt_code ) {
106014
 
+               case SIEVE_MATCH_OPT_END:
106015
 
+                       break;
106016
 
+               case OPT_INDEX:
106017
 
+                       if ( !sieve_opr_number_dump(denv, address, "index") )
106018
 
+                               return FALSE;
106019
 
+                       break;
106020
 
+               default:
106021
 
+                       return FALSE;
106022
 
+               }
106023
 
+       } while ( opt_code != SIEVE_MATCH_OPT_END );
106024
 
+
106025
 
+       return sieve_opr_stringlist_dump(denv, address, "key list");
106026
 
+}
106027
 
+
106028
 
+/*
106029
 
+ * Intepretation
106030
 
+ */
106031
 
+
106032
 
+static int tst_test_result_operation_execute
106033
 
+(const struct sieve_operation *op ATTR_UNUSED,
106034
 
+       const struct sieve_runtime_env *renv, sieve_size_t *address)
106035
 
+{      
106036
 
+       int opt_code = 0;
106037
 
+       bool result = TRUE;
106038
 
+       const struct sieve_comparator *cmp = &i_octet_comparator;
106039
 
+       const struct sieve_match_type *mtch = &is_match_type;
106040
 
+       struct sieve_match_context *mctx;
106041
 
+       struct sieve_coded_stringlist *key_list;
106042
 
+       bool matched;
106043
 
+       struct sieve_result_iterate_context *rictx;
106044
 
+       const struct sieve_action *action;
106045
 
+       bool keep;
106046
 
+       int cur_index = 0, index = 0;
106047
 
+       int ret;
106048
 
+
106049
 
+       /*
106050
 
+        * Read operands
106051
 
+        */
106052
 
+
106053
 
+       /* Handle optional operands */
106054
 
+       do {
106055
 
+               sieve_number_t number; 
106056
 
+
106057
 
+               if ( (ret=sieve_match_read_optional_operands
106058
 
+                       (renv, address, &opt_code, &cmp, &mtch)) <= 0 )
106059
 
+                       return ret;
106060
 
+
106061
 
+               switch ( opt_code ) {
106062
 
+               case SIEVE_MATCH_OPT_END:
106063
 
+                       break;
106064
 
+               case OPT_INDEX:
106065
 
+                       if ( !sieve_opr_number_read(renv, address, &number) ) {
106066
 
+                               sieve_runtime_trace_error(renv, "invalid index operand");
106067
 
+                               return SIEVE_EXEC_BIN_CORRUPT;
106068
 
+                       }
106069
 
+                       index = (int) number;
106070
 
+                       break;
106071
 
+               default:
106072
 
+                       sieve_runtime_trace_error(renv, "invalid optional operand");
106073
 
+                       return SIEVE_EXEC_BIN_CORRUPT;
106074
 
+               }       
106075
 
+       } while ( opt_code != SIEVE_MATCH_OPT_END);
106076
 
+
106077
 
+       /* Read key-list */
106078
 
+       if ( (key_list=sieve_opr_stringlist_read(renv, address)) == NULL ) {
106079
 
+               sieve_runtime_trace_error(renv, "invalid key-list operand");
106080
 
+               return SIEVE_EXEC_BIN_CORRUPT;
106081
 
+       }
106082
 
+
106083
 
+       /*
106084
 
+        * Perform operation
106085
 
+        */
106086
 
+       
106087
 
+       sieve_runtime_trace(renv, "TEST_RESULT test (index: %d)", index);
106088
 
+
106089
 
+       rictx = testsuite_result_iterate_init();
106090
 
+
106091
 
+  /* Initialize match */
106092
 
+  mctx = sieve_match_begin(renv->interp, mtch, cmp, NULL, key_list);
106093
 
+
106094
 
+  /* Iterate through all errors to match */
106095
 
+       matched = FALSE;
106096
 
+       cur_index = 1;
106097
 
+       ret = 0;
106098
 
+       while ( result && !matched &&
106099
 
+               (action=sieve_result_iterate_next(rictx, &keep, NULL)) != NULL ) {
106100
 
+               const char *act_name;
106101
 
+               
106102
 
+               if ( keep ) 
106103
 
+                       act_name = "keep";
106104
 
+               else
106105
 
+                       act_name = ( action == NULL || action->name == NULL ) ? "" : action->name;
106106
 
+
106107
 
+               if ( index == 0 || index == cur_index ) {
106108
 
+                       if ( (ret=sieve_match_value(mctx, act_name, strlen(act_name))) < 0 ) {
106109
 
+                               result = FALSE;
106110
 
+                               break;
106111
 
+                       }
106112
 
+               }
106113
 
+
106114
 
+               matched = ret > 0;
106115
 
+               cur_index++;
106116
 
+       }
106117
 
+
106118
 
+       /* Finish match */
106119
 
+       if ( (ret=sieve_match_end(&mctx)) < 0 )
106120
 
+               result = FALSE;
106121
 
+       else
106122
 
+               matched = ( ret > 0 || matched );
106123
 
+
106124
 
+       /* Set test result for subsequent conditional jump */
106125
 
+       if ( result ) {
106126
 
+               sieve_interpreter_set_test_result(renv->interp, matched);
106127
 
+               return SIEVE_EXEC_OK;
106128
 
+       }
106129
 
+
106130
 
+       sieve_runtime_trace_error(renv, "invalid string-list item");
106131
 
+       return SIEVE_EXEC_BIN_CORRUPT;
106132
 
+}
106133
 
+
106134
 
+
106135
 
+
106136
 
+
106137
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/testsuite/tst-test-result-execute.c dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/tst-test-result-execute.c
106138
 
--- dovecot-1.2.4/dovecot-libsieve/src/testsuite/tst-test-result-execute.c      1970-01-01 01:00:00.000000000 +0100
106139
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/tst-test-result-execute.c       2009-02-11 21:38:58.000000000 +0100
106140
 
@@ -0,0 +1,93 @@
106141
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
106142
 
+ */
106143
 
+
106144
 
+#include "sieve-common.h"
106145
 
+#include "sieve-script.h"
106146
 
+#include "sieve-commands.h"
106147
 
+#include "sieve-validator.h"
106148
 
+#include "sieve-generator.h"
106149
 
+#include "sieve-interpreter.h"
106150
 
+#include "sieve-code.h"
106151
 
+#include "sieve-binary.h"
106152
 
+#include "sieve-dump.h"
106153
 
+#include "sieve.h"
106154
 
+
106155
 
+#include "testsuite-common.h"
106156
 
+#include "testsuite-result.h"
106157
 
+
106158
 
+/*
106159
 
+ * Test_result_execute command
106160
 
+ *
106161
 
+ * Syntax:   
106162
 
+ *   test_result_execute
106163
 
+ */
106164
 
+
106165
 
+static bool tst_test_result_execute_generate
106166
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx);
106167
 
+
106168
 
+const struct sieve_command tst_test_result_execute = { 
106169
 
+       "test_result_execute", 
106170
 
+       SCT_TEST, 
106171
 
+       0, 0, FALSE, FALSE,
106172
 
+       NULL, NULL, NULL,
106173
 
+       tst_test_result_execute_generate, 
106174
 
+       NULL 
106175
 
+};
106176
 
+
106177
 
+/* 
106178
 
+ * Operation 
106179
 
+ */
106180
 
+
106181
 
+static int tst_test_result_execute_operation_execute
106182
 
+       (const struct sieve_operation *op, 
106183
 
+               const struct sieve_runtime_env *renv, sieve_size_t *address);
106184
 
+
106185
 
+const struct sieve_operation test_result_execute_operation = { 
106186
 
+       "TEST_RESULT_EXECUTE",
106187
 
+       &testsuite_extension, 
106188
 
+       TESTSUITE_OPERATION_TEST_RESULT_EXECUTE,
106189
 
+       NULL, 
106190
 
+       tst_test_result_execute_operation_execute 
106191
 
+};
106192
 
+
106193
 
+/* 
106194
 
+ * Code generation 
106195
 
+ */
106196
 
+
106197
 
+static bool tst_test_result_execute_generate
106198
 
+(const struct sieve_codegen_env *cgenv, 
106199
 
+       struct sieve_command_context *tst ATTR_UNUSED)
106200
 
+{
106201
 
+       sieve_operation_emit_code(cgenv->sbin, &test_result_execute_operation);
106202
 
+
106203
 
+       return TRUE;
106204
 
+}
106205
 
+
106206
 
+/*
106207
 
+ * Intepretation
106208
 
+ */
106209
 
+
106210
 
+static int tst_test_result_execute_operation_execute
106211
 
+(const struct sieve_operation *op ATTR_UNUSED,
106212
 
+       const struct sieve_runtime_env *renv, 
106213
 
+       sieve_size_t *address ATTR_UNUSED)
106214
 
+{
106215
 
+       bool result = TRUE;
106216
 
+
106217
 
+       /*
106218
 
+        * Perform operation
106219
 
+        */
106220
 
+
106221
 
+       sieve_runtime_trace(renv, "TEST_RESULT_EXECUTE test");
106222
 
+
106223
 
+       result = testsuite_result_execute(renv);
106224
 
+
106225
 
+       /* Set result */
106226
 
+       sieve_interpreter_set_test_result(renv->interp, result);
106227
 
+
106228
 
+       return SIEVE_EXEC_OK;
106229
 
+}
106230
 
+
106231
 
+
106232
 
+
106233
 
+
106234
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/testsuite/tst-test-script-compile.c dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/tst-test-script-compile.c
106235
 
--- dovecot-1.2.4/dovecot-libsieve/src/testsuite/tst-test-script-compile.c      1970-01-01 01:00:00.000000000 +0100
106236
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/tst-test-script-compile.c       2009-01-27 00:27:22.000000000 +0100
106237
 
@@ -0,0 +1,158 @@
106238
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
106239
 
+ */
106240
 
+
106241
 
+#include "sieve-common.h"
106242
 
+#include "sieve-script.h"
106243
 
+#include "sieve-commands.h"
106244
 
+#include "sieve-validator.h"
106245
 
+#include "sieve-generator.h"
106246
 
+#include "sieve-interpreter.h"
106247
 
+#include "sieve-code.h"
106248
 
+#include "sieve-binary.h"
106249
 
+#include "sieve-dump.h"
106250
 
+#include "sieve.h"
106251
 
+
106252
 
+#include "testsuite-common.h"
106253
 
+#include "testsuite-script.h"
106254
 
+
106255
 
+/*
106256
 
+ * Test_script_compile command
106257
 
+ *
106258
 
+ * Syntax:   
106259
 
+ *   test_script_compile <scriptpath: string>
106260
 
+ */
106261
 
+
106262
 
+static bool tst_test_script_compile_validate
106263
 
+       (struct sieve_validator *validator, struct sieve_command_context *cmd);
106264
 
+static bool tst_test_script_compile_generate
106265
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx);
106266
 
+
106267
 
+const struct sieve_command tst_test_script_compile = { 
106268
 
+       "test_script_compile", 
106269
 
+       SCT_TEST, 
106270
 
+       1, 0, FALSE, FALSE,
106271
 
+       NULL, NULL,
106272
 
+       tst_test_script_compile_validate, 
106273
 
+       tst_test_script_compile_generate, 
106274
 
+       NULL 
106275
 
+};
106276
 
+
106277
 
+/* 
106278
 
+ * Operation 
106279
 
+ */
106280
 
+
106281
 
+static bool tst_test_script_compile_operation_dump
106282
 
+       (const struct sieve_operation *op,
106283
 
+               const struct sieve_dumptime_env *denv, sieve_size_t *address);
106284
 
+static int tst_test_script_compile_operation_execute
106285
 
+       (const struct sieve_operation *op, 
106286
 
+               const struct sieve_runtime_env *renv, sieve_size_t *address);
106287
 
+
106288
 
+const struct sieve_operation test_script_compile_operation = { 
106289
 
+       "TEST_SCRIPT_COMPILE",
106290
 
+       &testsuite_extension, 
106291
 
+       TESTSUITE_OPERATION_TEST_SCRIPT_COMPILE,
106292
 
+       tst_test_script_compile_operation_dump, 
106293
 
+       tst_test_script_compile_operation_execute 
106294
 
+};
106295
 
+
106296
 
+/* 
106297
 
+ * Validation 
106298
 
+ */
106299
 
+
106300
 
+static bool tst_test_script_compile_validate
106301
 
+(struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_command_context *tst) 
106302
 
+{
106303
 
+       struct sieve_ast_argument *arg = tst->first_positional;
106304
 
+       
106305
 
+       if ( !sieve_validate_positional_argument
106306
 
+               (valdtr, tst, arg, "script", 1, SAAT_STRING) ) {
106307
 
+               return FALSE;
106308
 
+       }
106309
 
+       
106310
 
+       return sieve_validator_argument_activate(valdtr, tst, arg, FALSE);
106311
 
+}
106312
 
+
106313
 
+/* 
106314
 
+ * Code generation 
106315
 
+ */
106316
 
+
106317
 
+static inline struct testsuite_generator_context *
106318
 
+       _get_generator_context(struct sieve_generator *gentr)
106319
 
+{
106320
 
+       return (struct testsuite_generator_context *) 
106321
 
+               sieve_generator_extension_get_context(gentr, &testsuite_extension);
106322
 
+}
106323
 
+
106324
 
+static bool tst_test_script_compile_generate
106325
 
+(const struct sieve_codegen_env *cgenv, struct sieve_command_context *tst)
106326
 
+{
106327
 
+       sieve_operation_emit_code(cgenv->sbin, &test_script_compile_operation);
106328
 
+
106329
 
+       /* Generate arguments */
106330
 
+       return sieve_generate_arguments(cgenv, tst, NULL);
106331
 
+}
106332
 
+
106333
 
+/* 
106334
 
+ * Code dump
106335
 
+ */
106336
 
106337
 
+static bool tst_test_script_compile_operation_dump
106338
 
+(const struct sieve_operation *op ATTR_UNUSED,
106339
 
+       const struct sieve_dumptime_env *denv, sieve_size_t *address)
106340
 
+{
106341
 
+       sieve_code_dumpf(denv, "TEST_SCRIPT_COMPILE:");
106342
 
+       sieve_code_descend(denv);
106343
 
+
106344
 
+       if ( !sieve_opr_string_dump(denv, address, "script") ) 
106345
 
+               return FALSE;
106346
 
+
106347
 
+       return TRUE;
106348
 
+}
106349
 
+
106350
 
+/*
106351
 
+ * Intepretation
106352
 
+ */
106353
 
+
106354
 
+static int tst_test_script_compile_operation_execute
106355
 
+(const struct sieve_operation *op ATTR_UNUSED,
106356
 
+       const struct sieve_runtime_env *renv, sieve_size_t *address)
106357
 
+{
106358
 
+       string_t *script_name;
106359
 
+       const char *script_path;
106360
 
+       bool result = TRUE;
106361
 
+
106362
 
+       /*
106363
 
+        * Read operands
106364
 
+        */
106365
 
+
106366
 
+       if ( !sieve_opr_string_read(renv, address, &script_name) ) {
106367
 
+               sieve_runtime_trace_error(renv, "invalid script name operand");
106368
 
+               return SIEVE_EXEC_BIN_CORRUPT;
106369
 
+       }
106370
 
+
106371
 
+       /*
106372
 
+        * Perform operation
106373
 
+        */
106374
 
+
106375
 
+       sieve_runtime_trace(renv, "TEST COMPILE: %s", str_c(script_name));
106376
 
+
106377
 
+       script_path = sieve_script_dirpath(renv->script);
106378
 
+       if ( script_path == NULL ) 
106379
 
+               return SIEVE_EXEC_FAILURE;
106380
 
+
106381
 
+       script_path = t_strconcat(script_path, "/", str_c(script_name), NULL);
106382
 
+
106383
 
+       /* Attempt script compile */
106384
 
+
106385
 
+       result = testsuite_script_compile(script_path);
106386
 
+
106387
 
+       /* Set result */
106388
 
+       sieve_interpreter_set_test_result(renv->interp, result);
106389
 
+
106390
 
+       return SIEVE_EXEC_OK;
106391
 
+}
106392
 
+
106393
 
+
106394
 
+
106395
 
+
106396
 
diff -urN dovecot-1.2.4/dovecot-libsieve/src/testsuite/tst-test-script-run.c dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/tst-test-script-run.c
106397
 
--- dovecot-1.2.4/dovecot-libsieve/src/testsuite/tst-test-script-run.c  1970-01-01 01:00:00.000000000 +0100
106398
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/src/testsuite/tst-test-script-run.c   2009-02-11 21:38:58.000000000 +0100
106399
 
@@ -0,0 +1,197 @@
106400
 
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
106401
 
+ */
106402
 
+
106403
 
+#include "sieve-common.h"
106404
 
+#include "sieve-script.h"
106405
 
+#include "sieve-commands.h"
106406
 
+#include "sieve-validator.h"
106407
 
+#include "sieve-generator.h"
106408
 
+#include "sieve-interpreter.h"
106409
 
+#include "sieve-code.h"
106410
 
+#include "sieve-binary.h"
106411
 
+#include "sieve-dump.h"
106412
 
+#include "sieve.h"
106413
 
+
106414
 
+#include "testsuite-common.h"
106415
 
+#include "testsuite-script.h"
106416
 
+#include "testsuite-result.h"
106417
 
+
106418
 
+/*
106419
 
+ * Test_script_run command
106420
 
+ *
106421
 
+ * Syntax:   
106422
 
+ *   test_script_run
106423
 
+ */
106424
 
+
106425
 
+static bool tst_test_script_run_registered
106426
 
+(struct sieve_validator *validator, struct sieve_command_registration *cmd_reg);
106427
 
+static bool tst_test_script_run_generate
106428
 
+       (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx);
106429
 
+
106430
 
+const struct sieve_command tst_test_script_run = { 
106431
 
+       "test_script_run", 
106432
 
+       SCT_TEST, 
106433
 
+       0, 0, FALSE, FALSE,
106434
 
+       tst_test_script_run_registered, 
106435
 
+       NULL, NULL,
106436
 
+       tst_test_script_run_generate, 
106437
 
+       NULL 
106438
 
+};
106439
 
+
106440
 
+/* 
106441
 
+ * Operation 
106442
 
+ */
106443
 
+
106444
 
+static bool tst_test_script_run_operation_dump
106445
 
+       (const struct sieve_operation *op,
106446
 
+               const struct sieve_dumptime_env *denv, sieve_size_t *address);
106447
 
+static int tst_test_script_run_operation_execute
106448
 
+       (const struct sieve_operation *op, 
106449
 
+               const struct sieve_runtime_env *renv, sieve_size_t *address);
106450
 
+
106451
 
+const struct sieve_operation test_script_run_operation = { 
106452
 
+       "test_script_run",
106453
 
+       &testsuite_extension, 
106454
 
+       TESTSUITE_OPERATION_TEST_SCRIPT_RUN,
106455
 
+       tst_test_script_run_operation_dump, 
106456
 
+       tst_test_script_run_operation_execute 
106457
 
+};
106458
 
+
106459
 
+/*
106460
 
+ * Tagged arguments
106461
 
+ */
106462
 
+
106463
 
+/* Codes for optional arguments */
106464
 
+
106465
 
+enum cmd_vacation_optional {
106466
 
+       OPT_END,
106467
 
+       OPT_APPEND_RESULT
106468
 
+};
106469
 
+
106470
 
+/* Tags */
106471
 
+
106472
 
+static const struct sieve_argument append_result_tag = { 
106473
 
+       "append_result",        
106474
 
+       NULL, NULL, NULL, NULL, NULL
106475
 
+};
106476
 
+
106477
 
+static bool tst_test_script_run_registered
106478
 
+(struct sieve_validator *validator, struct sieve_command_registration *cmd_reg) 
106479
 
+{
106480
 
+       sieve_validator_register_tag
106481
 
+               (validator, cmd_reg, &append_result_tag, OPT_APPEND_RESULT);    
106482
 
+
106483
 
+       return TRUE;
106484
 
+}
106485
 
+
106486
 
+
106487
 
+/* 
106488
 
+ * Code generation 
106489
 
+ */
106490
 
+
106491
 
+static bool tst_test_script_run_generate
106492
 
+(const struct sieve_codegen_env *cgenv, 
106493
 
+       struct sieve_command_context *tst)
106494
 
+{
106495
 
+       sieve_operation_emit_code(cgenv->sbin, &test_script_run_operation);
106496
 
+
106497
 
+       return sieve_generate_arguments(cgenv, tst, NULL);
106498
 
+}
106499
 
+
106500
 
+/*
106501
 
+ * Code dump
106502
 
+ */
106503
 
+
106504
 
+static bool tst_test_script_run_operation_dump
106505
 
+(const struct sieve_operation *op ATTR_UNUSED,
106506
 
+       const struct sieve_dumptime_env *denv, sieve_size_t *address)
106507
 
+{      
106508
 
+       int opt_code = 1;
106509
 
+       
106510
 
+       sieve_code_dumpf(denv, "TEST_SCRIPT_RUN");
106511
 
+       sieve_code_descend(denv);       
106512
 
+
106513
 
+       /* Dump optional operands */
106514
 
+       if ( sieve_operand_optional_present(denv->sbin, address) ) {
106515
 
+               while ( opt_code != 0 ) {
106516
 
+                       sieve_code_mark(denv);
106517
 
+                       
106518
 
+                       if ( !sieve_operand_optional_read(denv->sbin, address, &opt_code) ) 
106519
 
+                               return FALSE;
106520
 
+
106521
 
+                       switch ( opt_code ) {
106522
 
+                       case 0:
106523
 
+                               break;
106524
 
+                       case OPT_APPEND_RESULT:
106525
 
+                               sieve_code_dumpf(denv, "append_result");        
106526
 
+                               break;
106527
 
+                       
106528
 
+                       default:
106529
 
+                               return FALSE;
106530
 
+                       }
106531
 
+               }
106532
 
+       }
106533
 
+       
106534
 
+       return TRUE;
106535
 
+}
106536
 
+
106537
 
+
106538
 
+/*
106539
 
+ * Intepretation
106540
 
+ */
106541
 
+
106542
 
+static int tst_test_script_run_operation_execute
106543
 
+(const struct sieve_operation *op ATTR_UNUSED,
106544
 
+       const struct sieve_runtime_env *renv, 
106545
 
+       sieve_size_t *address ATTR_UNUSED)
106546
 
+{
106547
 
+       bool append_result = FALSE;
106548
 
+       int opt_code = 1;
106549
 
+       bool result = TRUE;
106550
 
+
106551
 
+       /*
106552
 
+        * Read operands
106553
 
+        */
106554
 
+
106555
 
+       /* Optional operands */ 
106556
 
+       if ( sieve_operand_optional_present(renv->sbin, address) ) {
106557
 
+               while ( opt_code != 0 ) {
106558
 
+                       if ( !sieve_operand_optional_read(renv->sbin, address, &opt_code) ) {
106559
 
+                               sieve_runtime_trace_error(renv, "invalid optional operand");
106560
 
+                               return SIEVE_EXEC_BIN_CORRUPT;
106561
 
+                       }
106562
 
+
106563
 
+                       switch ( opt_code ) {
106564
 
+                       case 0:
106565
 
+                               break;
106566
 
+                       case OPT_APPEND_RESULT:
106567
 
+                               append_result = TRUE;
106568
 
+                               break;
106569
 
+                       default:
106570
 
+                               sieve_runtime_trace_error(renv, 
106571
 
+                                       "unknown optional operand");
106572
 
+                               return SIEVE_EXEC_BIN_CORRUPT;
106573
 
+                       }
106574
 
+               }
106575
 
+       }
106576
 
+
106577
 
+       /*
106578
 
+        * Perform operation
106579
 
+        */
106580
 
+
106581
 
+       /* Reset result object */
106582
 
+       if ( !append_result ) 
106583
 
+               testsuite_result_reset(renv);
106584
 
+
106585
 
+       /* Run script */
106586
 
+       result = testsuite_script_run(renv);
106587
 
+
106588
 
+       /* Indicate test status */
106589
 
+       sieve_interpreter_set_test_result(renv->interp, result);
106590
 
+
106591
 
+       return SIEVE_EXEC_OK;
106592
 
+}
106593
 
+
106594
 
+
106595
 
+
106596
 
+
106597
 
diff -urN dovecot-1.2.4/dovecot-libsieve/stamp.h.in dovecot-1.2.4.debian/dovecot-libsieve/stamp.h.in
106598
 
--- dovecot-1.2.4/dovecot-libsieve/stamp.h.in   1970-01-01 01:00:00.000000000 +0100
106599
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/stamp.h.in    2009-09-02 07:26:02.000000000 +0200
106600
 
@@ -0,0 +1,2 @@
106601
 
+
106602
 
+
106603
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/address.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/address.svtest
106604
 
--- dovecot-1.2.4/dovecot-libsieve/tests/address.svtest 1970-01-01 01:00:00.000000000 +0100
106605
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/address.svtest  2009-04-10 14:10:07.000000000 +0200
106606
 
@@ -0,0 +1,111 @@
106607
 
+require "vnd.dovecot.testsuite";
106608
 
+
106609
 
+/*
106610
 
+ * If an address is not syntactically valid, then it will not be matched
106611
 
+ * by tests specifying ":localpart" or ":domain".
106612
 
+ */
106613
 
+
106614
 
+test_set "message" text:
106615
 
+From: stephan@
106616
 
+To: @rename-it.nl
106617
 
+Cc: nonsense
106618
 
+Resent-To:
106619
 
+Subject: Invalid addresses
106620
 
+
106621
 
+Test.
106622
 
+.
106623
 
+;
106624
 
+
106625
 
+test "Invalid single addresses" {
106626
 
+       if address :localpart "from" "stephan" {
106627
 
+               test_fail ":localpart matched invalid address";
106628
 
+       }       
106629
 
+
106630
 
+       if address :domain "to" "rename-it.nl" {
106631
 
+               test_fail ":domain matched invalid address";
106632
 
+       }       
106633
 
+
106634
 
+       if not address :is :all "resent-to" "" {
106635
 
+               test_fail ":all failed to match empty address";
106636
 
+       }       
106637
 
+
106638
 
+       if not address :is :all "cc" "nonsense" {
106639
 
+               test_fail ":all failed to match invalid address";
106640
 
+       }
106641
 
+}
106642
 
+
106643
 
+/*
106644
 
+ * Errors in address lists
106645
 
+ */ 
106646
 
+
106647
 
+test_set "message" text:
106648
 
+From: stephan@
106649
 
+To: nico@vestingbar.nl, @rename-it.nl
106650
 
+Cc: stephan@rename-it.nl, nonsense
106651
 
+Subject: Invalid addresses
106652
 
+
106653
 
+Test.
106654
 
+.
106655
 
+;
106656
 
+
106657
 
+test "Invalid address list" {
106658
 
+       if address :is :localpart "to" "" {
106659
 
+               test_fail ":localpart matched invalid address";
106660
 
+       }       
106661
 
+
106662
 
+       if address :is :domain "to" "rename-it.nl" {
106663
 
+               test_fail ":domain matched invalid address";
106664
 
+       }       
106665
 
+}
106666
 
+
106667
 
+/*
106668
 
+ * Undisclosed recipients
106669
 
+ */
106670
 
+
106671
 
+test_set "message" text:
106672
 
+From: stephan@
106673
 
+To: undisclosed-recipients:;
106674
 
+Subject: Invalid addresses
106675
 
+
106676
 
+Test.
106677
 
+.
106678
 
+;
106679
 
+
106680
 
+test "Undisclosed recipients" {
106681
 
+    if address :is :domain "to" "undisclosed-recipients:;" {
106682
 
+        test_fail ":domain matched group name";
106683
 
+    }
106684
 
+
106685
 
+    if address :is :localpart "to" "undisclosed-recipients:;" {
106686
 
+        test_fail ":localpart matched group name";
106687
 
+    }
106688
 
+}
106689
 
+
106690
 
+/*
106691
 
+ * Strange
106692
 
+ */
106693
 
+
106694
 
+test_set "message" text:
106695
 
+From: SPAM@MYDOMAIN
106696
 
+To: stephan@renane-it.nl
106697
 
+Subject: Spam
106698
 
+
106699
 
+Spam!
106700
 
+.
106701
 
+;
106702
 
+
106703
 
+test "Questionable address" {
106704
 
+       if address :domain :is "from" "MYDOMAIN" {
106705
 
+               if address :localpart :is "from" "SPAM" {
106706
 
+                       
106707
 
+               } elsif header :contains "subject" "Cron" {
106708
 
+                       test_fail "message erroneously recognized as cron";
106709
 
+               } else {
106710
 
+                       test_fail "message erroneously recognized as normal";
106711
 
+               }
106712
 
+       } else {
106713
 
+               test_fail "message domain not recognized";
106714
 
+       }
106715
 
+}
106716
 
+
106717
 
+
106718
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/comparators/core.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/comparators/core.svtest
106719
 
--- dovecot-1.2.4/dovecot-libsieve/tests/comparators/core.svtest        1970-01-01 01:00:00.000000000 +0100
106720
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/comparators/core.svtest 2008-07-30 15:17:37.000000000 +0200
106721
 
@@ -0,0 +1,65 @@
106722
 
+require "vnd.dovecot.testsuite";
106723
 
+
106724
 
+test_set "message" text:
106725
 
+From: stephan@rename-it.nl
106726
 
+Cc: frop@example.com
106727
 
+To: test@dovecot.org
106728
 
+X-A: This is a TEST header
106729
 
+Subject: Test Message
106730
 
+
106731
 
+Test!
106732
 
+.
106733
 
+;
106734
 
+
106735
 
+# Comparator Tests
106736
 
+
106737
 
+test "CMP-octet-CONTAINS" {
106738
 
+       if not header :contains :comparator "i;octet" "X-A" "TEST" {
106739
 
+               test_fail "should have matched";
106740
 
+       }
106741
 
+}
106742
 
+
106743
 
+test "CMP-octet-NOTCONTAINS" {
106744
 
+       if header :contains :comparator "i;octet" "X-A" "test" {
106745
 
+               test_fail "should not have matched";
106746
 
+       }
106747
 
+}
106748
 
+
106749
 
+test "CMP-octet-MATCH" {
106750
 
+       if not header :matches :comparator "i;octet" "X-A" "This*TEST*r" {
106751
 
+               test_fail "should have matched";
106752
 
+       }
106753
 
+}
106754
 
+
106755
 
+test "CMP-octet-NOTMATCH" {
106756
 
+       if header :matches :comparator "i;octet" "X-A" "ThIs*tEsT*R" {
106757
 
+               test_fail "should not have matched";
106758
 
+       }
106759
 
+}
106760
 
+
106761
 
+test "CMP-ascii-casemap-CONTAINS-1" {
106762
 
+       if not header :contains :comparator "i;ascii-casemap" "X-A" "TEST" {
106763
 
+               test_fail "should have matched";
106764
 
+       }
106765
 
+}
106766
 
+
106767
 
+test "CMP-ascii-casemap-CONTAINS-2" {
106768
 
+       if not header :contains :comparator "i;ascii-casemap" "X-A" "test" {
106769
 
+               test_fail "should have matched";
106770
 
+       }
106771
 
+}
106772
 
+
106773
 
+test "CMP-ascii-casemap-MATCH-1" {
106774
 
+       if not header :matches :comparator "i;ascii-casemap" "X-A" "This*TEST*r" {
106775
 
+               test_fail "should have matched";
106776
 
+       }
106777
 
+}
106778
 
+
106779
 
+test "CMP-ascii-casemap-MATCH-2" {
106780
 
+       if not header :matches :comparator "i;ascii-casemap" "X-A" "ThIs*tEsT*R" {
106781
 
+               test_fail "should have matched";
106782
 
+       }
106783
 
+}
106784
 
+
106785
 
+
106786
 
+
106787
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/compile/compile.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/compile/compile.svtest
106788
 
--- dovecot-1.2.4/dovecot-libsieve/tests/compile/compile.svtest 1970-01-01 01:00:00.000000000 +0100
106789
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/compile/compile.svtest  2009-01-06 00:15:52.000000000 +0100
106790
 
@@ -0,0 +1,16 @@
106791
 
+require "vnd.dovecot.testsuite";
106792
 
+
106793
 
+# Just test whether valid scripts will compile without problems
106794
 
+
106795
 
+test "Trivial" {
106796
 
+       if not test_script_compile "trivial.sieve" {
106797
 
+               test_fail "could not compile";
106798
 
+       }
106799
 
+}
106800
 
+
106801
 
+test "Redirect" {
106802
 
+       if not test_script_compile "redirect.sieve" {
106803
 
+               test_fail "could not compile";
106804
 
+       }
106805
 
+}
106806
 
+
106807
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/compile/errors/address-part.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/compile/errors/address-part.sieve
106808
 
--- dovecot-1.2.4/dovecot-libsieve/tests/compile/errors/address-part.sieve      1970-01-01 01:00:00.000000000 +0100
106809
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/compile/errors/address-part.sieve       2008-07-30 15:17:37.000000000 +0200
106810
 
@@ -0,0 +1,17 @@
106811
 
+/*
106812
 
+ * Address part errors
106813
 
+ *
106814
 
+ * Total errors: 2 (+1 = 3)
106815
 
+ */
106816
 
+
106817
 
+# Duplicate address part (1)
106818
 
+if address :all :comparator "i;octet" :domain "from" "STEPHAN" {
106819
 
+
106820
 
+       # Duplicate address part (2)
106821
 
+       if address :domain :localpart :comparator "i;octet" "from" "drunksnipers.com" {
106822
 
+               keep;
106823
 
+       }
106824
 
+
106825
 
+       stop;
106826
 
+}
106827
 
+
106828
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/compile/errors/address.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/compile/errors/address.sieve
106829
 
--- dovecot-1.2.4/dovecot-libsieve/tests/compile/errors/address.sieve   1970-01-01 01:00:00.000000000 +0100
106830
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/compile/errors/address.sieve    2008-07-30 15:17:37.000000000 +0200
106831
 
@@ -0,0 +1,71 @@
106832
 
+require "comparator-i;ascii-numeric";
106833
 
+
106834
 
+/* 
106835
 
+ * Address test errors
106836
 
+ *
106837
 
+ * Total count: 8 (+1 = 9)
106838
 
+ */
106839
 
+
106840
 
+/*
106841
 
+ * Command structure
106842
 
+ */ 
106843
 
+
106844
 
+# Invalid tag
106845
 
+if address :nonsense :comparator "i;ascii-casemap" :localpart "From" "nico" {
106846
 
+       discard;
106847
 
+}
106848
 
+
106849
 
+# Invalid first argument
106850
 
+if address :is :comparator "i;ascii-numeric" :localpart 45 "nico" {
106851
 
+       discard;
106852
 
+}
106853
 
+
106854
 
+# Invalid second argument
106855
 
+if address :is :comparator "i;ascii-numeric" :localpart "From" 45 {
106856
 
+       discard;
106857
 
+}
106858
 
+
106859
 
+# Invalid second argument
106860
 
+if address :comparator "i;ascii-numeric" :localpart "From" :is {
106861
 
+       discard;
106862
 
+}
106863
 
+
106864
 
+# Missing second argument
106865
 
+if address :is :comparator "i;ascii-numeric" :localpart "From" {
106866
 
+       discard;
106867
 
+}
106868
 
+
106869
 
+# Missing arguments
106870
 
+if address :is :comparator "i;ascii-numeric" :localpart {
106871
 
+       discard;
106872
 
+}
106873
 
+
106874
 
+# Not an error
106875
 
+if address :localpart :is :comparator "i;ascii-casemap" "from" ["frop", "frop"] {
106876
 
+       discard;
106877
 
+}
106878
 
+
106879
 
+/*
106880
 
+ * Specified headers must contain addresses
106881
 
+ */
106882
 
+
106883
 
+# Invalid header 
106884
 
+if address :is "frop" "frml" {
106885
 
+       keep;
106886
 
+}
106887
 
+
106888
 
+# Not an error
106889
 
+if address :is "reply-to" "frml" {
106890
 
+       keep;
106891
 
+}
106892
 
+
106893
 
+# Invalid header (#2)
106894
 
+if address :is ["to", "frop"] "frml" {
106895
 
+       keep;
106896
 
+}
106897
 
+
106898
 
+# Not an error
106899
 
+if address :is ["to", "reply-to"] "frml" {
106900
 
+       keep;
106901
 
+}
106902
 
+
106903
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/compile/errors/encoded-character.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/compile/errors/encoded-character.sieve
106904
 
--- dovecot-1.2.4/dovecot-libsieve/tests/compile/errors/encoded-character.sieve 1970-01-01 01:00:00.000000000 +0100
106905
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/compile/errors/encoded-character.sieve  2008-07-30 15:17:37.000000000 +0200
106906
 
@@ -0,0 +1,23 @@
106907
 
+/*
106908
 
+ * Encoded-character errors
106909
 
+ *
106910
 
+ * Total errors: 2 (+1 = 3)
106911
 
+ */
106912
 
+
106913
 
+require "encoded-character";
106914
 
+require "fileinto";
106915
 
+
106916
 
+# Invalid unicode character (1)
106917
 
+fileinto "INBOX.${unicode:200000}";
106918
 
+
106919
 
+# Not an error
106920
 
+fileinto "INBOX.${unicode:200000";
106921
 
+
106922
 
+# Invalid unicode character (2)
106923
 
+fileinto "INBOX.${Unicode:DF01}";
106924
 
+
106925
 
+# Not an error
106926
 
+fileinto "INBOX.${Unicode:DF01";
106927
 
+
106928
 
+
106929
 
+
106930
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/compile/errors/envelope.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/compile/errors/envelope.sieve
106931
 
--- dovecot-1.2.4/dovecot-libsieve/tests/compile/errors/envelope.sieve  1970-01-01 01:00:00.000000000 +0100
106932
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/compile/errors/envelope.sieve   2008-07-30 15:17:37.000000000 +0200
106933
 
@@ -0,0 +1,23 @@
106934
 
+/*
106935
 
+ * Envelope test errors
106936
 
+ *
106937
 
+ * Total errors: 2 (+1 = 3)
106938
 
+ */
106939
 
+
106940
 
+require "envelope";
106941
 
+
106942
 
+# Not an error 
106943
 
+if envelope :is "to" "frop@rename-it.nl" {
106944
 
+}
106945
 
+
106946
 
+# Unknown envelope part (1)
106947
 
+if envelope :is "frop" "frop@rename-it.nl" {
106948
 
+}
106949
 
+
106950
 
+# Not an error
106951
 
+if envelope :is ["to","from"] "frop@rename-it.nl" {
106952
 
+}
106953
 
+
106954
 
+# Unknown envelope part (2)
106955
 
+if envelope :is ["to","frop"] "frop@rename-it.nl" {
106956
 
+}
106957
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/compile/errors/header.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/compile/errors/header.sieve
106958
 
--- dovecot-1.2.4/dovecot-libsieve/tests/compile/errors/header.sieve    1970-01-01 01:00:00.000000000 +0100
106959
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/compile/errors/header.sieve     2008-07-30 15:17:37.000000000 +0200
106960
 
@@ -0,0 +1,57 @@
106961
 
+require "comparator-i;ascii-numeric";
106962
 
+
106963
 
+/*
106964
 
+ * Compile errors for the header test
106965
 
+ *
106966
 
+ * Total errors: 9 (+1 validation failed msg = 10)
106967
 
+ */
106968
 
+
106969
 
+# Unknown tagged argument
106970
 
+if header :all :comparator "i;ascii-casemap" "From" "nico" {
106971
 
+       keep;
106972
 
+}
106973
 
+
106974
 
+# Wrong first argument
106975
 
+if header :is :comparator "i;ascii-numeric" 45 "nico" {
106976
 
+       keep;
106977
 
+}
106978
 
+
106979
 
+# Wrong second argument
106980
 
+if header :is :comparator "i;ascii-numeric" "From" 45 {
106981
 
+       discard;
106982
 
+}
106983
 
+
106984
 
+# Wrong second argument
106985
 
+if header :is :comparator "i;ascii-numeric" "From" :tag {
106986
 
+       stop;
106987
 
+}
106988
 
+
106989
 
+# Missing second argument
106990
 
+if header :is :comparator "i;ascii-numeric" "From" {
106991
 
+       stop;
106992
 
+}
106993
 
+
106994
 
+# Missing arguments
106995
 
+if header :is :comparator "i;ascii-numeric" {
106996
 
+       keep;
106997
 
+}
106998
 
+
106999
 
+# Not an error
107000
 
+if header :is :comparator "i;ascii-casemap" "frop" ["frop", "frop"] {
107001
 
+       discard;
107002
 
+}
107003
 
+
107004
 
+# Spurious sub-test
107005
 
+if header "frop" "frop" true {
107006
 
+       discard;
107007
 
+}
107008
 
+
107009
 
+# Test used as command with block
107010
 
+header "frop" "frop" {
107011
 
+    discard;
107012
 
+}
107013
 
+
107014
 
+# Test used as command
107015
 
+header "frop" "frop";
107016
 
+
107017
 
+
107018
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/compile/errors/if.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/compile/errors/if.sieve
107019
 
--- dovecot-1.2.4/dovecot-libsieve/tests/compile/errors/if.sieve        1970-01-01 01:00:00.000000000 +0100
107020
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/compile/errors/if.sieve 2008-07-30 15:17:37.000000000 +0200
107021
 
@@ -0,0 +1,78 @@
107022
 
+/*
107023
 
+ * If command errors 
107024
 
+ *
107025
 
+ * Total errors: 11 (+1 = 12)
107026
 
+ */
107027
 
+
107028
 
+# Spurious argument
107029
 
+if "frop" true {}
107030
 
+
107031
 
+# Spurious argument
107032
 
+elsif "frop" true {}
107033
 
+
107034
 
+# Spurious string list
107035
 
+if [ "false", "false", "false" ] false {
107036
 
+       stop;
107037
 
+}
107038
 
+
107039
 
+# No block
107040
 
+if true;
107041
 
+
107042
 
+# No test
107043
 
+if {
107044
 
+       keep;
107045
 
+}
107046
 
+
107047
 
+# Spurious test list
107048
 
+if ( false, false, true ) {
107049
 
+       keep;
107050
 
+}
107051
 
+
107052
 
+stop;
107053
 
+
107054
 
+# If-less else
107055
 
+else {
107056
 
+       keep;
107057
 
+}
107058
 
+
107059
 
+# Not an error
107060
 
+if true {
107061
 
+       keep;
107062
 
+}
107063
 
+
107064
 
+stop;
107065
 
+
107066
 
+# If-less if structure (should produce only one error)
107067
 
+elsif true {
107068
 
+       keep;
107069
 
+}
107070
 
+elsif true {
107071
 
+       keep;
107072
 
+}
107073
 
+else {
107074
 
+}
107075
 
+
107076
 
+# Elsif after else
107077
 
+if true {
107078
 
+       keep;
107079
 
+} else {
107080
 
+       stop;
107081
 
+} elsif true {
107082
 
+       stop;
107083
 
+}
107084
 
+
107085
 
+# If used as test
107086
 
+if if true {
107087
 
+} 
107088
 
+
107089
 
+# Else if in stead of elsif
107090
 
+
107091
 
+if true {
107092
 
+       stop;
107093
 
+} else if false {
107094
 
+       keep;
107095
 
+}
107096
 
+
107097
 
+
107098
 
+
107099
 
+
107100
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/compile/errors/keep.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/compile/errors/keep.sieve
107101
 
--- dovecot-1.2.4/dovecot-libsieve/tests/compile/errors/keep.sieve      1970-01-01 01:00:00.000000000 +0100
107102
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/compile/errors/keep.sieve       2008-07-30 15:17:37.000000000 +0200
107103
 
@@ -0,0 +1,14 @@
107104
 
+/*
107105
 
+ * Keep errors
107106
 
+ *
107107
 
+ * Total erors: 2 (+1 = 3)
107108
 
+ */
107109
 
+
107110
 
+# Spurious string argument
107111
 
+keep "frop";
107112
 
+
107113
 
+# Spurious test 
107114
 
+keep true;
107115
 
+
107116
 
+# Not an error
107117
 
+keep;
107118
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/compile/errors/lexer.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/compile/errors/lexer.sieve
107119
 
--- dovecot-1.2.4/dovecot-libsieve/tests/compile/errors/lexer.sieve     1970-01-01 01:00:00.000000000 +0100
107120
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/compile/errors/lexer.sieve      2008-08-10 20:30:25.000000000 +0200
107121
 
@@ -0,0 +1,71 @@
107122
 
+/*
107123
 
+ * Lexer tests
107124
 
+ *
107125
 
+ * Total errors: 7 (+1 = 8)
107126
 
+ */
107127
 
+
107128
 
+/*
107129
 
+ * Number limits
107130
 
+ */
107131
 
107132
 
+# Number too large
107133
 
+if size :under 4294967300 {
107134
 
+       stop;
107135
 
+}
107136
 
+
107137
 
+# Number too large
107138
 
+if size :under 4294967296 {
107139
 
+       stop;
107140
 
+}
107141
 
+
107142
 
+# Number too large
107143
 
+if size :over 35651584k {
107144
 
+       stop;
107145
 
+}
107146
 
+
107147
 
+# Number too large
107148
 
+if size :over 34816M {
107149
 
+       stop;
107150
 
+}
107151
 
+
107152
 
+# Number too large
107153
 
+if size :over 34G {
107154
 
+       stop;
107155
 
+}
107156
 
+
107157
 
+# Number too large
107158
 
+if size :over 4G {
107159
 
+       stop;
107160
 
+}
107161
 
+
107162
 
+# Number far too large
107163
 
+if size :over 49834598293485814273947921734981723971293741923 {
107164
 
+       stop;
107165
 
+}
107166
 
+
107167
 
+# Not an error
107168
 
+if size :under 4294967295 {
107169
 
+       stop;
107170
 
+}
107171
 
+
107172
 
+# Not an error
107173
 
+if size :under 4294967294 {
107174
 
+       stop;
107175
 
+}
107176
 
+
107177
 
+# Not an error
107178
 
+if size :under 1G {
107179
 
+       stop;
107180
 
+}
107181
 
+
107182
 
+/*
107183
 
+ * Identifier limits
107184
 
+ */
107185
 
+
107186
 
+if this_is_a_rediculously_long_test_name {
107187
 
+       stop;
107188
 
+}
107189
 
+
107190
 
+if test :this_is_an_even_more_rediculously_long_tagged_argument_name {
107191
 
+       stop;
107192
 
+}
107193
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/compile/errors/match-type.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/compile/errors/match-type.sieve
107194
 
--- dovecot-1.2.4/dovecot-libsieve/tests/compile/errors/match-type.sieve        1970-01-01 01:00:00.000000000 +0100
107195
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/compile/errors/match-type.sieve 2008-08-25 10:25:08.000000000 +0200
107196
 
@@ -0,0 +1,7 @@
107197
 
+require "comparator-i;ascii-numeric";
107198
 
+
107199
 
+if header :contains :comparator "i;ascii-numeric" "from" "drunksnipers.com" {
107200
 
+    keep;
107201
 
+}
107202
 
+
107203
 
+keep;
107204
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/compile/errors/out-address.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/compile/errors/out-address.sieve
107205
 
--- dovecot-1.2.4/dovecot-libsieve/tests/compile/errors/out-address.sieve       1970-01-01 01:00:00.000000000 +0100
107206
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/compile/errors/out-address.sieve        2009-01-21 23:50:10.000000000 +0100
107207
 
@@ -0,0 +1,27 @@
107208
 
+require "vacation";
107209
 
+
107210
 
+# Error 
107211
 
+
107212
 
+redirect "@wrong.example.com";
107213
 
+redirect "error";
107214
 
+redirect "error@";
107215
 
+redirect "Stephan Bosch error@rename-it.nl";
107216
 
+redirect "Stephan Bosch <error@rename-it.nl";
107217
 
+redirect " more error @  example.com  ";
107218
 
+redirect "@";
107219
 
+redirect "<>";
107220
 
+redirect "Error <";
107221
 
+redirect "Error <stephan";
107222
 
+redirect "Error <stephan@";
107223
 
+redirect "stephan@rename-it.nl,tss@iki.fi";
107224
 
+redirect "stephan@rename-it.nl,%&^&!!~";
107225
 
+
107226
 
+vacation :from "Error" "Ik ben er niet.";
107227
 
+
107228
 
+# Ok
107229
 
+
107230
 
+redirect "Ok Good <stephan@rename-it.nl>";
107231
 
+redirect "ok@example.com";
107232
 
+redirect " more  @  example.com  ";
107233
 
+
107234
 
+vacation :from "good@voorbeeld.nl" "Ik ben weg!";
107235
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/compile/errors/parser.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/compile/errors/parser.sieve
107236
 
--- dovecot-1.2.4/dovecot-libsieve/tests/compile/errors/parser.sieve    1970-01-01 01:00:00.000000000 +0100
107237
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/compile/errors/parser.sieve     2008-08-10 20:30:25.000000000 +0200
107238
 
@@ -0,0 +1,78 @@
107239
 
+/*
107240
 
+ * Parser errors
107241
 
+ *
107242
 
+ * Total errors: 8 (+1 = 9)
107243
 
+ */
107244
 
+
107245
 
+# Too many arguments (1)
107246
 
+frop :this "is" "a" 2 :long "argument" "list" :and :it :should "fail" :during "parsing" :but "it" "should" "be" 
107247
 
+       "recoverable" "." :this "is" "a" 2 :long "argument" "list" :and :it :should "fail" :during "parsing" :but 
107248
 
+       "it" "should" "be" "recoverable" {
107249
 
+       stop;
107250
 
+}
107251
 
+
107252
 
+# Garbage argument (2)
107253
 
+friep $$$;
107254
 
+
107255
 
+# Deep block nesting (1)
107256
 
+if true { if true { if true { if true { if true { if true { if true { if true {
107257
 
+       if true { if true { if true { if true { if true { if true { if true { if true {
107258
 
+               if true { if true { if true { if true { if true { if true { if true { if true {
107259
 
+                       if true { if true {     if true { if true {     if true { if true { if true { if true {
107260
 
+                               if true { if true { if true { if true { if true { if true { if true { if true {
107261
 
+                                       stop;
107262
 
+                               } } } } } } } }
107263
 
+                       } } } } } } } }
107264
 
+               } } } } } } } }
107265
 
+       } } } } } } } }
107266
 
+} } } } } } } }
107267
 
+
107268
 
+# Deepest block and too deep test (list) nesting (1)
107269
 
+if true { if true { if true { if true { if true { if true { if true { if true {
107270
 
+       if true { if true { if true { if true { if true { if true { if true { if true {
107271
 
+               if true { if true { if true { if true { if true { if true { if true { if true {
107272
 
+                       if true { if true {     if true { if true {     if true { if true { 
107273
 
+                               if      
107274
 
+                                       anyof ( anyof ( anyof ( anyof ( anyof ( anyof ( anyof ( anyof ( 
107275
 
+                                       anyof ( anyof ( anyof ( anyof ( anyof ( anyof ( anyof ( anyof ( 
107276
 
+                                       anyof ( anyof ( anyof ( anyof ( anyof ( anyof ( anyof ( anyof ( 
107277
 
+                                       anyof ( anyof ( anyof ( anyof ( anyof ( anyof ( anyof ( anyof ( 
107278
 
+                                       anyof ( anyof ( anyof ( anyof ( anyof ( anyof ( anyof ( anyof (
107279
 
+                                               true 
107280
 
+                                       )))))))) 
107281
 
+                                       )))))))) 
107282
 
+                                       )))))))) 
107283
 
+                                       )))))))) 
107284
 
+                                       )))))))) 
107285
 
+                               {
107286
 
+                                       stop;
107287
 
+                               } 
107288
 
+                       } } } } } }
107289
 
+               } } } } } } } }
107290
 
+       } } } } } } } }
107291
 
+} } } } } } } }
107292
 
+
107293
 
+# Deepest block and too deep test nesting (1)
107294
 
+if true { if true { if true { if true { if true { if true { if true { if true {
107295
 
+       if true { if true { if true { if true { if true { if true { if true { if true {
107296
 
+               if true { if true { if true { if true { if true { if true { if true { if true {
107297
 
+                       if true { if true {     if true { if true {     if true { if true { 
107298
 
+                               if      
107299
 
+                                       not not not not not not not not
107300
 
+                                       not not not not not not not not
107301
 
+                                       not not not not not not not not
107302
 
+                                       not not not not not not not not
107303
 
+                                       not not not not not not not not false
107304
 
+                               {
107305
 
+                                       stop;
107306
 
+                               } 
107307
 
+                       } } } } } }
107308
 
+               } } } } } } } }
107309
 
+       } } } } } } } }
107310
 
+} } } } } } } }
107311
 
+
107312
 
+
107313
 
+# Garbage command; test wether previous errors were resolved (2)
107314
 
+frop $$$$;
107315
 
+
107316
 
+
107317
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/compile/errors/require.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/compile/errors/require.sieve
107318
 
--- dovecot-1.2.4/dovecot-libsieve/tests/compile/errors/require.sieve   1970-01-01 01:00:00.000000000 +0100
107319
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/compile/errors/require.sieve    2009-04-18 09:57:35.000000000 +0200
107320
 
@@ -0,0 +1,42 @@
107321
 
+/*
107322
 
+ * Require errors
107323
 
+ *
107324
 
+ * Total errors: 11 (+1 = 12)
107325
 
+ */
107326
 
+
107327
 
+# Not an error
107328
 
+require "fileinto";
107329
 
+
107330
 
+# Missing argument
107331
 
+require;
107332
 
+
107333
 
+# Too many arguments
107334
 
+require "fileinto" "vacation";
107335
 
+
107336
 
+# Invalid argument
107337
 
+require 45;
107338
 
+
107339
 
+# Invalid extensions (3 errors)
107340
 
+require ["_frop", "_friep", "_frml"];
107341
 
+
107342
 
+# Core commands required
107343
 
+require ["redirect", "keep", "discard"];
107344
 
+
107345
 
+# Invalid arguments
107346
 
+require "dovecot.test" true;
107347
 
+
107348
 
+# Invalid extension
107349
 
+require "_frop";
107350
 
+
107351
 
+# Spurious command block
107352
 
+require "fileinto" { 
107353
 
+  keep;
107354
 
+}
107355
 
+
107356
 
+# Nested require
107357
 
+if true {
107358
 
+  require "relional";
107359
 
+}
107360
 
+
107361
 
+# Require after other command than require
107362
 
+require "copy";
107363
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/compile/errors/size.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/compile/errors/size.sieve
107364
 
--- dovecot-1.2.4/dovecot-libsieve/tests/compile/errors/size.sieve      1970-01-01 01:00:00.000000000 +0100
107365
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/compile/errors/size.sieve       2008-07-30 15:17:37.000000000 +0200
107366
 
@@ -0,0 +1,47 @@
107367
 
+/*
107368
 
+ * Size test errors
107369
 
+ * 
107370
 
+ * Total errors: 6 (+1 = 7)
107371
 
+ */
107372
 
+
107373
 
+# Used as command (1)
107374
 
+size :under 23;
107375
 
+
107376
 
+# Missing argument (2)
107377
 
+if size {
107378
 
+}
107379
 
+
107380
 
+# Missing :over/:under (3)
107381
 
+if size 45 {
107382
 
+       discard;
107383
 
+}
107384
 
+
107385
 
+# No error
107386
 
+if size :over 34K {
107387
 
+       stop;
107388
 
+}
107389
 
+
107390
 
+# No error
107391
 
+if size :under 34M {
107392
 
+       stop;
107393
 
+}
107394
 
+
107395
 
+# Conflicting tags (4)
107396
 
+if size :under :over 34 {
107397
 
+       keep;
107398
 
+}
107399
 
+
107400
 
+# Duplicate tags (5)
107401
 
+if size :over :over 45M {
107402
 
+       stop;
107403
 
+}
107404
 
+
107405
 
+# Wrong argument order (6)
107406
 
+if size 34M :over {
107407
 
+       stop;
107408
 
+}
107409
 
+
107410
 
+# No error; but worthy of a warning
107411
 
+if size :under 0 {
107412
 
+       stop;
107413
 
+}
107414
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/compile/errors/stop.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/compile/errors/stop.sieve
107415
 
--- dovecot-1.2.4/dovecot-libsieve/tests/compile/errors/stop.sieve      1970-01-01 01:00:00.000000000 +0100
107416
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/compile/errors/stop.sieve       2008-07-30 15:17:37.000000000 +0200
107417
 
@@ -0,0 +1,33 @@
107418
 
+/*
107419
 
+ * Stop command errors
107420
 
+ *
107421
 
+ * Total errors: 7 (+1 = 8)
107422
 
+ */
107423
 
+
107424
 
+# Spurious string argument
107425
 
+stop "frop";
107426
 
+
107427
 
+# Spurious number argument
107428
 
+stop 13;
107429
 
+
107430
 
+# Spurious string list argument
107431
 
+stop [ "frop", "frop" ];
107432
 
+
107433
 
+# Spurious test
107434
 
+stop true;
107435
 
+
107436
 
+# Spurious test list
107437
 
+stop ( true, false );
107438
 
+
107439
 
+# Spurious command block
107440
 
+stop {
107441
 
+  keep;
107442
 
+}
107443
 
+
107444
 
+# Spurious argument and test
107445
 
+stop "frop" true {
107446
 
+  stop;
107447
 
+}
107448
 
+
107449
 
+# Not an error
107450
 
+stop;
107451
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/compile/errors/tag.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/compile/errors/tag.sieve
107452
 
--- dovecot-1.2.4/dovecot-libsieve/tests/compile/errors/tag.sieve       1970-01-01 01:00:00.000000000 +0100
107453
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/compile/errors/tag.sieve        2008-10-04 10:41:25.000000000 +0200
107454
 
@@ -0,0 +1,16 @@
107455
 
+/*
107456
 
+ * Tag errors
107457
 
+ * 
107458
 
+ * Total errors: 2 (+1 = 3)
107459
 
+ */
107460
 
+
107461
 
+# Unknown tag (1)
107462
 
+if envelope :isnot :comparator "i;ascii-casemap" :localpart "From" "nico" {
107463
 
+       discard;
107464
 
+}
107465
 
+
107466
 
+# Spurious tag (1)
107467
 
+if true :comparator "i;ascii-numeric" {
107468
 
+       keep;
107469
 
+}
107470
 
+
107471
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/compile/errors/typos.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/compile/errors/typos.sieve
107472
 
--- dovecot-1.2.4/dovecot-libsieve/tests/compile/errors/typos.sieve     1970-01-01 01:00:00.000000000 +0100
107473
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/compile/errors/typos.sieve      2008-10-20 01:35:49.000000000 +0200
107474
 
@@ -0,0 +1,29 @@
107475
 
+/*
107476
 
+ * This test is primarily meant to check the compiler's handing of typos
107477
 
+ * at various locations.
107478
 
+ */
107479
 
+
107480
 
+require "fileinto";
107481
 
+
107482
 
+/* 
107483
 
+ * Missing semicolon 
107484
 
+ */
107485
 
+
107486
 
+fileinto "frop"
107487
 
+keep;
107488
 
+
107489
 
+/* Other situations */
107490
 
+
107491
 
+fileinto "frup" 
107492
 
+true;
107493
 
+
107494
 
+fileinto "friep" 
107495
 
+snot;
107496
 
+
107497
 
+/*
107498
 
+ * Forgot tag colon
107499
 
+ */ 
107500
 
+
107501
 
+if address matches "from" "*frop*" {
107502
 
+       stop;
107503
 
+}
107504
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/compile/errors/unsupported.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/compile/errors/unsupported.sieve
107505
 
--- dovecot-1.2.4/dovecot-libsieve/tests/compile/errors/unsupported.sieve       1970-01-01 01:00:00.000000000 +0100
107506
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/compile/errors/unsupported.sieve        2008-10-20 01:35:49.000000000 +0200
107507
 
@@ -0,0 +1,39 @@
107508
 
+/* 
107509
 
+ * Handling of unsupported language features.
107510
 
+ *
107511
 
+ *   Total errors: 3 (+1 = 4)
107512
 
+ */
107513
 
+
107514
 
+require "variables";
107515
 
+require "include";
107516
 
+require "regex";
107517
 
+
107518
 
+/* 
107519
 
+ * Unsupported use of variables
107520
 
+ */
107521
 
+
107522
 
+/* Comparator argument */ 
107523
 
+
107524
 
+set "comp" "i;ascii-numeric";
107525
 
+
107526
 
+if address :comparator "${comp}" "from" "stephan@rename-it.nl" {
107527
 
+       stop;
107528
 
+}
107529
 
+
107530
 
+/* Included script */
107531
 
+
107532
 
+set "script" "blacklist";
107533
 
+
107534
 
+include "${blacklist}";
107535
 
+
107536
 
+/* Variable regexp */
107537
 
+
107538
 
+set "match" "(.*)rename-it(.*)";
107539
 
+
107540
 
+if address :regex "from" "${match}" {
107541
 
+       stop;
107542
 
+}
107543
 
107544
 
+
107545
 
+
107546
 
+
107547
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/compile/errors.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/compile/errors.svtest
107548
 
--- dovecot-1.2.4/dovecot-libsieve/tests/compile/errors.svtest  1970-01-01 01:00:00.000000000 +0100
107549
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/compile/errors.svtest   2009-04-18 10:02:11.000000000 +0200
107550
 
@@ -0,0 +1,368 @@
107551
 
+require "vnd.dovecot.testsuite";
107552
 
+
107553
 
+require "relational";
107554
 
+require "comparator-i;ascii-numeric";
107555
 
+
107556
 
+/*
107557
 
+ * Errors triggered in the compiled scripts are pretty reduntant over the
107558
 
+ * tested commands, but we want to be thorough. 
107559
 
+ */
107560
 
+
107561
 
+/*
107562
 
+ * Lexer errors
107563
 
+ */
107564
 
+
107565
 
+test "Lexer errors (FIXME: count only)" {
107566
 
+    if test_script_compile "errors/lexer.sieve" {
107567
 
+        test_fail "compile should have failed.";
107568
 
+    }
107569
 
+
107570
 
+    if not test_error :count "eq" :comparator "i;ascii-numeric" "10" {
107571
 
+        test_fail "wrong number of errors reported";
107572
 
+    }
107573
 
+}
107574
 
+
107575
 
+/*
107576
 
+ * Parser errors
107577
 
+ */
107578
 
+
107579
 
+test "Parser errors (FIXME: count only)" {
107580
 
+    if test_script_compile "errors/parser.sieve" {
107581
 
+        test_fail "compile should have failed.";
107582
 
+    }
107583
 
+
107584
 
+    if not test_error :count "eq" :comparator "i;ascii-numeric" "9" {
107585
 
+        test_fail "wrong number of errors reported";
107586
 
+    }
107587
 
+}
107588
 
+
107589
 
+/*
107590
 
+ * Header test
107591
 
+ */
107592
 
+
107593
 
+test "Header errors" {
107594
 
+       if test_script_compile "errors/header.sieve" {
107595
 
+               test_fail "compile should have failed.";
107596
 
+       }
107597
 
+
107598
 
+       if not test_error :count "eq" :comparator "i;ascii-numeric" "10" {
107599
 
+               test_fail "wrong number of errors reported";
107600
 
+       }
107601
 
+
107602
 
+       if not test_error :index 1 :matches 
107603
 
+               "unknown * ':all' for * header test *" {
107604
 
+               test_fail "error 1 is invalid";
107605
 
+       }
107606
 
+
107607
 
+       if not test_error :index 2 :matches 
107608
 
+               "*header test * string list * 1 (header names), but * number *" {
107609
 
+               test_fail "error 2 is invalid";
107610
 
+       }
107611
 
+
107612
 
+       if not test_error :index 3 :matches
107613
 
+               "*header test * string list * 2 (key list), * number *" {
107614
 
+               test_fail "error 3 is invalid";
107615
 
+       }
107616
 
+
107617
 
+       if not test_error :index 4 :matches 
107618
 
+               "* unexpected tagged argument ':tag' while *" {
107619
 
+               test_fail "error 4 is invalid";
107620
 
+       }
107621
 
+
107622
 
+       if not test_error :index 5 :matches 
107623
 
+               "* header test requires 2 *, but 1 *" {
107624
 
+               test_fail "error 5 is invalid";
107625
 
+       }
107626
 
+
107627
 
+       if not test_error :index 6 :matches 
107628
 
+               "* header test requires 2 *, but 0 *" {
107629
 
+               test_fail "error 6 is invalid";
107630
 
+       }
107631
 
+
107632
 
+       if not test_error :index 7 :matches 
107633
 
+               "*header test accepts no sub-tests* specified*" {
107634
 
+               test_fail "error 7 is invalid";
107635
 
+       }
107636
 
+
107637
 
+       if not test_error :index 8 :matches 
107638
 
+               "* use test 'header' * command*" {
107639
 
+               test_fail "error 8 is invalid";
107640
 
+       }
107641
 
+
107642
 
+       if not test_error :index 9 :matches 
107643
 
+               "* use test 'header' * command*" {
107644
 
+               test_fail "error 9 is invalid";
107645
 
+       }
107646
 
+
107647
 
+       if test_error :index 4 :contains "radish" {
107648
 
+               test_fail "error test matched nonsense";
107649
 
+       }
107650
 
+}      
107651
 
+
107652
 
+/*
107653
 
+ * Address test
107654
 
+ */
107655
 
+
107656
 
+
107657
 
+test "Address errors" {
107658
 
+       if test_script_compile "errors/address.sieve" {
107659
 
+               test_fail "compile should have failed.";
107660
 
+       }
107661
 
+
107662
 
+       if not test_error :count "eq" :comparator "i;ascii-numeric" "9" {
107663
 
+               test_fail "wrong number of errors reported";
107664
 
+       }       
107665
 
+
107666
 
+       if not test_error :index 1 :matches
107667
 
+               "*unknown * ':nonsense' * address test*" {
107668
 
+               test_fail "error 1 is invalid";
107669
 
+       }
107670
 
+
107671
 
+       if not test_error :index 2 :matches
107672
 
+               "*address test expects *string list * 1 (header list),* number * found*" {
107673
 
+               test_fail "error 2 is invalid";
107674
 
+       }
107675
 
+
107676
 
+       if not test_error :index 3 :matches
107677
 
+               "*address test expects *string list * 2 (key list),* number * found*" {
107678
 
+               test_fail "error 3 is invalid";
107679
 
+       }
107680
 
+
107681
 
+       if not test_error :index 4 :matches
107682
 
+               "*unexpected *':is' * address test*" {
107683
 
+               test_fail "error 4 is invalid";
107684
 
+       }
107685
 
+
107686
 
+       if not test_error :index 5 :matches
107687
 
+               "*address test * 2 positional arg*, but 1*" {
107688
 
+               test_fail "error 5 is invalid";
107689
 
+       }
107690
 
+
107691
 
+       if not test_error :index 6 :matches
107692
 
+               "*address test * 2 positional arg*, but 0*" {
107693
 
+               test_fail "error 6 is invalid";
107694
 
+       }
107695
 
+
107696
 
+       if not test_error :index 7 :matches
107697
 
+               "*'frop' *not allowed *address test*" {
107698
 
+               test_fail "error 7 is invalid";
107699
 
+       }
107700
 
+
107701
 
+       if not test_error :index 8 :matches
107702
 
+               "*'frop' *not allowed *address test*" {
107703
 
+               test_fail "error 8 is invalid";
107704
 
+       }
107705
 
+
107706
 
+       if test_error :index 23 :contains "radish" {
107707
 
+               test_fail "error test matched nonsense";
107708
 
+       }
107709
 
+}
107710
 
+
107711
 
+/*
107712
 
+ * If command
107713
 
+ */
107714
 
+
107715
 
+test "If errors (FIXME: count only)" {
107716
 
+       if test_script_compile "errors/if.sieve" {
107717
 
+               test_fail "compile should have failed.";
107718
 
+       }
107719
 
+
107720
 
+       if not test_error :count "eq" :comparator "i;ascii-numeric" "12" {
107721
 
+               test_fail "wrong number of errors reported";
107722
 
+       }       
107723
 
+}
107724
 
+
107725
 
+/*
107726
 
+ * Require command
107727
 
+ */
107728
 
+
107729
 
+test "Require errors (FIXME: count only)" {
107730
 
+       if test_script_compile "errors/require.sieve" {
107731
 
+               test_fail "compile should have failed.";
107732
 
+       }
107733
 
+
107734
 
+       if not test_error :count "eq" :comparator "i;ascii-numeric" "15" {
107735
 
+               test_fail "wrong number of errors reported";
107736
 
+       }       
107737
 
+}
107738
 
+
107739
 
+/*
107740
 
+ * Size test
107741
 
+ */
107742
 
+
107743
 
+test "Size errors (FIXME: count only)" {
107744
 
+    if test_script_compile "errors/size.sieve" {
107745
 
+        test_fail "compile should have failed.";
107746
 
+    }
107747
 
+
107748
 
+    if not test_error :count "eq" :comparator "i;ascii-numeric" "7" {
107749
 
+        test_fail "wrong number of errors reported";
107750
 
+    }
107751
 
+}
107752
 
+
107753
 
+/*
107754
 
+ * Envelope test
107755
 
+ */
107756
 
+
107757
 
+test "Envelope errors (FIXME: count only)" {
107758
 
+    if test_script_compile "errors/envelope.sieve" {
107759
 
+        test_fail "compile should have failed.";
107760
 
+    }
107761
 
+
107762
 
+    if not test_error :count "eq" :comparator "i;ascii-numeric" "3" {
107763
 
+        test_fail "wrong number of errors reported";
107764
 
+    }
107765
 
+}
107766
 
+
107767
 
+/*
107768
 
+ * Stop command
107769
 
+ */
107770
 
+
107771
 
+test "Stop errors (FIXME: count only)" {
107772
 
+    if test_script_compile "errors/stop.sieve" {
107773
 
+        test_fail "compile should have failed.";
107774
 
+    }
107775
 
+
107776
 
+    if not test_error :count "eq" :comparator "i;ascii-numeric" "9" {
107777
 
+        test_fail "wrong number of errors reported";
107778
 
+    }
107779
 
+}
107780
 
+
107781
 
+/*
107782
 
+ * Keep command
107783
 
+ */
107784
 
+
107785
 
+test "Keep errors (FIXME: count only)" {
107786
 
+    if test_script_compile "errors/keep.sieve" {
107787
 
+        test_fail "compile should have failed.";
107788
 
+    }
107789
 
+
107790
 
+    if not test_error :count "eq" :comparator "i;ascii-numeric" "3" {
107791
 
+        test_fail "wrong number of errors reported";
107792
 
+    }
107793
 
+}
107794
 
+
107795
 
+/*
107796
 
+ * ADDRESS-PART errors
107797
 
+ */
107798
 
+
107799
 
+test "ADDRESS-PART errors (FIXME: count only)" {
107800
 
+    if test_script_compile "errors/address-part.sieve" {
107801
 
+        test_fail "compile should have failed.";
107802
 
+    }
107803
 
+
107804
 
+    if not test_error :count "eq" :comparator "i;ascii-numeric" "3" {
107805
 
+        test_fail "wrong number of errors reported";
107806
 
+    }
107807
 
+}
107808
 
+
107809
 
+/*
107810
 
+ * MATCH-TYPE errors
107811
 
+ */
107812
 
+
107813
 
+test "MATCH-TYPE errors (FIXME: count only)" {
107814
 
+    if test_script_compile "errors/match-type.sieve" {
107815
 
+        test_fail "compile should have failed.";
107816
 
+    }
107817
 
+
107818
 
+    if not test_error :count "eq" :comparator "i;ascii-numeric" "2" {
107819
 
+        test_fail "wrong number of errors reported";
107820
 
+    }
107821
 
+}
107822
 
+
107823
 
+/*
107824
 
+ * Encoded-character errors
107825
 
+ */
107826
 
+
107827
 
+test "Encoded-character errors (FIXME: count only)" {
107828
 
+    if test_script_compile "errors/encoded-character.sieve" {
107829
 
+        test_fail "compile should have failed.";
107830
 
+    }
107831
 
+
107832
 
+    if not test_error :count "eq" :comparator "i;ascii-numeric" "3" {
107833
 
+        test_fail "wrong number of errors reported";
107834
 
+    }
107835
 
+}
107836
 
+
107837
 
+/*
107838
 
+ * Outgoing address errors
107839
 
+ */
107840
 
+
107841
 
+test "Outgoing address errors (FIXME: count only)" {
107842
 
+    if test_script_compile "errors/out-address.sieve" {
107843
 
+        test_fail "compile should have failed.";
107844
 
+    }
107845
 
+
107846
 
+    if not test_error :count "eq" :comparator "i;ascii-numeric" "15" {
107847
 
+        test_fail "wrong number of errors reported";
107848
 
+    }
107849
 
+}
107850
 
+
107851
 
+
107852
 
+/*
107853
 
+ * Tagged argument errors
107854
 
+ */
107855
 
+
107856
 
+test "Tagged argument errors (FIXME: count only)" {
107857
 
+    if test_script_compile "errors/tag.sieve" {
107858
 
+        test_fail "compile should have failed.";
107859
 
+    }
107860
 
+
107861
 
+    if not test_error :count "eq" :comparator "i;ascii-numeric" "3" {
107862
 
+        test_fail "wrong number of errors reported";
107863
 
+    }
107864
 
+}
107865
 
+
107866
 
+/*
107867
 
+ * Typos
107868
 
+ */
107869
 
+
107870
 
+test "Typos" {
107871
 
+       if test_script_compile "errors/typos.sieve" {
107872
 
+               test_fail "compile should have failed.";
107873
 
+       }
107874
 
+
107875
 
+       if not test_error :count "eq" :comparator "i;ascii-numeric" "6" {
107876
 
+               test_fail "wrong number of errors reported";
107877
 
+       }
107878
 
+
107879
 
+       if not test_error :index 1 :matches
107880
 
+               "missing semicolon * fileinto *" {
107881
 
+               test_fail "error 1 is invalid";
107882
 
+       }
107883
 
+
107884
 
+       if not test_error :index 2 :matches
107885
 
+               "*fileinto command * no *tests* specified*" {
107886
 
+               test_fail "error 2 is invalid";
107887
 
+       }
107888
 
+
107889
 
+       if not test_error :index 3 :matches
107890
 
+               "missing semicolon * fileinto *" {
107891
 
+               test_fail "error 3 is invalid";
107892
 
+       }
107893
 
+
107894
 
+       if not test_error :index 4 :matches
107895
 
+               "*address test requires 2 * 0 * specified" {
107896
 
+               test_fail "error 4 is invalid";
107897
 
+       }
107898
 
+
107899
 
+       if not test_error :index 5 :matches
107900
 
+               "missing colon *matches* tag * address test" {
107901
 
+               test_fail "error 5 is invalid";
107902
 
+       }
107903
 
+}
107904
 
+
107905
 
+
107906
 
+/*
107907
 
+ * Unsupported language features
107908
 
+ */
107909
 
+
107910
 
+test "Unsupported language features (FIXME: count only)" {
107911
 
+    if test_script_compile "errors/unsupported.sieve" {
107912
 
+        test_fail "compile should have failed.";
107913
 
+    }
107914
 
+
107915
 
+    if not test_error :count "eq" :comparator "i;ascii-numeric" "4" {
107916
 
+        test_fail "wrong number of errors reported";
107917
 
+    }
107918
 
+}
107919
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/compile/redirect.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/compile/redirect.sieve
107920
 
--- dovecot-1.2.4/dovecot-libsieve/tests/compile/redirect.sieve 1970-01-01 01:00:00.000000000 +0100
107921
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/compile/redirect.sieve  2008-07-30 15:17:37.000000000 +0200
107922
 
@@ -0,0 +1,23 @@
107923
 
+# Test various white space occurences
107924
 
+redirect "stephan@rename-it.nl";
107925
 
+redirect " stephan@rename-it.nl";
107926
 
+redirect "stephan @rename-it.nl";
107927
 
+redirect "stephan@ rename-it.nl";
107928
 
+redirect "stephan@rename-it.nl ";
107929
 
+redirect " stephan @ rename-it.nl ";
107930
 
+redirect "Stephan Bosch<stephan@rename-it.nl>";
107931
 
+redirect " Stephan Bosch<stephan@rename-it.nl>";
107932
 
+redirect "Stephan Bosch <stephan@rename-it.nl>";
107933
 
+redirect "Stephan Bosch< stephan@rename-it.nl>";
107934
 
+redirect "Stephan Bosch<stephan @rename-it.nl>";
107935
 
+redirect "Stephan Bosch<stephan@ rename-it.nl>";
107936
 
+redirect "Stephan Bosch<stephan@rename-it.nl >";
107937
 
+redirect "Stephan Bosch<stephan@rename-it.nl> ";
107938
 
+redirect "  Stephan Bosch  <  stephan  @  rename-it.nl  > ";
107939
 
+
107940
 
+# Test address syntax
107941
 
+redirect "\"Stephan Bosch\"@rename-it.nl";
107942
 
+redirect "Stephan.Bosch@rename-it.nl";
107943
 
+redirect "Stephan.Bosch@ReNaMe-It.Nl";
107944
 
+redirect "Stephan Bosch <stephan@rename-it.nl>";
107945
 
+
107946
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/compile/trivial.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/compile/trivial.sieve
107947
 
--- dovecot-1.2.4/dovecot-libsieve/tests/compile/trivial.sieve  1970-01-01 01:00:00.000000000 +0100
107948
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/compile/trivial.sieve   2008-08-04 10:39:20.000000000 +0200
107949
 
@@ -0,0 +1,17 @@
107950
 
+# Commands must be case-insensitive
107951
 
+keep;
107952
 
+Keep;
107953
 
+KEEP;
107954
 
+discard;
107955
 
+DisCaRD;
107956
 
+
107957
 
+# Tags must be case-insensitive
107958
 
+if size :UNDER 34 {
107959
 
+}
107960
 
+
107961
 
+if header :Is "from" "tukker@rename-it.n" {
107962
 
+}
107963
 
+
107964
 
+# Numbers must be case-insensitive
107965
 
+if anyof( size :UNDER 34m, size :oVeR 50M ) {
107966
 
+}
107967
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/compile/warnings/invalid-headers.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/compile/warnings/invalid-headers.sieve
107968
 
--- dovecot-1.2.4/dovecot-libsieve/tests/compile/warnings/invalid-headers.sieve 1970-01-01 01:00:00.000000000 +0100
107969
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/compile/warnings/invalid-headers.sieve  2008-12-09 19:02:55.000000000 +0100
107970
 
@@ -0,0 +1,11 @@
107971
 
+if header "from:" "frop@rename-it.nl" {
107972
 
+       stop;
107973
 
+}
107974
 
+
107975
 
+if address "from:" "frop@rename-it.nl" {
107976
 
+       stop;
107977
 
+}
107978
 
+
107979
 
+if exists "from:" {
107980
 
+       stop;
107981
 
+}
107982
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/control-structures.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/control-structures.svtest
107983
 
--- dovecot-1.2.4/dovecot-libsieve/tests/control-structures.svtest      1970-01-01 01:00:00.000000000 +0100
107984
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/control-structures.svtest       2008-07-30 15:17:37.000000000 +0200
107985
 
@@ -0,0 +1,149 @@
107986
 
+require "vnd.dovecot.testsuite";
107987
 
+
107988
 
+test_set "message" text:
107989
 
+From: stephan@rename-it.nl
107990
 
+To: test@dovecot.org
107991
 
+Subject: Test
107992
 
+
107993
 
+Test!
107994
 
+.
107995
 
+;
107996
 
+
107997
 
+test "IF-true" {
107998
 
+       if true {
107999
 
+       } else {
108000
 
+               test_fail "executed wrong alternative";
108001
 
+       }
108002
 
+}
108003
 
+
108004
 
+test "IF-false" {
108005
 
+       if false {
108006
 
+               test_fail "executed wrong alternative";
108007
 
+       }
108008
 
+}
108009
 
+
108010
 
+test "ELSEIF-true" {
108011
 
+       if false {
108012
 
+               test_fail "executed wrong alternative (if)";
108013
 
+       } elsif true {
108014
 
+       } else {
108015
 
+               test_fail "executed wrong alternative (else)";  
108016
 
+       }
108017
 
+}
108018
 
+
108019
 
+test "ELSEIF-false" {
108020
 
+       if false {
108021
 
+               test_fail "executed wrong alternative (if)";
108022
 
+       } elsif false {
108023
 
+               test_fail "executed wrong alternative (elsif)"; 
108024
 
+       } else {
108025
 
+       }
108026
 
+}
108027
 
+
108028
 
+test "IF-address-true" {
108029
 
+       if address :is "from" "stephan@rename-it.nl" {
108030
 
+       } else {
108031
 
+               test_fail "executed wrong alternative";
108032
 
+       }
108033
 
+}
108034
 
+
108035
 
+test "IF-address-false" {
108036
 
+       if address :is "from" "tss@iki.fi" {
108037
 
+               test_fail "executed wrong alternative";
108038
 
+       }
108039
 
+}
108040
 
+
108041
 
+test "ELSEIF-address-true" {
108042
 
+       if address :is "from" "tss@iki.fi" {
108043
 
+               test_fail "executed wrong alternative (if)";
108044
 
+       } elsif address :is "from" "stephan@rename-it.nl" {
108045
 
+       } else {
108046
 
+               test_fail "executed wrong alternative (else)";  
108047
 
+       }
108048
 
+}
108049
 
+
108050
 
+test "ELSEIF-address-false" {
108051
 
+       if address :is "from" "tss@iki.fi" {
108052
 
+               test_fail "executed wrong alternative (if)";
108053
 
+       } elsif address :is "to" "stephan@rename-it.nl" {
108054
 
+               test_fail "executed wrong alternative (elsif)"; 
108055
 
+       } else {
108056
 
+       }
108057
 
+}
108058
 
+
108059
 
+test "IF-nesting-static" {
108060
 
+       if true {
108061
 
+               if true {
108062
 
+                       if false {
108063
 
+                               test_fail "chose wrong outcome: true->true->false";
108064
 
+                       } else {
108065
 
+                       }
108066
 
+               } else {
108067
 
+                       test_fail "chose wrong outcome: true->false";
108068
 
+               }
108069
 
+       } elsif true {
108070
 
+               if false {
108071
 
+                       test_fail "chose wrong outcome: false->true->false";    
108072
 
+               } elsif true {
108073
 
+                       test_fail "chose wrong outcome: false->true->true";
108074
 
+               }
108075
 
+       } else {
108076
 
+               test_fail "chose wrong outcome: false->false";
108077
 
+       }
108078
 
+}
108079
 
+
108080
 
+test "ALLOF-ANYOF-static" {
108081
 
+       if allof ( true, true, true, true, anyof (false, false, true, false) ) {
108082
 
+               if anyof( allof(false, false), allof(false, true), allof(true, false) ) {
108083
 
+                       test_fail "chose wrong outcome: true->true";
108084
 
+               } elsif allof( anyof(false, true), true, anyof(true, false), anyof(true, true)) {
108085
 
+                       
108086
 
+               } else {
108087
 
+                       test_fail "chose wrong outcome: true->false->false";                    
108088
 
+               }
108089
 
+       } else {
108090
 
+               test_fail "chose wrong outcome: false";
108091
 
+       }
108092
 
+}
108093
 
+
108094
 
+test "ALLOF-ANYOF-single" {
108095
 
+       # Static 
108096
 
+       if not allof ( true ) {
108097
 
+               test_fail "allof ( true ) evaluates to false";
108098
 
+       }
108099
 
+
108100
 
+       if allof ( false ) {
108101
 
+               test_fail "allof ( false ) evaluates to true";
108102
 
+       }
108103
 
+
108104
 
+       if not anyof ( true ) {
108105
 
+               test_fail "anyof ( true ) evaluates to false";
108106
 
+       }
108107
 
+
108108
 
+       if anyof ( false ) {
108109
 
+               test_fail "anyof ( false ) evaluates to true";
108110
 
+       }       
108111
 
+
108112
 
+       # Dynamic
108113
 
+       if not allof ( exists "subject" ) {
108114
 
+        test_fail "allof ( 'true' ) evaluates to false";
108115
 
+    }
108116
 
+
108117
 
+    if allof ( exists "x-nonsense" ) {
108118
 
+        test_fail "allof ( 'false' ) evaluates to true";
108119
 
+    }
108120
 
+
108121
 
+    if not anyof ( exists "subject" ) {
108122
 
+        test_fail "anyof ( 'true' ) evaluates to false";
108123
 
+    }
108124
 
+
108125
 
+    if anyof ( exists "x-nonsense" ) {
108126
 
+        test_fail "anyof ( 'false' ) evaluates to true";
108127
 
+    }
108128
 
+}
108129
 
+
108130
 
+test "STOP" {
108131
 
+       stop;
108132
 
+       test_fail "continued after stop";
108133
 
+}
108134
 
+
108135
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/deprecated/notify/basic.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/deprecated/notify/basic.svtest
108136
 
--- dovecot-1.2.4/dovecot-libsieve/tests/deprecated/notify/basic.svtest 1970-01-01 01:00:00.000000000 +0100
108137
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/deprecated/notify/basic.svtest  2009-07-19 15:54:39.000000000 +0200
108138
 
@@ -0,0 +1,11 @@
108139
 
+require "vnd.dovecot.testsuite";
108140
 
+require "notify";
108141
 
+
108142
 
+test "Execute" {
108143
 
+       /* Test to catch runtime segfaults */
108144
 
+       notify 
108145
 
+               :message "This is probably very important"
108146
 
+               :low
108147
 
+               :method "mailto" 
108148
 
+               :options ["stephan@example.com", "stephan@rename-it.nl"];
108149
 
+}
108150
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/deprecated/notify/errors/options.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/deprecated/notify/errors/options.sieve
108151
 
--- dovecot-1.2.4/dovecot-libsieve/tests/deprecated/notify/errors/options.sieve 1970-01-01 01:00:00.000000000 +0100
108152
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/deprecated/notify/errors/options.sieve  2009-07-19 15:54:39.000000000 +0200
108153
 
@@ -0,0 +1,11 @@
108154
 
+require "notify";
108155
 
+
108156
 
+# 1: empty option
108157
 
+notify :options "";
108158
 
+
108159
 
+# 2: invalid address syntax
108160
 
+notify :options "frop#vestingbar.nl";
108161
 
+
108162
 
+# Valid
108163
 
+notify :options "frop@vestingbar.nl";
108164
 
+
108165
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/deprecated/notify/errors.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/deprecated/notify/errors.svtest
108166
 
--- dovecot-1.2.4/dovecot-libsieve/tests/deprecated/notify/errors.svtest        1970-01-01 01:00:00.000000000 +0100
108167
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/deprecated/notify/errors.svtest 2009-07-19 15:54:39.000000000 +0200
108168
 
@@ -0,0 +1,13 @@
108169
 
+require "vnd.dovecot.testsuite";
108170
 
+require "comparator-i;ascii-numeric";
108171
 
+require "relational";
108172
 
+
108173
 
+test "Invalid :options argument (FIXME: count only)" {
108174
 
+       if test_script_compile "errors/options.sieve" {
108175
 
+               test_fail "compile should have failed";
108176
 
+       }
108177
 
+
108178
 
+       if not test_error :count "eq" :comparator "i;ascii-numeric" "3" {
108179
 
+               test_fail "wrong number of errors reported";
108180
 
+       }
108181
 
+}
108182
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/deprecated/notify/execute/duplicates.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/deprecated/notify/execute/duplicates.sieve
108183
 
--- dovecot-1.2.4/dovecot-libsieve/tests/deprecated/notify/execute/duplicates.sieve     1970-01-01 01:00:00.000000000 +0100
108184
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/deprecated/notify/execute/duplicates.sieve      2009-07-19 15:54:39.000000000 +0200
108185
 
@@ -0,0 +1,4 @@
108186
 
+require "notify";
108187
 
+
108188
 
+notify :message "Incoming stupidity." :options ["stephan@rename-it.nl", "stephan@drunksnipers.com", "idiot@rename-it.nl"];
108189
 
+notify :message "There it is." :options ["tss@iki.fi", "stephan@rename-it.nl", "idiot@rename-it.nl", "nico@vestingbar.nl", "stephan@drunksnipers.com"];
108190
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/deprecated/notify/execute.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/deprecated/notify/execute.svtest
108191
 
--- dovecot-1.2.4/dovecot-libsieve/tests/deprecated/notify/execute.svtest       1970-01-01 01:00:00.000000000 +0100
108192
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/deprecated/notify/execute.svtest        2009-07-19 15:54:39.000000000 +0200
108193
 
@@ -0,0 +1,25 @@
108194
 
+require "vnd.dovecot.testsuite";
108195
 
+require "relational";
108196
 
+
108197
 
+
108198
 
+/*
108199
 
+ * Execution testing (currently just meant to trigger any segfaults)
108200
 
+ */
108201
 
+
108202
 
+test "Duplicate recipients" {
108203
 
+       if not test_script_compile "execute/duplicates.sieve" {
108204
 
+               test_fail "script compile failed";
108205
 
+       }
108206
 
+
108207
 
+       if not test_script_run {
108208
 
+               test_fail "script execute failed";
108209
 
+       }
108210
 
+
108211
 
+       if test_result :count "ne" "2" {
108212
 
+               test_fail "second notify action was discarded entirely";
108213
 
+       }
108214
 
+
108215
 
+       if not test_result_execute {
108216
 
+               test_fail "result execute failed";
108217
 
+       }
108218
 
+}
108219
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/deprecated/notify/mailto.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/deprecated/notify/mailto.svtest
108220
 
--- dovecot-1.2.4/dovecot-libsieve/tests/deprecated/notify/mailto.svtest        1970-01-01 01:00:00.000000000 +0100
108221
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/deprecated/notify/mailto.svtest 2009-07-19 15:54:39.000000000 +0200
108222
 
@@ -0,0 +1,155 @@
108223
 
+require "vnd.dovecot.testsuite";
108224
 
+require "notify";
108225
 
+require "relational";
108226
 
+require "comparator-i;ascii-numeric";
108227
 
+
108228
 
+/*
108229
 
+ * Simple test
108230
 
+ */
108231
 
+
108232
 
+test_set "message" text:
108233
 
+From: stephan@rename-it.nl
108234
 
+To: nico@vestingbar.nl
108235
 
+Subject: Frop!
108236
 
+
108237
 
+Klutsefluts.
108238
 
+.
108239
 
+;
108240
 
+
108241
 
+test "Simple" {
108242
 
+       notify :method "mailto" :options "stephan@rename-it.nl";
108243
 
+
108244
 
+       if not test_result_execute {
108245
 
+               test_fail "failed to execute notify";
108246
 
+       }
108247
 
+
108248
 
+       test_message :smtp 0;
108249
 
+
108250
 
+       if not header :matches "Auto-Submitted" "auto-generated*" {
108251
 
+               test_fail "auto-submitted header set inappropriately";
108252
 
+       }
108253
 
+
108254
 
+       if not exists "X-Sieve" {
108255
 
+               test_fail "x-sieve header missing from outgoing message";
108256
 
+       }
108257
 
+}
108258
 
+
108259
 
+/*
108260
 
+ * Multiple recipients
108261
 
+ */
108262
 
+
108263
 
+test_result_reset;
108264
 
+
108265
 
+test_set "message" text:
108266
 
+From: stephan@rename-it.nl
108267
 
+To: nico@vestingbar.nl
108268
 
+Subject: Frop!
108269
 
+
108270
 
+Klutsefluts.
108271
 
+.
108272
 
+;
108273
 
+
108274
 
+test "Multiple recipients" {
108275
 
+       notify :options ["timo@example.com","stephan@dovecot.org","postmaster@vestingbar.nl"];
108276
 
+
108277
 
+       if not test_result_execute {
108278
 
+               test_fail "failed to execute notify";
108279
 
+       }
108280
 
+
108281
 
+       test_message :smtp 0;
108282
 
+
108283
 
+       if not address :is "to" "timo@example.com" {
108284
 
+               test_fail "first To address missing";
108285
 
+       }
108286
 
+
108287
 
+       test_message :smtp 1;
108288
 
+
108289
 
+       if not address :is "to" "stephan@dovecot.org" {
108290
 
+               test_fail "second To address missing";
108291
 
+       }
108292
 
+
108293
 
+       if not header :matches "Auto-Submitted" "auto-generated*" {
108294
 
+               test_fail "auto-submitted header not found for second message";
108295
 
+       }
108296
 
+
108297
 
+       test_message :smtp 2;
108298
 
+
108299
 
+       if not address :is "to" "postmaster@vestingbar.nl" {
108300
 
+               test_fail "third To address missing";
108301
 
+       }
108302
 
+
108303
 
+       if not header :matches "Auto-Submitted" "auto-generated*" {
108304
 
+               test_fail "auto-submitted header not found for third message";
108305
 
+       }
108306
 
+
108307
 
+       if not address :count "eq" :comparator "i;ascii-numeric" "to" "1" {
108308
 
+               test_fail "too many recipients in To header";
108309
 
+       } 
108310
 
+
108311
 
+       if not address :count "eq" :comparator "i;ascii-numeric" "cc" "0" {
108312
 
+               test_fail "too many recipients in Cc header";
108313
 
+       } 
108314
 
+}
108315
 
+
108316
 
+/*
108317
 
+ * Duplicate recipients
108318
 
+ */
108319
 
+
108320
 
+test_result_reset;
108321
 
+
108322
 
+test_set "message" text:
108323
 
+From: stephan@rename-it.nl
108324
 
+To: nico@vestingbar.nl
108325
 
+Subject: Frop!
108326
 
+
108327
 
+Klutsefluts.
108328
 
+.
108329
 
+;
108330
 
+
108331
 
+test "Duplicate recipients" {
108332
 
+       notify :options ["timo@example.com", "stephan@dovecot.org", "stephan@dovecot.org"];
108333
 
+       notify :options ["timo@example.com", "stephan@rename-it.nl"];
108334
 
+
108335
 
+       if not test_result_execute {
108336
 
+               test_fail "failed to execute notify";
108337
 
+       }
108338
 
+
108339
 
+       test_message :smtp 2;
108340
 
+
108341
 
+       if address "To" "stephan@dovecot.org" {
108342
 
+               test_fail "duplicate recipient not removed from first message";
108343
 
+       }
108344
 
+
108345
 
+       if address "To" "timo@example.com" {
108346
 
+               test_fail "duplicate recipient not removed from second message";
108347
 
+       }
108348
 
+}
108349
 
+
108350
 
+/*
108351
 
+ * Notifying on automated messages
108352
 
+ */
108353
 
+
108354
 
+test_result_reset;
108355
 
+
108356
 
+test_set "message" text:
108357
 
+From: stephan@rename-it.nl
108358
 
+To: nico@vestingbar.nl
108359
 
+Auto-submitted: auto-notify
108360
 
+Subject: Frop!
108361
 
+
108362
 
+Klutsefluts.
108363
 
+.
108364
 
+;
108365
 
+
108366
 
+test "Notifying on automated messages" {
108367
 
+       notify :options "stephan@rename-it.nl";
108368
 
+
108369
 
+       if not test_result_execute {
108370
 
+               test_fail "failed to execute notify";
108371
 
+       }
108372
 
+
108373
 
+       if test_message :smtp 0 {
108374
 
+               test_fail "notified of auto-submitted message";
108375
 
+       }
108376
 
+}
108377
 
+
108378
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/execute/actions/fileinto.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/execute/actions/fileinto.sieve
108379
 
--- dovecot-1.2.4/dovecot-libsieve/tests/execute/actions/fileinto.sieve 1970-01-01 01:00:00.000000000 +0100
108380
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/execute/actions/fileinto.sieve  2008-10-20 01:35:49.000000000 +0200
108381
 
@@ -0,0 +1,17 @@
108382
 
+require "fileinto";
108383
 
+
108384
 
+/* Three store actions */
108385
 
+
108386
 
+if address :contains "to" "vestingbar" {
108387
 
+       /* #1 */
108388
 
+       fileinto "INBOX.VB";
108389
 
+}
108390
 
+
108391
 
+/* #2 */
108392
 
+fileinto "INBOX.backup";
108393
 
+
108394
 
+/* #3 */
108395
 
+keep;
108396
 
+
108397
 
+/* Duplicate of keep */
108398
 
+fileinto "INBOX";
108399
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/execute/actions/redirect.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/execute/actions/redirect.sieve
108400
 
--- dovecot-1.2.4/dovecot-libsieve/tests/execute/actions/redirect.sieve 1970-01-01 01:00:00.000000000 +0100
108401
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/execute/actions/redirect.sieve  2008-10-20 01:35:49.000000000 +0200
108402
 
@@ -0,0 +1,17 @@
108403
 
+if address :contains "to" "vestingbar" {
108404
 
+       /* #1 */
108405
 
+       redirect "stephan@example.com";
108406
 
+       
108407
 
+       /* #2 */
108408
 
+       keep;
108409
 
+}
108410
 
+
108411
 
+/* #3 */
108412
 
+redirect "stephan@rename-it.nl";
108413
 
+
108414
 
+/* #4 */
108415
 
+redirect "nico@example.nl";
108416
 
+
108417
 
+/* Duplicates */
108418
 
+redirect "Stephan Bosch <stephan@example.com>";
108419
 
+keep;
108420
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/execute/actions.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/execute/actions.svtest
108421
 
--- dovecot-1.2.4/dovecot-libsieve/tests/execute/actions.svtest 1970-01-01 01:00:00.000000000 +0100
108422
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/execute/actions.svtest  2009-07-31 17:34:58.000000000 +0200
108423
 
@@ -0,0 +1,80 @@
108424
 
+require "vnd.dovecot.testsuite";
108425
 
+require "relational";
108426
 
+require "comparator-i;ascii-numeric";
108427
 
+
108428
 
+test_set "message" text:
108429
 
+To: nico@vestingbar.nl
108430
 
+From: stephan@rename-it.nl
108431
 
+Subject: Test
108432
 
+
108433
 
+Test.
108434
 
+.
108435
 
+;
108436
 
+
108437
 
+test_mailbox :create "INBOX.VB";
108438
 
+test_mailbox :create "INBOX.backup";
108439
 
+
108440
 
+test "Fileinto" {
108441
 
+       if not test_script_compile "actions/fileinto.sieve" {
108442
 
+               test_fail "script compile failed";
108443
 
+       }
108444
 
+
108445
 
+       if not test_script_run {
108446
 
+               test_fail "script run failed";
108447
 
+       }
108448
 
+
108449
 
+       if not test_result :count "eq" :comparator "i;ascii-numeric" "3" {
108450
 
+               test_fail "wrong number of actions in result";
108451
 
+       } 
108452
 
+
108453
 
+       if not test_result :index 1 "store" {
108454
 
+               test_fail "first action is not 'store'";
108455
 
+       } 
108456
 
+
108457
 
+       if not test_result :index 2 "store" {
108458
 
+               test_fail "second action is not 'store'";
108459
 
+       } 
108460
 
+
108461
 
+       if not test_result :index 3 "keep" {
108462
 
+               test_fail "third action is not 'keep'";
108463
 
+       } 
108464
 
+
108465
 
+       if not test_result_execute {
108466
 
+               test_fail "result execute failed";
108467
 
+       }
108468
 
+}
108469
 
+
108470
 
+test "Redirect" {
108471
 
+       if not test_script_compile "actions/redirect.sieve" {
108472
 
+               test_fail "compile failed";
108473
 
+       }
108474
 
+
108475
 
+       if not test_script_run {
108476
 
+               test_fail "execute failed";
108477
 
+       }
108478
 
+
108479
 
+       if not test_result :count "eq" :comparator "i;ascii-numeric" "4" {
108480
 
+               test_fail "wrong number of actions in result";
108481
 
+       } 
108482
 
+
108483
 
+       if not test_result :index 1 "redirect" {
108484
 
+               test_fail "first action is not 'redirect'";
108485
 
+       } 
108486
 
+
108487
 
+       if not test_result :index 2 "keep" {
108488
 
+               test_fail "second action is not 'keep'";
108489
 
+       } 
108490
 
+
108491
 
+       if not test_result :index 3 "redirect" {
108492
 
+               test_fail "third action is not 'redirect'";
108493
 
+       } 
108494
 
+
108495
 
+       if not test_result :index 4 "redirect" {
108496
 
+               test_fail "fourth action is not 'redirect'";
108497
 
+       } 
108498
 
+
108499
 
+       if not test_result_execute {
108500
 
+               test_fail "result execute failed";
108501
 
+       }
108502
 
+}
108503
 
+
108504
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/execute/errors/action-duplicates.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/execute/errors/action-duplicates.sieve
108505
 
--- dovecot-1.2.4/dovecot-libsieve/tests/execute/errors/action-duplicates.sieve 1970-01-01 01:00:00.000000000 +0100
108506
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/execute/errors/action-duplicates.sieve  2008-08-25 17:35:24.000000000 +0200
108507
 
@@ -0,0 +1,4 @@
108508
 
+require "reject";
108509
 
+
108510
 
+reject "Message is not appreciated.";
108511
 
+reject "No, really, it is not appreciated.";
108512
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/execute/errors/actions-limit.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/execute/errors/actions-limit.sieve
108513
 
--- dovecot-1.2.4/dovecot-libsieve/tests/execute/errors/actions-limit.sieve     1970-01-01 01:00:00.000000000 +0100
108514
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/execute/errors/actions-limit.sieve      2008-09-06 12:59:49.000000000 +0200
108515
 
@@ -0,0 +1,35 @@
108516
 
+require "fileinto";
108517
 
+
108518
 
+fileinto "box1";
108519
 
+fileinto "box2";
108520
 
+fileinto "box3";
108521
 
+fileinto "box4";
108522
 
+fileinto "box5";
108523
 
+fileinto "box6";
108524
 
+fileinto "box7";
108525
 
+fileinto "box8";
108526
 
+fileinto "box9";
108527
 
+fileinto "box10";
108528
 
+fileinto "box11";
108529
 
+fileinto "box12";
108530
 
+fileinto "box13";
108531
 
+fileinto "box14";
108532
 
+fileinto "box15";
108533
 
+fileinto "box16";
108534
 
+fileinto "box17";
108535
 
+fileinto "box18";
108536
 
+fileinto "box19";
108537
 
+fileinto "box20";
108538
 
+fileinto "box21";
108539
 
+fileinto "box22";
108540
 
+fileinto "box23";
108541
 
+fileinto "box24";
108542
 
+fileinto "box25";
108543
 
+fileinto "box26";
108544
 
+fileinto "box27";
108545
 
+fileinto "box28";
108546
 
+redirect "address1@example.com";
108547
 
+redirect "address2@example.com";
108548
 
+redirect "address3@example.com";
108549
 
+redirect "address4@example.com";
108550
 
+keep;
108551
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/execute/errors/conflict-reject-fileinto.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/execute/errors/conflict-reject-fileinto.sieve
108552
 
--- dovecot-1.2.4/dovecot-libsieve/tests/execute/errors/conflict-reject-fileinto.sieve  1970-01-01 01:00:00.000000000 +0100
108553
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/execute/errors/conflict-reject-fileinto.sieve   2008-08-26 15:53:02.000000000 +0200
108554
 
@@ -0,0 +1,5 @@
108555
 
+require "reject";
108556
 
+require "fileinto";
108557
 
+
108558
 
+reject "No nonsense in my mailbox.";
108559
 
+fileinto "Spam";
108560
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/execute/errors/conflict-reject-keep.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/execute/errors/conflict-reject-keep.sieve
108561
 
--- dovecot-1.2.4/dovecot-libsieve/tests/execute/errors/conflict-reject-keep.sieve      1970-01-01 01:00:00.000000000 +0100
108562
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/execute/errors/conflict-reject-keep.sieve       2008-08-26 15:56:33.000000000 +0200
108563
 
@@ -0,0 +1,4 @@
108564
 
+require "reject";
108565
 
+
108566
 
+reject "I am not interested in your nonsense.";
108567
 
+keep;
108568
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/execute/errors/conflict-reject-redirect.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/execute/errors/conflict-reject-redirect.sieve
108569
 
--- dovecot-1.2.4/dovecot-libsieve/tests/execute/errors/conflict-reject-redirect.sieve  1970-01-01 01:00:00.000000000 +0100
108570
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/execute/errors/conflict-reject-redirect.sieve   2008-08-26 15:54:24.000000000 +0200
108571
 
@@ -0,0 +1,4 @@
108572
 
+require "reject";
108573
 
+
108574
 
+reject "I am not interested in your nonsense.";
108575
 
+redirect "frop@example.com";
108576
 
Binary files dovecot-1.2.4/dovecot-libsieve/tests/execute/errors/conflict-reject-redirect.svbin and dovecot-1.2.4.debian/dovecot-libsieve/tests/execute/errors/conflict-reject-redirect.svbin differ
108577
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/execute/errors/redirect-limit.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/execute/errors/redirect-limit.sieve
108578
 
--- dovecot-1.2.4/dovecot-libsieve/tests/execute/errors/redirect-limit.sieve    1970-01-01 01:00:00.000000000 +0100
108579
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/execute/errors/redirect-limit.sieve     2008-09-06 12:59:49.000000000 +0200
108580
 
@@ -0,0 +1,5 @@
108581
 
+redirect "address1@example.com";
108582
 
+redirect "address2@example.com";
108583
 
+redirect "address3@example.com";
108584
 
+redirect "address4@example.com";
108585
 
+redirect "address5@example.com";
108586
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/execute/errors.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/execute/errors.svtest
108587
 
--- dovecot-1.2.4/dovecot-libsieve/tests/execute/errors.svtest  1970-01-01 01:00:00.000000000 +0100
108588
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/execute/errors.svtest   2009-01-06 00:15:52.000000000 +0100
108589
 
@@ -0,0 +1,82 @@
108590
 
+require "vnd.dovecot.testsuite";
108591
 
+
108592
 
+require "relational";
108593
 
+require "comparator-i;ascii-numeric";
108594
 
+
108595
 
+test "Action conflicts: reject <-> fileinto" {
108596
 
+       if not test_script_compile "errors/conflict-reject-fileinto.sieve" {
108597
 
+               test_fail "compile failed";
108598
 
+       }
108599
 
+
108600
 
+       if test_script_run {
108601
 
+               test_fail "execution should have failed";
108602
 
+       }
108603
 
+
108604
 
+       if test_error :count "gt" :comparator "i;ascii-numeric" "1" {
108605
 
+               test_fail "too many runtime errors reported";
108606
 
+       }
108607
 
+}
108608
 
+
108609
 
+test "Action conflicts: reject <-> keep" {
108610
 
+       if not test_script_compile "errors/conflict-reject-keep.sieve" {
108611
 
+               test_fail "compile failed";
108612
 
+       }
108613
 
+
108614
 
+       if test_script_run {
108615
 
+               test_fail "execution should have failed";
108616
 
+       }
108617
 
+
108618
 
+       if test_error :count "gt" :comparator "i;ascii-numeric" "1" {
108619
 
+               test_fail "too many runtime errors reported";
108620
 
+       }
108621
 
+}
108622
 
+
108623
 
+test "Action conflicts: reject <-> redirect" {
108624
 
+       if not test_script_compile "errors/conflict-reject-redirect.sieve" {
108625
 
+               test_fail "compile failed";
108626
 
+       }
108627
 
+
108628
 
+       if test_script_run {
108629
 
+               test_fail "execution should have failed";
108630
 
+       }
108631
 
+
108632
 
+       if test_error :count "gt" :comparator "i;ascii-numeric" "1" {
108633
 
+               test_fail "too many runtime errors reported";
108634
 
+       }
108635
 
+}
108636
 
+
108637
 
+test "Action limit" {
108638
 
+       if not test_script_compile "errors/actions-limit.sieve" {
108639
 
+               test_fail "compile failed";
108640
 
+       }
108641
 
+
108642
 
+       if test_script_run {
108643
 
+               test_fail "execution should have failed";
108644
 
+       }
108645
 
+
108646
 
+       if test_error :count "gt" :comparator "i;ascii-numeric" "1" {
108647
 
+               test_fail "too many runtime errors reported";
108648
 
+       }
108649
 
+       
108650
 
+       if not test_error :index 1 :contains "total number of actions exceeds policy limit"{
108651
 
+               test_fail "unexpected error reported";
108652
 
+       }
108653
 
+}
108654
 
+
108655
 
+test "Redirect limit" {
108656
 
+       if not test_script_compile "errors/redirect-limit.sieve" {
108657
 
+               test_fail "compile failed";
108658
 
+       }
108659
 
+
108660
 
+       if test_script_run {
108661
 
+               test_fail "execution should have failed";
108662
 
+       }
108663
 
+
108664
 
+       if test_error :count "gt" :comparator "i;ascii-numeric" "1" {
108665
 
+               test_fail "too many runtime errors reported";
108666
 
+       }
108667
 
+       
108668
 
+       if not test_error :index 1 :contains "number of redirect actions exceeds policy limit"{
108669
 
+               test_fail "unexpected error reported";
108670
 
+       }
108671
 
+}
108672
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/execute/examples.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/execute/examples.svtest
108673
 
--- dovecot-1.2.4/dovecot-libsieve/tests/execute/examples.svtest        1970-01-01 01:00:00.000000000 +0100
108674
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/execute/examples.svtest 2009-08-21 00:52:15.000000000 +0200
108675
 
@@ -0,0 +1,115 @@
108676
 
+require "vnd.dovecot.testsuite";
108677
 
+
108678
 
+/* Compile and execute all example scripts to trigger 
108679
 
+ * any Segfaults. No message is set and no results are checked.
108680
 
+ */
108681
 
+
108682
 
+test "Elvey example" {
108683
 
+       if not test_script_compile "../../examples/elvey.sieve" {
108684
 
+               test_fail "could not compile";
108685
 
+       }
108686
 
+
108687
 
+       test_binary :save "elvey";
108688
 
+       test_binary :load "elvey";
108689
 
+
108690
 
+       if not test_script_run { }
108691
 
+}
108692
 
+
108693
 
+test "M. Johnson example" {
108694
 
+       if not test_script_compile "../../examples/mjohnson.sieve" {
108695
 
+               test_fail "could not compile";
108696
 
+       }
108697
 
+
108698
 
+       test_binary :save "mjohnson";
108699
 
+       test_binary :load "mjohnson";
108700
 
+
108701
 
+       if not test_script_run { }
108702
 
+}
108703
 
+
108704
 
+test "RFC 3028 example" {
108705
 
+       if not test_script_compile "../../examples/rfc3028.sieve" {
108706
 
+               test_fail "could not compile";
108707
 
+       }
108708
 
+
108709
 
+       test_binary :save "rfc3028";
108710
 
+       test_binary :load "rfc3028";
108711
 
+
108712
 
+       if not test_script_run { }
108713
 
+}
108714
 
+
108715
 
+test "Sieve examples" {
108716
 
+       if not test_script_compile "../../examples/sieve_examples.sieve" {
108717
 
+               test_fail "could not compile";
108718
 
+       }
108719
 
+
108720
 
+       test_binary :save "sieve_examples";
108721
 
+       test_binary :load "sieve_examples";
108722
 
+
108723
 
+       if not test_script_run { }
108724
 
+}
108725
 
+
108726
 
+test "Vivil example" {
108727
 
+       if not test_script_compile "../../examples/vivil.sieve" {
108728
 
+               test_fail "could not compile";
108729
 
+       }
108730
 
+
108731
 
+       test_binary :save "vivil";
108732
 
+       test_binary :load "vivil";
108733
 
+
108734
 
+       if not test_script_run { }
108735
 
+}
108736
 
+
108737
 
+test "Jerry example" {
108738
 
+       if not test_script_compile "../../examples/jerry.sieve" {
108739
 
+               test_fail "could not compile";
108740
 
+       }
108741
 
+
108742
 
+       test_binary :save "jerry";
108743
 
+       test_binary :load "jerry";
108744
 
+
108745
 
+       if not test_script_run { }
108746
 
+}
108747
 
+
108748
 
+test "M. Klose example" {
108749
 
+       if not test_script_compile "../../examples/mklose.sieve" {
108750
 
+               test_fail "could not compile";
108751
 
+       }
108752
 
+
108753
 
+       test_binary :save "mklose";
108754
 
+       test_binary :load "mklose";
108755
 
+
108756
 
+       if not test_script_run { }
108757
 
+}
108758
 
+
108759
 
+test "Sanjay example" {
108760
 
+       if not test_script_compile "../../examples/sanjay.sieve" {
108761
 
+               test_fail "could not compile";
108762
 
+       }
108763
 
+
108764
 
+       test_binary :save "sanjay";
108765
 
+       test_binary :load "sanjay";
108766
 
+
108767
 
+       if not test_script_run { }
108768
 
+}
108769
 
+
108770
 
+test "Relational (RFC5231) example" {
108771
 
+       if not test_script_compile "../../examples/relational.rfc5231.sieve" {
108772
 
+               test_fail "could not compile";
108773
 
+       }
108774
 
+
108775
 
+       test_binary :save "relational";
108776
 
+       test_binary :load "relational";
108777
 
+
108778
 
+       if not test_script_run { }
108779
 
+}
108780
 
+
108781
 
+test "Subaddress (RFC5233) example" {
108782
 
+       if not test_script_compile "../../examples/subaddress.rfc5233.sieve" {
108783
 
+               test_fail "could not compile";
108784
 
+       }
108785
 
+
108786
 
+       test_binary :save "subaddress";
108787
 
+       test_binary :load "subaddress";
108788
 
+
108789
 
+       if not test_script_run { }
108790
 
+}
108791
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/execute/mailstore.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/execute/mailstore.svtest
108792
 
--- dovecot-1.2.4/dovecot-libsieve/tests/execute/mailstore.svtest       1970-01-01 01:00:00.000000000 +0100
108793
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/execute/mailstore.svtest        2009-08-02 09:44:14.000000000 +0200
108794
 
@@ -0,0 +1,84 @@
108795
 
+require "vnd.dovecot.testsuite";
108796
 
+require "fileinto";
108797
 
+require "variables";
108798
 
+require "mailbox";
108799
 
+
108800
 
+set "message1" text:
108801
 
+From: stephan@rename-it.nl
108802
 
+To: nico@vestingbar.nl
108803
 
+Subject: First message
108804
 
+
108805
 
+Frop
108806
 
+.
108807
 
+;
108808
 
+
108809
 
+set "message2" text:
108810
 
+From: stephan@rename-it.nl
108811
 
+To: nico@vestingbar.nl
108812
 
+Subject: Second message
108813
 
+
108814
 
+Frop
108815
 
+.
108816
 
+;
108817
 
+
108818
 
+set "message3" text:
108819
 
+From: stephan@rename-it.nl
108820
 
+To: nico@vestingbar.nl
108821
 
+Subject: Third message
108822
 
+
108823
 
+Frop
108824
 
+.
108825
 
+;
108826
 
+
108827
 
+test "Duplicates" {
108828
 
+       test_set "message" "${message1}";
108829
 
+
108830
 
+       fileinto :create "Folder";
108831
 
+       fileinto :create "Folder";
108832
 
+
108833
 
+       if not test_result_execute {
108834
 
+               test_fail "failed to execute first result";
108835
 
+       }
108836
 
+
108837
 
+       test_result_reset;
108838
 
+
108839
 
+       test_set "message" "${message2}";
108840
 
+
108841
 
+       fileinto :create "Folder";
108842
 
+       fileinto :create "Folder";
108843
 
+
108844
 
+       if not test_result_execute {
108845
 
+               test_fail "failed to execute second result";
108846
 
+       }
108847
 
+
108848
 
+       test_result_reset;
108849
 
+
108850
 
+       test_set "message" "${message3}";
108851
 
+
108852
 
+       fileinto :create "Folder";
108853
 
+       fileinto :create "Folder";
108854
 
+
108855
 
+       if not test_result_execute {
108856
 
+               test_fail "failed to execute third result";
108857
 
+       }
108858
 
+
108859
 
+       test_message :folder "Folder" 0;
108860
 
+       
108861
 
+       if not header :is "subject" "First message" {
108862
 
+               test_fail "first message incorrect";
108863
 
+       }
108864
 
+
108865
 
+       test_message :folder "Folder" 1;
108866
 
+
108867
 
+       if not header :is "subject" "Second message" {
108868
 
+               test_fail "first message incorrect";
108869
 
+       }
108870
 
+
108871
 
+       test_message :folder "Folder" 2;
108872
 
+
108873
 
+       if not header :is "subject" "Third message" {
108874
 
+               test_fail "first message incorrect";
108875
 
+       }
108876
 
+}
108877
 
+
108878
 
+
108879
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/execute/smtp.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/execute/smtp.svtest
108880
 
--- dovecot-1.2.4/dovecot-libsieve/tests/execute/smtp.svtest    1970-01-01 01:00:00.000000000 +0100
108881
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/execute/smtp.svtest     2009-07-21 12:28:37.000000000 +0200
108882
 
@@ -0,0 +1,61 @@
108883
 
+require "vnd.dovecot.testsuite";
108884
 
+require "envelope";
108885
 
+
108886
 
+test_set "message" text:
108887
 
+From: stephan@rename-it.nl
108888
 
+To: tss@iki.fi
108889
 
+Subject: Frop!
108890
 
+
108891
 
+Frop!
108892
 
+.
108893
 
+;
108894
 
+
108895
 
+test_set "envelope.from" "sirius@rename-it.nl";
108896
 
+test_set "envelope.to" "timo@iki.fi";
108897
 
+
108898
 
+test "Redirect" {
108899
 
+       redirect "cras@iki.fi";
108900
 
+
108901
 
+       if not test_result_execute {
108902
 
+        test_fail "failed to execute redirect";
108903
 
+    }
108904
 
+
108905
 
+    test_message :smtp 0;
108906
 
+
108907
 
+    if not address :is "to" "tss@iki.fi" {
108908
 
+        test_fail "to address incorrect (strange forward)";
108909
 
+    }
108910
 
+
108911
 
+    if not address :is "from" "stephan@rename-it.nl" {
108912
 
+        test_fail "from address incorrect (strange forward)";
108913
 
+    }
108914
 
+
108915
 
+       if not envelope :is "to" "cras@iki.fi" {
108916
 
+               test_fail "envelope recipient incorrect";
108917
 
+       }
108918
 
+
108919
 
+       if not envelope :is "from" "sirius@rename-it.nl" {
108920
 
+               test_fail "envelope sender incorrect";
108921
 
+       }
108922
 
+}
108923
 
+
108924
 
+test_result_reset;
108925
 
+
108926
 
+test "Redirect from <>" {
108927
 
+
108928
 
+       test_set "envelope.from" "<>";
108929
 
+
108930
 
+       redirect "cras@iki.fi";
108931
 
+
108932
 
+       if not test_result_execute {
108933
 
+        test_fail "failed to execute redirect";
108934
 
+    }
108935
 
+
108936
 
+       if envelope :is "from" "sirius@rename-it.nl" {
108937
 
+        test_fail "envelope sender incorrect (not changed)";
108938
 
+    }
108939
 
+
108940
 
+       if not envelope :is "from" "" {
108941
 
+        test_fail "envelope sender incorrect";
108942
 
+    }
108943
 
+}
108944
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/exists.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/exists.svtest
108945
 
--- dovecot-1.2.4/dovecot-libsieve/tests/exists.svtest  1970-01-01 01:00:00.000000000 +0100
108946
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/exists.svtest   2008-07-30 15:17:37.000000000 +0200
108947
 
@@ -0,0 +1,42 @@
108948
 
+require "vnd.dovecot.testsuite";
108949
 
+
108950
 
+test_set "message" text:
108951
 
+From: stephan@rename-it.nl
108952
 
+To: nico@vestingbar.bl
108953
 
+Subject: Test message
108954
 
+X-Spam-Status: Not Spam
108955
 
+Resent-To: nico@vestingbar.nl
108956
 
+
108957
 
+Test!
108958
 
+.
108959
 
+;
108960
 
+
108961
 
+test "EXISTS-one" {
108962
 
+       if not exists "from" {
108963
 
+               test_fail "exists test missed from header";
108964
 
+       }
108965
 
+
108966
 
+       if exists "x-nonsense" {
108967
 
+        test_fail "exists test found non-existant header";
108968
 
+    }
108969
 
+}
108970
 
+
108971
 
+test "EXISTS-two" {
108972
 
+    if not exists ["from","to"] {
108973
 
+        test_fail "exists test missed from or to header";
108974
 
+    }
108975
 
+
108976
 
+    if exists ["from","to","x-nonsense"] {
108977
 
+        test_fail "exists test found non-existant header";
108978
 
+    }
108979
 
+}
108980
 
+
108981
 
+test "EXISTS-three" {
108982
 
+    if not exists ["Subject","X-spam-STATUS","resent-to"] {
108983
 
+        test_fail "exists test missed from or to header";
108984
 
+    }
108985
 
+
108986
 
+    if exists ["x-spam", "sub", "resent"] {
108987
 
+        test_fail "exists test found non-existant header";
108988
 
+    }
108989
 
+}
108990
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/body/basic.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/body/basic.svtest
108991
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/body/basic.svtest   1970-01-01 01:00:00.000000000 +0100
108992
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/body/basic.svtest    2008-08-10 22:09:49.000000000 +0200
108993
 
@@ -0,0 +1,188 @@
108994
 
+require "vnd.dovecot.testsuite";
108995
 
+require "relational";
108996
 
+require "comparator-i;ascii-numeric";
108997
 
+
108998
 
+require "body";
108999
 
+
109000
 
+test_set "message" text:
109001
 
+From: stephan@rename-it.nl
109002
 
+To: tss@iki.fi
109003
 
+Subject: Test message.
109004
 
+
109005
 
+Test!
109006
 
+
109007
 
+.
109008
 
+;
109009
 
+
109010
 
+/* Empty line
109011
 
+ * 
109012
 
+ *  RFC 5173: 
109013
 
+ *    'The body test matches content in the body of an email message, that
109014
 
+ *     is, anything following the first empty line after the header.  (The
109015
 
+ *     empty line itself, if present, is not considered to be part of the
109016
 
+ *     body.)'
109017
 
+ */
109018
 
+test "The empty line" {
109019
 
+
109020
 
+       if not body :raw :is text:
109021
 
+Test!
109022
 
+
109023
 
+.
109024
 
+       {
109025
 
+               test_fail "invalid message body extracted";
109026
 
+       }
109027
 
+
109028
 
+       if body :raw :is text:
109029
 
+
109030
 
+Test!
109031
 
+
109032
 
+.
109033
 
+       {
109034
 
+               test_fail "invalid message body extracted";
109035
 
+       }
109036
 
+
109037
 
+       if body :raw :is "Test"
109038
 
+       {
109039
 
+               test_fail "body test matches nonsense";
109040
 
+       }
109041
 
+}
109042
 
+
109043
 
+/* Default comparator and match type
109044
 
+ *
109045
 
+ *  RFC 5173:
109046
 
+ *    'The COMPARATOR and MATCH-TYPE keyword parameters are defined in
109047
 
+ *     [SIEVE].  As specified in Sections 2.7.1 and 2.7.3 of [SIEVE], the
109048
 
+ *     default COMPARATOR is "i;ascii-casemap" and the default MATCH-TYPE is
109049
 
+ *     ":is".'
109050
 
+ */
109051
 
+
109052
 
+test "Defaults" {
109053
 
+       if anyof ( body :raw "Test", body :raw "*Test*" ) {
109054
 
+               test_fail "default match type is not :is as is required";
109055
 
+       }
109056
 
+
109057
 
+       if allof( not body :raw :contains "tesT", body :raw :contains "Test" ) {
109058
 
+               test_fail "default comparator is not i;ascii-casemap as is required";
109059
 
+       }
109060
 
+}
109061
 
+
109062
 
+/* No body
109063
 
+ *
109064
 
+ *  RFC 5173:
109065
 
+ *    'If a message consists of a header only, not followed by an empty line, 
109066
 
+ *     then that set is empty and all "body" tests return false, including 
109067
 
+ *     those that test for an empty string.  (This is similar to how the 
109068
 
+ *     "header" test always fails when the named header fields aren't present.)'
109069
 
+ */
109070
 
+
109071
 
+test_set "message" text:
109072
 
+From: stephan@rename-it.nl
109073
 
+To: tss@iki.fi
109074
 
+Subject: No body is here!
109075
 
+.
109076
 
+;
109077
 
+
109078
 
+test "No body" {
109079
 
+       if body :raw :contains "" {
109080
 
+               test_fail "matched against non-existant body (:contains \"\")";
109081
 
+       }
109082
 
+
109083
 
+       if body :raw :is "" {
109084
 
+               test_fail "matched against non-existant body (:is \"\")";
109085
 
+       }
109086
 
+
109087
 
+       if body :raw :matches "*" {
109088
 
+               test_fail "matched against non-existant body (:matches \"*\")";
109089
 
+       }
109090
 
+}
109091
 
+
109092
 
+/*
109093
 
+ *
109094
 
+ */
109095
 
+
109096
 
+test_set "message" text:
109097
 
+From: Whomever <whomever@domain.dom>
109098
 
+To: Someone <someone@domain.com>
109099
 
+Date: Fri, 08 Aug 2008 10:14:34 -0700
109100
 
+Subject: whatever
109101
 
+Content-Type: multipart/mixed; boundary=outer
109102
 
+
109103
 
+This is a multi-part message in MIME format.
109104
 
+
109105
 
+--outer
109106
 
+Content-Type: multipart/alternative; boundary=inner
109107
 
+
109108
 
+This is a nested multi-part message in MIME format.
109109
 
+
109110
 
+--inner
109111
 
+Content-Type: text/plain; charset="us-ascii"
109112
 
+
109113
 
+Hello
109114
 
+
109115
 
+--inner
109116
 
+Content-Type: text/html; charset="us-ascii"
109117
 
+
109118
 
+<html><body>Hello</body></html>
109119
 
+
109120
 
+--inner--
109121
 
+
109122
 
+This is the end of the inner MIME multipart.
109123
 
+
109124
 
+--outer
109125
 
+Content-Type: message/rfc822
109126
 
+From: Someone Else <someone.else@domain.dom>
109127
 
+Subject: hello request
109128
 
+
109129
 
+Please say Hello
109130
 
+
109131
 
+--outer--
109132
 
+
109133
 
+This is the end of the outer MIME multipart.
109134
 
+.
109135
 
+;
109136
 
+
109137
 
+test "RFC nested example - :content \"text\"" {
109138
 
+       if not body :content "text" :contains "html" {
109139
 
+               test_fail "failed to acquire nested MIME body part (1)";        
109140
 
+       }
109141
 
+
109142
 
+       if not body :content "text/html" :contains "hello" {
109143
 
+               test_fail "failed to acquire nested MIME body part (2)";        
109144
 
+       }
109145
 
+       
109146
 
+       if not body :content "text/plain" :contains "hello" {
109147
 
+        test_fail "failed to acquire nested MIME body part (3)";
109148
 
+    }
109149
 
+
109150
 
+       if not body :content "text" :contains "hello" {
109151
 
+        test_fail "failed to acquire nested MIME body part (4)";
109152
 
+    }
109153
 
+
109154
 
+/* FIXME: fails
109155
 
+       if not body :content "text" :count "eq" :comparator "i;ascii-numeric" "2" {
109156
 
+               test_fail "matched wrong number of \"text/*\" body parts";
109157
 
+       }*/
109158
 
+}
109159
 
+
109160
 
+/* FIXME: fails
109161
 
+test "RFC nested example - :content \"multipart\"" {
109162
 
+       if not body :content "multipart" :contains
109163
 
+               "This is a multi-part message in MIME format" {
109164
 
+               test_fail "missed first multipart body part";
109165
 
+       }
109166
 
+
109167
 
+       if not body :content "multipart" :contains
109168
 
+               "This is a nested multi-part message in MIME format" {
109169
 
+               test_fail "missed second multipart body part";
109170
 
+       }
109171
 
+       
109172
 
+       if not body :content "multipart" :contains
109173
 
+               "This is the end of the inner MIME multipart" {
109174
 
+               test_fail "missed third multipart body part";
109175
 
+       }
109176
 
+
109177
 
+       if not body :content "multipart" :contains
109178
 
+               "This is the end of the outer MIME multipart." {
109179
 
+               test_fail "missed fourth multipart body part";
109180
 
+       }       
109181
 
+}*/
109182
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/body/match-values.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/body/match-values.svtest
109183
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/body/match-values.svtest    1970-01-01 01:00:00.000000000 +0100
109184
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/body/match-values.svtest     2008-08-25 10:25:08.000000000 +0200
109185
 
@@ -0,0 +1,55 @@
109186
 
+require "vnd.dovecot.testsuite";
109187
 
+
109188
 
+require "body";
109189
 
+require "variables";
109190
 
+
109191
 
+test_set "message" text:
109192
 
+From: stephan@rename-it.nl
109193
 
+To: s.bosch@utwente.nl
109194
 
+Subject: Body test
109195
 
+
109196
 
+The big bad body test.
109197
 
+.
109198
 
+;
109199
 
+
109200
 
+# Test whether body test ignores match values
109201
 
+test "Match values disabled" {
109202
 
+       if not body :raw :matches "The * bad * test*" {
109203
 
+               test_fail "should have matched";
109204
 
+       }
109205
 
+
109206
 
+       if anyof (
109207
 
+               string :is "${1}" "big",
109208
 
+               string :is "${2}" "body",
109209
 
+               not string :is "${0}" "",
109210
 
+               not string :is "${1}" "",
109211
 
+               not string :is "${2}" "") {
109212
 
+               test_fail "match values not disabled";
109213
 
+       }
109214
 
+}
109215
 
+
109216
 
+test "Match values re-enabled" {
109217
 
+       if not header :matches "from" "*@*" {
109218
 
+               test_fail "should have matched";
109219
 
+       }
109220
 
+
109221
 
+       if anyof (
109222
 
+               not string :is "${0}" "stephan@rename-it.nl",
109223
 
+               not string :is "${1}" "stephan",
109224
 
+               not string :is "${2}" "rename-it.nl" ) {
109225
 
+               test_fail "match values not re-enabled properly.";
109226
 
+       }
109227
 
+}
109228
 
+
109229
 
+test "Match values retained" {
109230
 
+       if not body :raw :matches "The * bad * test*" {
109231
 
+               test_fail "should have matched";
109232
 
+       }
109233
 
+
109234
 
+       if anyof (
109235
 
+               not string :is "${0}" "stephan@rename-it.nl",
109236
 
+               not string :is "${1}" "stephan",
109237
 
+               not string :is "${2}" "rename-it.nl" ) {
109238
 
+               test_fail "match values not retained after body test.";
109239
 
+       }
109240
 
+}
109241
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/date/basic.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/date/basic.svtest
109242
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/date/basic.svtest   1970-01-01 01:00:00.000000000 +0100
109243
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/date/basic.svtest    2009-08-21 00:52:15.000000000 +0200
109244
 
@@ -0,0 +1,41 @@
109245
 
+require "vnd.dovecot.testsuite";
109246
 
+require "date";
109247
 
+require "variables";
109248
 
+require "relational";
109249
 
+
109250
 
+test_set "message" text:
109251
 
+From: stephan@rename-it.nl
109252
 
+To: sirius@drunksnipers.com
109253
 
+Subject: Frop!
109254
 
+Date: Mon, 20 Jul 2009 21:44:43 +0300
109255
 
+Delivery-Date: Mon, 22 Jul 2009 23:30:14 +0300
109256
 
+Invalid-Date: Moo, 34 Juul 3060 25:30:42 +6600
109257
 
+Wanna date?
109258
 
+.
109259
 
+;
109260
 
+
109261
 
+test "Defaults" {
109262
 
+       if not date :originalzone "date" "std11" "mon, 20 jul 2009 21:44:43 +0300" {
109263
 
+               test_fail "default comparator is not i;ascii-casemap";  
109264
 
+       }
109265
 
+
109266
 
+       if anyof ( date "date" "std11" "Mon", date "date" "std11" "*") {
109267
 
+               test_fail "default match type appears to be :contains or :matches";
109268
 
+       }
109269
 
+}
109270
 
+
109271
 
+test "Count" {
109272
 
+       if not date :count "eq" "date" "date" "1" {
109273
 
+               test_fail "count of existing date header field is not 1";       
109274
 
+       }
109275
 
+
109276
 
+       if not date :count "eq" "resent-date" "date" "0" {
109277
 
+               test_fail "count of non-existent date header field is not 0";   
109278
 
+       }
109279
 
+}
109280
 
+
109281
 
+test "Invalid" {
109282
 
+       if date :matches "invalid-date" "std11" "*" {
109283
 
+               test_fail "matched invalid date: ${0}"; 
109284
 
+       }
109285
 
+}
109286
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/date/date-parts.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/date/date-parts.svtest
109287
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/date/date-parts.svtest      1970-01-01 01:00:00.000000000 +0100
109288
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/date/date-parts.svtest       2009-08-21 00:52:15.000000000 +0200
109289
 
@@ -0,0 +1,120 @@
109290
 
+require "vnd.dovecot.testsuite";
109291
 
+require "date";
109292
 
+require "variables";
109293
 
+
109294
 
+test_set "message" text:
109295
 
+From: stephan@rename-it.nl
109296
 
+To: sirius@drunksnipers.com
109297
 
+Subject: Frop!
109298
 
+Date: Mon, 20 Jul 2009 21:44:43 +0300
109299
 
+Delivery-Date: Mon, 22 Jul 2009 23:30:14 +0300
109300
 
+
109301
 
+Wanna date?
109302
 
+.
109303
 
+;
109304
 
+
109305
 
+/* "year"      => the year, "0000" .. "9999". */
109306
 
+test "Year" {
109307
 
+       if not date :originalzone "date" "year" "2009" {
109308
 
+               test_fail "failed to extract year part";
109309
 
+       }
109310
 
+}
109311
 
+
109312
 
+/* "month"     => the month, "01" .. "12". */
109313
 
+test "Month" {
109314
 
+       if not date :originalzone "date" "month" "07" {
109315
 
+               test_fail "failed to extract month part";
109316
 
+       }
109317
 
+}
109318
 
+
109319
 
+/* "day"       => the day, "01" .. "31". */
109320
 
+test "Day" {
109321
 
+       if not date :originalzone "date" "day" "20" {
109322
 
+               test_fail "failed to extract day part";
109323
 
+       }
109324
 
+}
109325
 
+
109326
 
+/* "date"      => the date in "yyyy-mm-dd" format. */
109327
 
+test "Date" {
109328
 
+       if not date :originalzone "date" "date" "2009-07-20" {
109329
 
+               test_fail "failed to extract date part";
109330
 
+       }
109331
 
+}
109332
 
+
109333
 
+/* "julian"    => the Modified Julian Day, that is, the date
109334
 
+              expressed as an integer number of days since
109335
 
+              00:00 UTC on November 17, 1858 (using the Gregorian
109336
 
+              calendar).  This corresponds to the regular
109337
 
+              Julian Day minus 2400000.5.  */
109338
 
+test "Julian" {
109339
 
+       if not date :originalzone "date" "julian" "55032" {
109340
 
+               if date :matches :originalzone "date" "julian" "*" { }
109341
 
+               test_fail "failed to extract julian part: ${0}";
109342
 
+       }
109343
 
+       if not date :originalzone "delivery-date" "julian" "55034" {
109344
 
+               if date :matches :originalzone "delivery-date" "julian" "*" { }
109345
 
+               test_fail "failed to extract julian part: ${0}";
109346
 
+       }
109347
 
+}
109348
 
+
109349
 
+/* "hour"      => the hour, "00" .. "23". */
109350
 
+test "Hour" {
109351
 
+       if not date :originalzone "date" "hour" "21" {
109352
 
+               test_fail "failed to extract hour part";
109353
 
+       }
109354
 
+}
109355
 
+
109356
 
+/* "minute"    => the minute, "00" .. "59". */
109357
 
+test "Minute" {
109358
 
+       if not date :originalzone "date" "minute" "44" {
109359
 
+               test_fail "failed to extract minute part";
109360
 
+       }
109361
 
+}
109362
 
+
109363
 
+/* "second"    => the second, "00" .. "60". */
109364
 
+test "Second" {
109365
 
+       if not date :originalzone "date" "second" "43" {
109366
 
+               test_fail "failed to extract second part";
109367
 
+       }
109368
 
+}
109369
 
+
109370
 
+/* "time"      => the time in "hh:mm:ss" format. */
109371
 
+test "Time" {
109372
 
+       if not date :originalzone "date" "time" "21:44:43" {
109373
 
+               test_fail "failed to extract time part";
109374
 
+       }
109375
 
+}
109376
 
+
109377
 
+/* "iso8601"   => the date and time in restricted ISO 8601 format. */
109378
 
+test "ISO8601" {
109379
 
+       if not date :originalzone "date" "iso8601" "2009-07-20T21:44:43+03:00" {
109380
 
+               test_fail "failed to extract iso8601 part";
109381
 
+       }
109382
 
+}
109383
 
+
109384
 
+/* "std11"     => the date and time in a format appropriate
109385
 
+                  for use in a Date: header field [RFC2822]. */
109386
 
+test "STD11" {
109387
 
+       if not date :originalzone "date" "std11" "Mon, 20 Jul 2009 21:44:43 +0300" {
109388
 
+               test_fail "failed to extract std11 part";
109389
 
+       }
109390
 
+}
109391
 
+
109392
 
+/* "zone"      => the time zone in use.  */
109393
 
+test "zone" {
109394
 
+       if not date :originalzone "date" "zone" "+0300" {
109395
 
+               test_fail "failed to extract zone part";
109396
 
+       }
109397
 
+
109398
 
+       if not date :zone "+0200" "date" "zone" "+0200" {
109399
 
+               test_fail "failed to extract zone part";
109400
 
+       }
109401
 
+}
109402
 
+
109403
 
+/* "weekday"   => the day of the week expressed as an integer between
109404
 
+                  "0" and "6". "0" is Sunday, "1" is Monday, etc. */
109405
 
+test "Weekday" {
109406
 
+       if not date :originalzone "date" "weekday" "1" {
109407
 
+               test_fail "failed to extract weekday part";
109408
 
+       }
109409
 
+}
109410
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/date/zones.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/date/zones.svtest
109411
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/date/zones.svtest   1970-01-01 01:00:00.000000000 +0100
109412
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/date/zones.svtest    2009-08-21 00:52:15.000000000 +0200
109413
 
@@ -0,0 +1,76 @@
109414
 
+require "vnd.dovecot.testsuite";
109415
 
+require "date";
109416
 
+require "variables";
109417
 
+
109418
 
+/* Extract local timezone first */
109419
 
+test "Local-Zone" {
109420
 
+       if not currentdate :matches "zone" "*" {
109421
 
+               test_fail "matches '*' failed for zone part.";
109422
 
+       }
109423
 
+       set "local_zone" "${0}";        
109424
 
+}
109425
 
+
109426
 
+/* FIXME: using variables somehow fails here */
109427
 
+if string "${local_zone}" "+0200" {
109428
 
+test_set "message" text:
109429
 
+From: stephan@rename-it.nl
109430
 
+To: sirius@drunksnipers.com
109431
 
+Subject: Frop!
109432
 
+Date: Mon, 20 Jul 2009 21:44:43 +0300
109433
 
+Delivery-Date: Mon, 23 Jul 2009 05:30:14 +0800
109434
 
+
109435
 
+Wanna date?
109436
 
+.
109437
 
+;
109438
 
+} else {
109439
 
+test_set "message" text:
109440
 
+From: stephan@rename-it.nl
109441
 
+To: sirius@drunksnipers.com
109442
 
+Subject: Frop!
109443
 
+Date: Mon, 20 Jul 2009 21:44:43 +0300
109444
 
+Delivery-Date: Mon, 22 Jul 2009 23:30:14 +0200
109445
 
+
109446
 
+Wanna date?
109447
 
+.
109448
 
+;
109449
 
+}
109450
 
+
109451
 
+test "Specified Zone" {
109452
 
+       if not date :zone "+0200" "date" "zone" "+0200" {
109453
 
+               if date :matches :zone "+0200" "date" "zone" "*" {}
109454
 
+               test_fail "zone is incorrect: ${0}";    
109455
 
+       }
109456
 
+
109457
 
+       if not date :zone "+0200" "date" "time" "20:44:43" {
109458
 
+               test_fail "zone is not applied";        
109459
 
+       }
109460
 
+}
109461
 
+
109462
 
+test "Original Zone" {
109463
 
+       if not date :originalzone "date" "zone" "+0300" {
109464
 
+               if date :matches :originalzone "date" "zone" "*" {}
109465
 
+               test_fail "zone is incorrect: ${0}";    
109466
 
+       }
109467
 
+
109468
 
+       if not date :originalzone "date" "time" "21:44:43" {
109469
 
+               test_fail "time should be left untouched";      
109470
 
+       }
109471
 
+}
109472
 
+
109473
 
+test "Local Zone Shift" {
109474
 
+       if anyof ( 
109475
 
+                       allof ( 
109476
 
+                               string "${local_zone}" "+0200",
109477
 
+                               date "delivery-date" "iso8601" "2009-07-23T05:30:14+08:00"),
109478
 
+                       allof ( 
109479
 
+                               not string "${local_zone}" "+0200",
109480
 
+                               date "delivery-date" "iso8601" "2009-07-22T23:30:14+02:00")) {
109481
 
+       
109482
 
+               if date :matches "delivery-date" "iso8601" "*" 
109483
 
+                       { set "a" "${0}"; }
109484
 
+               if date :originalzone :matches "delivery-date" "iso8601" "*" 
109485
 
+                       { set "b" "${0}"; }
109486
 
+
109487
 
+               test_fail "time not shifted to local zone: ${b} => ${a}";
109488
 
+       }
109489
 
+}
109490
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/encoded-character.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/encoded-character.svtest
109491
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/encoded-character.svtest    1970-01-01 01:00:00.000000000 +0100
109492
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/encoded-character.svtest     2008-08-01 16:50:38.000000000 +0200
109493
 
@@ -0,0 +1,180 @@
109494
 
+require "vnd.dovecot.testsuite";
109495
 
+
109496
 
+require "encoded-character";
109497
 
+require "variables";
109498
 
+
109499
 
+test "HEX equality one" {
109500
 
+       if not string "${hex:42}" "B" {
109501
 
+               test_fail "failed to match the string 'B'";
109502
 
+       }
109503
 
+
109504
 
+       if string "${hex:42}" "b" {
109505
 
+               test_fail "matched nonsense";
109506
 
+       }
109507
 
+
109508
 
+       if string "${hex:42}" "" {
109509
 
+               test_fail "substitution failed";
109510
 
+       }
109511
 
+}
109512
 
+
109513
 
+test "HEX equality one middle" {
109514
 
+       if not string " ${hex:42} " " B " {
109515
 
+               test_fail "failed to match the string ' B '";
109516
 
+       }
109517
 
+
109518
 
+       if string " ${hex:42} " " b " {
109519
 
+               test_fail "matched nonsense";
109520
 
+       }
109521
 
+
109522
 
+       if string " ${hex:42} " "  " {
109523
 
+               test_fail "substitution failed";
109524
 
+       }
109525
 
+}
109526
 
+
109527
 
+test "HEX equality one begin" {
109528
 
+       if not string "${hex:42} " "B " {
109529
 
+               test_fail "failed to match the string 'B '";
109530
 
+       }
109531
 
+
109532
 
+       if string "${hex:42} " " b" {
109533
 
+               test_fail "matched nonsense";
109534
 
+       }
109535
 
+
109536
 
+       if string "${hex:42} " " " {
109537
 
+               test_fail "substitution failed";
109538
 
+       }
109539
 
+}
109540
 
+
109541
 
+test "HEX equality one end" {
109542
 
+       if not string " ${hex:42}" " B" {
109543
 
+               test_fail "failed to match the string ' B'";
109544
 
+       }
109545
 
+
109546
 
+       if string " ${hex:42}" " b " {
109547
 
+               test_fail "matched nonsense";
109548
 
+       }
109549
 
+
109550
 
+       if string " ${hex:42}" " " {
109551
 
+               test_fail "substitution failed";
109552
 
+       }
109553
 
+}
109554
 
+
109555
 
+test "HEX equality two triple" {
109556
 
+       if not string "${hex:42 61 64}${hex: 61 73 73}" "Badass" {
109557
 
+               test_fail "failed to match the string 'Badass'";
109558
 
+       }
109559
 
+
109560
 
+       if string "${hex:42 61 64}${hex: 61 73 73}" "Sadass" {
109561
 
+               test_fail "matched nonsense";
109562
 
+       }
109563
 
+
109564
 
+       if string "${hex:42 61 64}${hex: 61 73 73}" "" {
109565
 
+               test_fail "substitution failed";
109566
 
+       }
109567
 
+}
109568
 
+
109569
 
+test "HEX equality braindead" {
109570
 
+       if not string "${hex:42 72 61 69 6E 64 65 61 64}" "Braindead" {
109571
 
+               test_fail "failed to match the string 'Braindead'";
109572
 
+       }
109573
 
+
109574
 
+       if string "${hex:42 72 61 69 6E 64 65 61 64}" "Brian Nut" {
109575
 
+               test_fail "matched nonsense";
109576
 
+       }
109577
 
+}
109578
 
+
109579
 
+test "Syntax errors" {
109580
 
+       if anyof( not string "$" "${hex:24}", not string "$ " "${hex:24} ", not string " $" " ${hex:24}" ) {
109581
 
+        test_fail "loose $ handled inappropriately";
109582
 
+    }
109583
 
+
109584
 
+       if anyof( not string "${" "${hex:24}{", not string "a${" "a${hex:24}{", not string "${a" "${hex:24}{a" ) {
109585
 
+        test_fail "loose ${ handled inappropriately";
109586
 
+    }
109587
 
+
109588
 
+       if anyof( not string "${}" "${hex:24}{}", not string "b${}" "b${hex:24}{}", not string "${}b" "${hex:24}{}b" ) {
109589
 
+               test_fail "entirely missing content handled inappropriately";
109590
 
+       }
109591
 
+               
109592
 
+       if not string "${:}" "${hex:24}{:}" {
109593
 
+        test_fail "missing content handled inappropriately";
109594
 
+    }
109595
 
+       
109596
 
+       if not string "${hex:}" "${hex:24}{hex:}" {
109597
 
+        test_fail "missing hex content handled inappropriately";
109598
 
+    }
109599
 
+
109600
 
+       if not string "${unicode:}" "${hex:24}{unicode:}" {
109601
 
+        test_fail "missing unicode content handled inappropriately";
109602
 
+    }
109603
 
+
109604
 
+       if not string "${hex:sss}" "${hex:24}{hex:sss}" {
109605
 
+        test_fail "erroneous hex content handled inappropriately";
109606
 
+    }
109607
 
+
109608
 
+    if not string "${unicode:ttt}" "${hex:24}{unicode:ttt}" {
109609
 
+        test_fail "erroneous unicode content handled inappropriately";
109610
 
+    }
109611
 
+       
109612
 
+       if not string "${hex:aa aa" "${hex:24}{hex:aa aa" {
109613
 
+        test_fail "unterminated hex content handled inappropriately";
109614
 
+    }
109615
 
+
109616
 
+    if not string "${unicode: aaaa aaaa" "${hex:24}{unicode: aaaa aaaa" {
109617
 
+        test_fail "unterminated unicode content handled inappropriately";
109618
 
+    }
109619
 
+}
109620
 
+
109621
 
+/*
109622
 
+ * RFC Examples
109623
 
+ */
109624
 
+
109625
 
+test "RFC Examples" {
109626
 
+       if not string "$${hex:40}" "$@" {
109627
 
+               test_fail "failed RFC example 1";
109628
 
+       }
109629
 
+
109630
 
+       if not string "${hex: 40 }" "@" {
109631
 
+               test_fail "failed RFC example 2";
109632
 
+       }
109633
 
+
109634
 
+       if not string "${HEX: 40}" "@" {
109635
 
+               test_fail "failed RFC example 3";
109636
 
+       }
109637
 
+       
109638
 
+       if not string "${hex:40" "${hex:40" {
109639
 
+               test_fail "failed RFC example 4";
109640
 
+       }
109641
 
+
109642
 
+       if not string "${hex:400}" "${hex:400}" {
109643
 
+               test_fail "failed RFC example 5";
109644
 
+       }
109645
 
+
109646
 
+       if not string "${hex:4${hex:30}}" "${hex: 24}{hex:40}" {
109647
 
+               test_fail "failed RFC example 6";
109648
 
+       }
109649
 
+
109650
 
+       if not string "${unicode:40}" "@" {
109651
 
+               test_fail "failed RFC example 7";
109652
 
+       }
109653
 
+     
109654
 
+       if not string "${ unicode:40}" "${ unicode:40}" {
109655
 
+               test_fail "failed RFC example 8";
109656
 
+       }
109657
 
+
109658
 
+       if not string "${UNICODE:40}" "@" {
109659
 
+               test_fail "failed RFC example 9";
109660
 
+       }
109661
 
+
109662
 
+       if not string "${UnICoDE:0000040}" "@" {
109663
 
+               test_fail "failed RFC example 10";
109664
 
+       }
109665
 
+
109666
 
+       if not string "${Unicode:40}" "@" {
109667
 
+               test_fail "failed RFC example 11";
109668
 
+       }
109669
 
+
109670
 
+       if not string "${Unicode:Cool}" "${Unicode:Cool}" {
109671
 
+               test_fail "failed RFC example 12";
109672
 
+       }
109673
 
+}
109674
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/enotify/basic.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/enotify/basic.svtest
109675
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/enotify/basic.svtest        1970-01-01 01:00:00.000000000 +0100
109676
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/enotify/basic.svtest 2009-01-06 00:15:52.000000000 +0100
109677
 
@@ -0,0 +1,15 @@
109678
 
+require "vnd.dovecot.testsuite";
109679
 
+require "enotify";
109680
 
+
109681
 
+test "Execute" {
109682
 
+       /* Test to catch runtime segfaults */
109683
 
+       if valid_notify_method 
109684
 
+               "mailto:stephan@example.com" {
109685
 
+
109686
 
+               /* Test to catch runtime segfaults */
109687
 
+               notify 
109688
 
+                       :message "This is probably very important"
109689
 
+                       :importance "1" 
109690
 
+                       "mailto:stephan@example.com%2cstephan@rename-it.nl?subject=Important%20message%20received";
109691
 
+       }
109692
 
+}
109693
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/enotify/encodeurl.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/enotify/encodeurl.svtest
109694
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/enotify/encodeurl.svtest    1970-01-01 01:00:00.000000000 +0100
109695
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/enotify/encodeurl.svtest     2008-11-28 22:33:49.000000000 +0100
109696
 
@@ -0,0 +1,11 @@
109697
 
+require "vnd.dovecot.testsuite";
109698
 
+require "variables";
109699
 
+require "enotify";
109700
 
+
109701
 
+test "Encode Simple" {
109702
 
+       set :encodeurl "url_data" "\\frop\\&fruts/^@";
109703
 
+
109704
 
+       if not string :is :comparator "i;octet" "${url_data}" "%5Cfrop%5C%26fruts%2F%5E%40" {
109705
 
+               test_fail "url data encoded incorrectly '${url_data}'";
109706
 
+       }
109707
 
+}
109708
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/enotify/errors/from-mailto.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/enotify/errors/from-mailto.sieve
109709
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/enotify/errors/from-mailto.sieve    1970-01-01 01:00:00.000000000 +0100
109710
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/enotify/errors/from-mailto.sieve     2009-07-19 15:54:39.000000000 +0200
109711
 
@@ -0,0 +1,7 @@
109712
 
+require "enotify";
109713
 
+
109714
 
+# 1: Invalid from address
109715
 
+notify :from "stephan#rename-it.nl" "mailto:stephan@example.com";
109716
 
+
109717
 
+# 2: Empty from address
109718
 
+notify :from "" "mailto:stephan@example.com";
109719
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/enotify/errors/options.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/enotify/errors/options.sieve
109720
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/enotify/errors/options.sieve        1970-01-01 01:00:00.000000000 +0100
109721
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/enotify/errors/options.sieve 2009-01-06 00:15:52.000000000 +0100
109722
 
@@ -0,0 +1,18 @@
109723
 
+require "enotify";
109724
 
+
109725
 
+# 1: empty option
109726
 
+notify :options "" "mailto:stephan@rename-it.nl";
109727
 
+
109728
 
+# 2: invalid option name syntax
109729
 
+notify :options "frop" "mailto:stephan@rename-it.nl";
109730
 
+
109731
 
+# 3: invalid option name syntax
109732
 
+notify :options "_frop=" "mailto:stephan@rename-it.nl";
109733
 
+
109734
 
+# 4: invalid option name syntax
109735
 
+notify :options "=frop" "mailto:stephan@rename-it.nl";
109736
 
+
109737
 
+# 5: invalid value
109738
 
+notify :options "frop=frml
109739
 
+frop" "mailto:stephan@rename-it.nl";
109740
 
+
109741
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/enotify/errors/uri-mailto.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/enotify/errors/uri-mailto.sieve
109742
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/enotify/errors/uri-mailto.sieve     1970-01-01 01:00:00.000000000 +0100
109743
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/enotify/errors/uri-mailto.sieve      2009-01-06 00:15:52.000000000 +0100
109744
 
@@ -0,0 +1,20 @@
109745
 
+require "enotify";
109746
 
+
109747
 
+# 1: Invalid character in to part
109748
 
+notify "mailto:stephan@rename-it.nl;?header=frop";
109749
 
+
109750
 
+# 2: Invalid character in hname
109751
 
+notify "mailto:stephan@rename-it.nl?header<=frop";
109752
 
+
109753
 
+# 3: Invalid character in hvalue
109754
 
+notify "mailto:stephan@rename-it.nl?header=fr>op";
109755
 
+
109756
 
+# 4: Invalid header name 
109757
 
+notify "mailto:stephan@rename-it.nl?header:=frop";
109758
 
+
109759
 
+# 5: Invalid recipient
109760
 
+notify "mailto:stephan%23rename-it.nl";
109761
 
+
109762
 
+# 6: Invalid to header recipient
109763
 
+notify "mailto:stephan@rename-it.nl?to=nico%23vestingbar.nl";
109764
 
+
109765
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/enotify/errors/uri.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/enotify/errors/uri.sieve
109766
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/enotify/errors/uri.sieve    1970-01-01 01:00:00.000000000 +0100
109767
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/enotify/errors/uri.sieve     2009-01-06 00:15:52.000000000 +0100
109768
 
@@ -0,0 +1,5 @@
109769
 
+require "enotify";
109770
 
+
109771
 
+# 1: Invalid url scheme
109772
 
+notify "snailto:stephan@rename-it.nl";
109773
 
+
109774
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/enotify/errors.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/enotify/errors.svtest
109775
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/enotify/errors.svtest       1970-01-01 01:00:00.000000000 +0100
109776
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/enotify/errors.svtest        2009-07-19 15:54:39.000000000 +0200
109777
 
@@ -0,0 +1,45 @@
109778
 
+require "vnd.dovecot.testsuite";
109779
 
+require "comparator-i;ascii-numeric";
109780
 
+require "relational";
109781
 
+
109782
 
+require "enotify";
109783
 
+
109784
 
+test "Invalid URI (FIXME: count only)" {
109785
 
+       if test_script_compile "errors/uri.sieve" {
109786
 
+               test_fail "compile should have failed";
109787
 
+       }
109788
 
+
109789
 
+       if not test_error :count "eq" :comparator "i;ascii-numeric" "2" {
109790
 
+               test_fail "wrong number of errors reported";
109791
 
+       }
109792
 
+}
109793
 
+
109794
 
+test "Invalid mailto URI (FIXME: count only)" {
109795
 
+       if test_script_compile "errors/uri-mailto.sieve" {
109796
 
+               test_fail "compile should have failed";
109797
 
+       }
109798
 
+
109799
 
+       if not test_error :count "eq" :comparator "i;ascii-numeric" "7" {
109800
 
+               test_fail "wrong number of errors reported";
109801
 
+       }
109802
 
+}
109803
 
+
109804
 
+test "Invalid mailto :from address (FIXME: count only)" {
109805
 
+       if test_script_compile "errors/from-mailto.sieve" {
109806
 
+               test_fail "compile should have failed";
109807
 
+       }
109808
 
+
109809
 
+       if not test_error :count "eq" :comparator "i;ascii-numeric" "3" {
109810
 
+               test_fail "wrong number of errors reported";
109811
 
+       }
109812
 
+}
109813
 
+
109814
 
+test "Invalid :options argument (FIXME: count only)" {
109815
 
+       if test_script_compile "errors/options.sieve" {
109816
 
+               test_fail "compile should have failed";
109817
 
+       }
109818
 
+
109819
 
+       if not test_error :count "eq" :comparator "i;ascii-numeric" "6" {
109820
 
+               test_fail "wrong number of errors reported";
109821
 
+       }
109822
 
+}
109823
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/enotify/execute/draft-rfc-ex1.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/enotify/execute/draft-rfc-ex1.sieve
109824
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/enotify/execute/draft-rfc-ex1.sieve 1970-01-01 01:00:00.000000000 +0100
109825
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/enotify/execute/draft-rfc-ex1.sieve  2008-11-21 22:05:14.000000000 +0100
109826
 
@@ -0,0 +1,26 @@
109827
 
+require ["enotify", "fileinto", "variables"];
109828
 
+
109829
 
+if header :contains "from" "boss@example.org" {
109830
 
+       notify :importance "1"
109831
 
+               :message "This is probably very important"
109832
 
+               "mailto:alm@example.com";
109833
 
+       # Don't send any further notifications
109834
 
+       stop;
109835
 
+}
109836
 
+
109837
 
+if header :contains "to" "sievemailinglist@example.org" {
109838
 
+       # :matches is used to get the value of the Subject header
109839
 
+       if header :matches "Subject" "*" {
109840
 
+               set "subject" "${1}";
109841
 
+       }
109842
 
+
109843
 
+       # :matches is used to get the value of the From header
109844
 
+       if header :matches "From" "*" {
109845
 
+               set "from" "${1}";
109846
 
+       }
109847
 
+
109848
 
+       notify :importance "3"
109849
 
+               :message "[SIEVE] ${from}: ${subject}"
109850
 
+               "mailto:alm@example.com";
109851
 
+       fileinto "INBOX.sieve";
109852
 
+}
109853
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/enotify/execute/draft-rfc-ex2.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/enotify/execute/draft-rfc-ex2.sieve
109854
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/enotify/execute/draft-rfc-ex2.sieve 1970-01-01 01:00:00.000000000 +0100
109855
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/enotify/execute/draft-rfc-ex2.sieve  2008-11-21 22:05:14.000000000 +0100
109856
 
@@ -0,0 +1,22 @@
109857
 
+require ["enotify", "fileinto", "variables", "envelope"];
109858
 
+
109859
 
+if header :matches "from" "*@*.example.org" {
109860
 
+       # :matches is used to get the MAIL FROM address
109861
 
+       if envelope :all :matches "from" "*" {
109862
 
+               set "env_from" " [really: ${1}]";
109863
 
+       }
109864
 
+
109865
 
+       # :matches is used to get the value of the Subject header
109866
 
+       if header :matches "Subject" "*" {
109867
 
+               set "subject" "${1}";
109868
 
+       }
109869
 
+
109870
 
+       # :matches is used to get the address from the From header
109871
 
+       if address :matches :all "from" "*" {
109872
 
+               set "from_addr" "${1}";
109873
 
+       }
109874
 
+
109875
 
+       notify :message "${from_addr}${env_from}: ${subject}"
109876
 
+               "mailto:alm@example.com";
109877
 
+}
109878
 
+
109879
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/enotify/execute/draft-rfc-ex3.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/enotify/execute/draft-rfc-ex3.sieve
109880
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/enotify/execute/draft-rfc-ex3.sieve 1970-01-01 01:00:00.000000000 +0100
109881
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/enotify/execute/draft-rfc-ex3.sieve  2008-11-21 22:05:14.000000000 +0100
109882
 
@@ -0,0 +1,31 @@
109883
 
+require ["enotify", "variables"];
109884
 
+
109885
 
+set "notif_method"
109886
 
+       "xmpp:tim@example.com?message;subject=SIEVE;body=You%20got%20mail";
109887
 
+
109888
 
+if header :contains "subject" "Your dog" {
109889
 
+       set "notif_method" "tel:+14085551212";
109890
 
+}
109891
 
+
109892
 
+if header :contains "to" "sievemailinglist@example.org" {
109893
 
+       set "notif_method" "";
109894
 
+}
109895
 
+
109896
 
+if not string :is "${notif_method}" "" {
109897
 
+       notify "${notif_method}";
109898
 
+}
109899
 
+
109900
 
+if header :contains "from" "boss@example.org" {
109901
 
+       # :matches is used to get the value of the Subject header
109902
 
+       if header :matches "Subject" "*" {
109903
 
+               set "subject" "${1}";
109904
 
+       }
109905
 
+
109906
 
+       # don't need high importance notification for
109907
 
+       # a 'for your information'
109908
 
+       if not header :contains "subject" "FYI:" {
109909
 
+               notify :importance "1" :message "BOSS: ${subject}"
109910
 
+                       "tel:+14085551212";
109911
 
+       }
109912
 
+}
109913
 
+
109914
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/enotify/execute/draft-rfc-ex5.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/enotify/execute/draft-rfc-ex5.sieve
109915
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/enotify/execute/draft-rfc-ex5.sieve 1970-01-01 01:00:00.000000000 +0100
109916
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/enotify/execute/draft-rfc-ex5.sieve  2008-11-21 22:05:14.000000000 +0100
109917
 
@@ -0,0 +1,11 @@
109918
 
+require ["enotify"];
109919
 
+
109920
 
+if notify_method_capability
109921
 
+       "xmpp:tim@example.com?message;subject=SIEVE"
109922
 
+       "Online"
109923
 
+       "yes" {
109924
 
+       notify :importance "1" :message "You got mail"
109925
 
+               "xmpp:tim@example.com?message;subject=SIEVE";
109926
 
+} else {
109927
 
+       notify :message "You got mail" "tel:+14085551212";
109928
 
+}
109929
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/enotify/execute/draft-rfc-ex6.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/enotify/execute/draft-rfc-ex6.sieve
109930
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/enotify/execute/draft-rfc-ex6.sieve 1970-01-01 01:00:00.000000000 +0100
109931
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/enotify/execute/draft-rfc-ex6.sieve  2008-11-21 22:05:14.000000000 +0100
109932
 
@@ -0,0 +1,5 @@
109933
 
+require ["enotify", "variables"];
109934
 
+
109935
 
+set :encodeurl "body_param" "Safe body&evil=evilbody";
109936
 
+
109937
 
+notify "mailto:tim@example.com?body=${body_param}";
109938
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/enotify/execute/duplicates.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/enotify/execute/duplicates.sieve
109939
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/enotify/execute/duplicates.sieve    1970-01-01 01:00:00.000000000 +0100
109940
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/enotify/execute/duplicates.sieve     2009-01-21 23:50:11.000000000 +0100
109941
 
@@ -0,0 +1,4 @@
109942
 
+require "enotify";
109943
 
+
109944
 
+notify :message "Incoming stupidity." "mailto:stephan@rename-it.nl%2cstephan@drunksnipers.com%2cidiot@rename-it.nl";
109945
 
+notify :message "There it is." "mailto:tss@iki.fi%2cstephan@rename-it.nl%2cidiot@rename-it.nl%2cnico@vestingbar.nl%2cstephan@drunksnipers.com";
109946
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/enotify/execute.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/enotify/execute.svtest
109947
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/enotify/execute.svtest      1970-01-01 01:00:00.000000000 +0100
109948
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/enotify/execute.svtest       2009-01-21 23:50:11.000000000 +0100
109949
 
@@ -0,0 +1,99 @@
109950
 
+require "vnd.dovecot.testsuite";
109951
 
+require "relational";
109952
 
+
109953
 
+
109954
 
+/*
109955
 
+ * Execution testing (currently just meant to trigger any segfaults)
109956
 
+ */
109957
 
+
109958
 
+test "RFC Example 1" {
109959
 
+       if not test_script_compile "execute/draft-rfc-ex1.sieve" {
109960
 
+               test_fail "script compile failed";
109961
 
+       }
109962
 
+
109963
 
+       if not test_script_run {
109964
 
+               test_fail "script run failed";
109965
 
+       }
109966
 
+
109967
 
+       if not test_result_execute {
109968
 
+               test_fail "result execute failed";
109969
 
+       }
109970
 
+}
109971
 
+
109972
 
+test "RFC Example 2" {
109973
 
+       if not test_script_compile "execute/draft-rfc-ex2.sieve" {
109974
 
+               test_fail "script compile failed";
109975
 
+       }
109976
 
+
109977
 
+       if not test_script_run {
109978
 
+               test_fail "script execute failed";
109979
 
+       }
109980
 
+
109981
 
+       if not test_result_execute {
109982
 
+               test_fail "result execute failed";
109983
 
+       }
109984
 
+}
109985
 
+
109986
 
+/* tel: not supported
109987
 
+test "RFC Example 3" {
109988
 
+       if not test_script_compile "execute/draft-rfc-ex3.sieve" {
109989
 
+               test_fail "script compile failed";
109990
 
+       }
109991
 
+
109992
 
+       if not test_script_run {
109993
 
+               test_fail "script execute failed";
109994
 
+       }
109995
 
+
109996
 
+       if not test_result_execute {
109997
 
+               test_fail "result execute failed";
109998
 
+       }
109999
 
+}
110000
 
+*/
110001
 
+
110002
 
+/* tel: and xmmp: not supported
110003
 
+test "RFC Example 5" {
110004
 
+       if not test_script_compile "execute/draft-rfc-ex5.sieve" {
110005
 
+               test_fail "script compile failed";
110006
 
+       }
110007
 
+
110008
 
+       if not test_script_run {
110009
 
+               test_fail "script execute failed";
110010
 
+       }
110011
 
+
110012
 
+       if not test_result_execute {
110013
 
+               test_fail "result execute failed";
110014
 
+       }
110015
 
+}
110016
 
+*/
110017
 
+
110018
 
+test "RFC Example 6" {
110019
 
+       if not test_script_compile "execute/draft-rfc-ex6.sieve" {
110020
 
+               test_fail "script compile failed";
110021
 
+       }
110022
 
+
110023
 
+       if not test_script_run {
110024
 
+               test_fail "script execute failed";
110025
 
+       }
110026
 
+
110027
 
+       if not test_result_execute {
110028
 
+               test_fail "result execute failed";
110029
 
+       }
110030
 
+}
110031
 
+
110032
 
+test "Duplicate recipients" {
110033
 
+       if not test_script_compile "execute/duplicates.sieve" {
110034
 
+               test_fail "script compile failed";
110035
 
+       }
110036
 
+
110037
 
+       if not test_script_run {
110038
 
+               test_fail "script execute failed";
110039
 
+       }
110040
 
+
110041
 
+       if test_result :count "ne" "2" {
110042
 
+               test_fail "second notify action was discarded entirely";
110043
 
+       }
110044
 
+
110045
 
+       if not test_result_execute {
110046
 
+               test_fail "result execute failed";
110047
 
+       }
110048
 
+}
110049
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/enotify/mailto.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/enotify/mailto.svtest
110050
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/enotify/mailto.svtest       1970-01-01 01:00:00.000000000 +0100
110051
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/enotify/mailto.svtest        2009-07-21 13:08:06.000000000 +0200
110052
 
@@ -0,0 +1,302 @@
110053
 
+require "vnd.dovecot.testsuite";
110054
 
+require "enotify";
110055
 
+require "relational";
110056
 
+require "envelope";
110057
 
+require "comparator-i;ascii-numeric";
110058
 
+
110059
 
+/*
110060
 
+ * Simple test
110061
 
+ */
110062
 
+
110063
 
+test_set "message" text:
110064
 
+From: stephan@rename-it.nl
110065
 
+To: nico@vestingbar.nl
110066
 
+Subject: Frop!
110067
 
+
110068
 
+Klutsefluts.
110069
 
+.
110070
 
+;
110071
 
+
110072
 
+test "Simple" {
110073
 
+       notify "mailto:stephan@rename-it.nl";
110074
 
+
110075
 
+       if not test_result_execute {
110076
 
+               test_fail "failed to execute notify";
110077
 
+       }
110078
 
+
110079
 
+       test_message :smtp 0;
110080
 
+
110081
 
+       if not header :matches "Auto-Submitted" "auto-notified*" {
110082
 
+               test_fail "auto-submitted header set inappropriately";
110083
 
+       }
110084
 
+
110085
 
+       if not exists "X-Sieve" {
110086
 
+               test_fail "x-sieve header missing from outgoing message";
110087
 
+       }
110088
 
+}
110089
 
+
110090
 
+/*
110091
 
+ * Multiple recipients
110092
 
+ */
110093
 
+
110094
 
+test_result_reset;
110095
 
+
110096
 
+test_set "message" text:
110097
 
+From: stephan@rename-it.nl
110098
 
+To: nico@vestingbar.nl
110099
 
+Subject: Frop!
110100
 
+
110101
 
+Klutsefluts.
110102
 
+.
110103
 
+;
110104
 
+
110105
 
+test "Multiple recipients" {
110106
 
+       notify "mailto:timo@example.com%2cstephan@dovecot.org?cc=postmaster@vestingbar.nl&subject=Frop%20received";
110107
 
+
110108
 
+       if not test_result_execute {
110109
 
+               test_fail "failed to execute notify";
110110
 
+       }
110111
 
+
110112
 
+       test_message :smtp 0;
110113
 
+
110114
 
+       if not address :is "to" "timo@example.com" {
110115
 
+               test_fail "first To address missing";
110116
 
+       }
110117
 
+
110118
 
+       if not address :is "to" "stephan@dovecot.org" {
110119
 
+               test_fail "second To address missing";
110120
 
+       }
110121
 
+
110122
 
+       if not address :is "cc" "postmaster@vestingbar.nl" {
110123
 
+               test_fail "first Cc address missing";
110124
 
+       }
110125
 
+
110126
 
+       if not address :count "eq" :comparator "i;ascii-numeric" "to" "2" {
110127
 
+               test_fail "too many recipients in To header";
110128
 
+       } 
110129
 
+
110130
 
+       if not address :count "eq" :comparator "i;ascii-numeric" "cc" "1" {
110131
 
+               test_fail "too many recipients in Cc header";
110132
 
+       } 
110133
 
+
110134
 
+       if not header "subject" "Frop received" {
110135
 
+               test_fail "subject header set incorrectly";
110136
 
+       }
110137
 
+
110138
 
+       test_message :smtp 1;
110139
 
+
110140
 
+       if not header :matches "Auto-Submitted" "auto-notified*" {
110141
 
+               test_fail "auto-submitted header not found for second message";
110142
 
+       }
110143
 
+
110144
 
+       test_message :smtp 2;
110145
 
+
110146
 
+       if not header :matches "Auto-Submitted" "auto-notified*" {
110147
 
+               test_fail "auto-submitted header not found for third message";
110148
 
+       }
110149
 
+}
110150
 
+
110151
 
+/*
110152
 
+ * Duplicate recipients
110153
 
+ */
110154
 
+
110155
 
+test_result_reset;
110156
 
+
110157
 
+test_set "message" text:
110158
 
+From: stephan@rename-it.nl
110159
 
+To: nico@vestingbar.nl
110160
 
+Subject: Frop!
110161
 
+
110162
 
+Klutsefluts.
110163
 
+.
110164
 
+;
110165
 
+
110166
 
+test "Duplicate recipients" {
110167
 
+       notify "mailto:timo@example.com%2cstephan@dovecot.org?cc=stephan@dovecot.org";
110168
 
+       notify "mailto:stephan@rename-it.nl?cc=timo@example.com";
110169
 
+
110170
 
+       if not test_result_execute {
110171
 
+               test_fail "failed to execute notify";
110172
 
+       }
110173
 
+
110174
 
+       test_message :smtp 0;
110175
 
+
110176
 
+       if address "Cc" "stephan@dovecot.org" {
110177
 
+               test_fail "duplicate recipient not removed from first message";
110178
 
+       }
110179
 
+
110180
 
+       test_message :smtp 1;
110181
 
+
110182
 
+       if address "Cc" "timo@example.com" {
110183
 
+               test_fail "duplicate recipient not removed from second message";
110184
 
+       }
110185
 
+}
110186
 
+
110187
 
+
110188
 
+/*
110189
 
+ * Notifying on automated messages
110190
 
+ */
110191
 
+
110192
 
+test_result_reset;
110193
 
+
110194
 
+test_set "message" text:
110195
 
+From: stephan@rename-it.nl
110196
 
+To: nico@vestingbar.nl
110197
 
+Auto-submitted: auto-notify
110198
 
+Subject: Frop!
110199
 
+
110200
 
+Klutsefluts.
110201
 
+.
110202
 
+;
110203
 
+
110204
 
+test "Notifying on automated messages" {
110205
 
+       notify "mailto:stephan@rename-it.nl?cc=timo@example.com";
110206
 
+
110207
 
+       if not test_result_execute {
110208
 
+               test_fail "failed to execute notify";
110209
 
+       }
110210
 
+
110211
 
+       if test_message :smtp 0 {
110212
 
+               test_fail "notified of auto-submitted message";
110213
 
+       }
110214
 
+}
110215
 
+
110216
 
+/*
110217
 
+ * Envelope
110218
 
+ */
110219
 
+
110220
 
+test_set "message" text:
110221
 
+From: stephan@rename-it.nl
110222
 
+To: nico@vestingbar.nl
110223
 
+Subject: Frop!
110224
 
+
110225
 
+Klutsefluts.
110226
 
+.
110227
 
+;
110228
 
+
110229
 
+test_result_reset;
110230
 
+
110231
 
+test_set "envelope.from" "sirius@rename-it.nl";
110232
 
+test_set "envelope.to" "bertus@vestingbar.nl";
110233
 
+
110234
 
+test "Envelope" {
110235
 
+       notify "mailto:stephan@rename-it.nl?cc=timo@example.com";
110236
 
+
110237
 
+       if not test_result_execute {
110238
 
+               test_fail "failed to execute notify";
110239
 
+       }
110240
 
+
110241
 
+       test_message :smtp 0;
110242
 
+
110243
 
+       if not envelope :localpart :is "from" "postmaster" {
110244
 
+               test_fail "envelope sender set incorrectly";
110245
 
+       }
110246
 
+
110247
 
+       if not envelope :is "to" "stephan@rename-it.nl" {
110248
 
+               test_fail "envelope sender set incorrectly";
110249
 
+       }
110250
 
+
110251
 
+       test_message :smtp 1;
110252
 
+
110253
 
+       if not envelope :localpart :is "from" "postmaster" {
110254
 
+               test_fail "envelope sender set incorrectly";
110255
 
+       }
110256
 
+
110257
 
+       if not envelope :is "to" "timo@example.com" {
110258
 
+               test_fail "envelope sender set incorrectly";
110259
 
+       }       
110260
 
+}
110261
 
+
110262
 
+/* 
110263
 
+ * Envelope :from 
110264
 
+ */
110265
 
+
110266
 
+test_set "message" text:
110267
 
+From: stephan@rename-it.nl
110268
 
+To: nico@vestingbar.nl
110269
 
+Subject: Frop!
110270
 
+
110271
 
+Klutsefluts.
110272
 
+.
110273
 
+;
110274
 
+
110275
 
+test_set "envelope.from" "sirius@rename-it.nl";
110276
 
+test_set "envelope.to" "bertus@vestingbar.nl";
110277
 
+
110278
 
+test_result_reset;
110279
 
+
110280
 
+test "Envelope :from" {
110281
 
+       notify :from "nico@vestingbar.nl"
110282
 
+               "mailto:stephan@rename-it.nl?cc=timo@example.com";
110283
 
+
110284
 
+       if not test_result_execute {
110285
 
+               test_fail "failed to execute notify";
110286
 
+       }
110287
 
+
110288
 
+       test_message :smtp 0;
110289
 
+
110290
 
+       if not envelope :is "from" "nico@vestingbar.nl" {
110291
 
+               test_fail "envelope sender set incorrectly";
110292
 
+       }
110293
 
+
110294
 
+       if not envelope :is "to" "stephan@rename-it.nl" {
110295
 
+               test_fail "envelope sender set incorrectly";
110296
 
+       }
110297
 
+
110298
 
+       test_message :smtp 1;
110299
 
+
110300
 
+       if not envelope :is "from" "nico@vestingbar.nl" {
110301
 
+               test_fail "envelope sender set incorrectly";
110302
 
+       }
110303
 
+
110304
 
+       if not envelope :is "to" "timo@example.com" {
110305
 
+               test_fail "envelope sender set incorrectly";
110306
 
+       }       
110307
 
+}
110308
 
+
110309
 
+/* 
110310
 
+ * Envelope <> 
110311
 
+ */
110312
 
+
110313
 
+test_set "message" text:
110314
 
+From: stephan@rename-it.nl
110315
 
+To: nico@vestingbar.nl
110316
 
+Subject: Frop!
110317
 
+
110318
 
+Klutsefluts.
110319
 
+.
110320
 
+;
110321
 
+
110322
 
+test_set "envelope.from" "<>";
110323
 
+test_set "envelope.to" "bertus@vestingbar.nl";
110324
 
+
110325
 
+test_result_reset;
110326
 
+
110327
 
+test "Envelope <>" {
110328
 
+       notify :from "nico@vestingbar.nl"
110329
 
+               "mailto:stephan@rename-it.nl?cc=timo@example.com";
110330
 
+
110331
 
+       if not test_result_execute {
110332
 
+               test_fail "failed to execute notify";
110333
 
+       }
110334
 
+
110335
 
+       test_message :smtp 0;
110336
 
+
110337
 
+       if not envelope :is "from" "" {
110338
 
+               test_fail "envelope sender set incorrectly";
110339
 
+       }
110340
 
+
110341
 
+       if not envelope :is "to" "stephan@rename-it.nl" {
110342
 
+               test_fail "envelope sender set incorrectly";
110343
 
+       }
110344
 
+
110345
 
+       test_message :smtp 1;
110346
 
+
110347
 
+       if not envelope :is "from" "" {
110348
 
+               test_fail "envelope sender set incorrectly";
110349
 
+       }
110350
 
+
110351
 
+       if not envelope :is "to" "timo@example.com" {
110352
 
+               test_fail "envelope sender set incorrectly";
110353
 
+       }       
110354
 
+}
110355
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/enotify/notify_method_capability.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/enotify/notify_method_capability.svtest
110356
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/enotify/notify_method_capability.svtest     1970-01-01 01:00:00.000000000 +0100
110357
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/enotify/notify_method_capability.svtest      2009-01-06 00:15:52.000000000 +0100
110358
 
@@ -0,0 +1,12 @@
110359
 
+require "vnd.dovecot.testsuite";
110360
 
+require "enotify";
110361
 
+
110362
 
+test "Mailto" {
110363
 
+       if not notify_method_capability :is "mailto:stephan@rename-it.nl" "online" "maybe" {
110364
 
+               test_fail "test should have matched";
110365
 
+       }
110366
 
+
110367
 
+       if notify_method_capability :is "mailto:stephan@rename-it.nl" "online" "yes" {
110368
 
+               test_fail "test should not have matched";
110369
 
+       }
110370
 
+}
110371
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/enotify/valid_notify_method.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/enotify/valid_notify_method.svtest
110372
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/enotify/valid_notify_method.svtest  1970-01-01 01:00:00.000000000 +0100
110373
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/enotify/valid_notify_method.svtest   2009-01-06 00:15:52.000000000 +0100
110374
 
@@ -0,0 +1,31 @@
110375
 
+require "vnd.dovecot.testsuite";
110376
 
+
110377
 
+require "enotify";
110378
 
+
110379
 
+test "Mailto: invalid header name" {
110380
 
+       if valid_notify_method 
110381
 
+               "mailto:stephan@rename-it.nl?header:=frop" {
110382
 
+               test_fail "invalid uri accepted";
110383
 
+       }
110384
 
+}
110385
 
+
110386
 
+test "Mailto: invalid recipient" {
110387
 
+       if valid_notify_method 
110388
 
+               "mailto:stephan%23rename-it.nl" {
110389
 
+               test_fail "invalid uri accepted";
110390
 
+       }
110391
 
+}
110392
 
+
110393
 
+test "Mailto: invalid to header recipient" {
110394
 
+       if valid_notify_method
110395
 
+               "mailto:stephan@rename-it.nl?to=nico%23vestingbar.nl" {
110396
 
+               test_fail "invalid uri accepted";
110397
 
+       }
110398
 
+}
110399
 
+
110400
 
+test "Mailto: valid URI" {
110401
 
+       if not valid_notify_method
110402
 
+               "mailto:stephan@rename-it.nl" {
110403
 
+               test_fail "valid uri denied";
110404
 
+       }
110405
 
+}
110406
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/envelope.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/envelope.svtest
110407
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/envelope.svtest     1970-01-01 01:00:00.000000000 +0100
110408
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/envelope.svtest      2008-08-01 16:26:09.000000000 +0200
110409
 
@@ -0,0 +1,218 @@
110410
 
+require "vnd.dovecot.testsuite";
110411
 
+
110412
 
+require "envelope";
110413
 
+
110414
 
+/*
110415
 
+ * Empty envelope addresses
110416
 
+ */
110417
 
+
110418
 
+test "Envelope - from empty" {
110419
 
+       /* Return_path: "" */
110420
 
+
110421
 
+       test_set "envelope.from" "";
110422
 
+
110423
 
+       if not envelope :all :is "from" "" {
110424
 
+               test_fail "failed to (:all :is)-match a \"\" return path";
110425
 
+       }
110426
 
+
110427
 
+       if not envelope :all :contains "from" "" {
110428
 
+               test_fail "failed to (:all :contains)-match a \"\" return path";
110429
 
+       }
110430
 
+
110431
 
+       if not envelope :domain :is "from" "" {
110432
 
+               test_fail "failed to (:domain :is)-match a \"\" return path";
110433
 
+       }
110434
 
+
110435
 
+       if not envelope :domain :contains "from" "" {
110436
 
+               test_fail "failed to (:domain :contains)-match a \"\" return path";
110437
 
+       }
110438
 
+
110439
 
+       /* Return path: <> */
110440
 
+
110441
 
+       test_set "envelope.from" "<>";
110442
 
+
110443
 
+       if not envelope :all :is "from" "" {
110444
 
+               test_fail "failed to (:all :is)-match a <> return path";
110445
 
+       }
110446
 
+
110447
 
+       if not envelope :all :contains "from" "" {
110448
 
+               test_fail "failed to (:all :contains)-match a <> return path";
110449
 
+       }
110450
 
+
110451
 
+       if not envelope :domain :is "from" "" {
110452
 
+               test_fail "failed to (:domain :is)-match a <> return path";
110453
 
+       }
110454
 
+
110455
 
+       if not envelope :domain :contains "from" "" {
110456
 
+               test_fail "failed to (:domain :contains)-match a <> return path";
110457
 
+       }
110458
 
+
110459
 
+       if envelope :all :is "from" "nico@vestingbar.nl" {
110460
 
+               test_fail "envelope test matches nonsense";
110461
 
+       }
110462
 
+
110463
 
+       /* Forward path: <> */
110464
 
+
110465
 
+    test_set "envelope.to" "<>";
110466
 
+
110467
 
+    if envelope :all :is "to" "" {
110468
 
+        test_fail "successfully matched a <> forward path, which is wrong";
110469
 
+    }
110470
 
+}
110471
 
+
110472
 
+/*
110473
 
+ * Invalid envelope addresses
110474
 
+ */
110475
 
+
110476
 
+test "Envelope - invalid paths" {
110477
 
+    /* Return_path: "hutsefluts" */
110478
 
+
110479
 
+       test_set "envelope.from" "hutsefluts";
110480
 
+       test_set "envelope.to" "knurft";
110481
 
+
110482
 
+       if not envelope :all :is "from" "hutsefluts" {
110483
 
+               test_fail ":all address part mangled syntactically incorrect reverse path";
110484
 
+       }
110485
 
+
110486
 
+       if envelope :localpart :is "from" "hutsefluts" {
110487
 
+        test_fail ":localpart address part matched syntactically incorrect reverse path";
110488
 
+    }
110489
 
+
110490
 
+       if envelope :domain :contains "from" "" {
110491
 
+        test_fail ":domain address part matched syntactically incorrect reverse path";
110492
 
+    }
110493
 
+
110494
 
+       if not envelope :all :is "to" "knurft" {
110495
 
+               test_fail ":all address part mangled syntactically incorrect forward path";
110496
 
+       }
110497
 
+
110498
 
+       if envelope :localpart :is "to" "knurft" {
110499
 
+        test_fail ":localpart address part matched syntactically incorrect forward path";
110500
 
+    }
110501
 
+
110502
 
+       if envelope :domain :contains "to" "" {
110503
 
+        test_fail ":domain address part matched syntactically incorrect forward path";
110504
 
+    }
110505
 
+}
110506
 
+
110507
 
+/*
110508
 
+ * Syntax errors 
110509
 
+ */
110510
 
+
110511
 
+test "Envelope - syntax errors" {
110512
 
+       /* Control */
110513
 
+       test_set "envelope.from" "<stephan@rename-it.nl>";
110514
 
+       if not envelope :all :is "from" "stephan@rename-it.nl" {
110515
 
+               test_fail "correct control test failed";
110516
 
+       }
110517
 
+
110518
 
+       # Duplicate <
110519
 
+       test_set "envelope.from" "<<stephan@rename-it.nl>";
110520
 
+    if envelope :all :is "from" "stephan@rename-it.nl" {
110521
 
+        test_fail "failed to recognize syntax error";
110522
 
+    }
110523
 
+
110524
 
+       # Spurious >
110525
 
+       test_set "envelope.from" "stephan@rename-it.nl>";
110526
 
+    if envelope :all :is "from" "stephan@rename-it.nl" {
110527
 
+        test_fail "failed to recognize syntax error";
110528
 
+    }
110529
 
+
110530
 
+       # Missing >
110531
 
+       test_set "envelope.from" "<stephan@rename-it.nl";
110532
 
+    if envelope :all :is "from" "stephan@rename-it.nl" {
110533
 
+        test_fail "failed to recognize syntax error";
110534
 
+    }
110535
 
+       
110536
 
+       # No @
110537
 
+       test_set "envelope.from" "<stephan rename-it.nl>";
110538
 
+    if envelope :domain :contains "from" "" {
110539
 
+        test_fail "failed to recognize syntax error";
110540
 
+    }
110541
 
+
110542
 
+       # Duplicate @
110543
 
+       test_set "envelope.from" "<stephan@@rename-it.nl>";
110544
 
+    if envelope :domain :contains "from" "" {
110545
 
+        test_fail "failed to recognize syntax error";
110546
 
+    }
110547
 
+}
110548
 
+
110549
 
+/*
110550
 
+ * Ignoring source routes
110551
 
+ */
110552
 
+
110553
 
+test "Envelope - source route" {
110554
 
+       /* Single */
110555
 
+       test_set "envelope.from" "<@cola.rename-it.nl:stephan@rename-it.nl>";
110556
 
+       if not envelope :localpart :is "from" "stephan" {
110557
 
+               test_fail "parsing path with source route (single) failed";
110558
 
+
110559
 
+       }
110560
 
+
110561
 
+       /* Dual */
110562
 
+       test_set "envelope.from" "<@cola.rename-it.nl,@mx.utwente.nl:stephan@rename-it.nl>";
110563
 
+       if not envelope :localpart :is "from" "stephan" {
110564
 
+               test_fail "parsing path with source route (dual) failed";
110565
 
+
110566
 
+       }
110567
 
+       
110568
 
+       /* Multiple */
110569
 
+       test_set "envelope.from" "<@cola.rename-it.nl,@mx.utwente.nl,@smtp.iki.fi:stephan@rename-it.nl>";
110570
 
+       if not envelope :localpart :is "from" "stephan" {
110571
 
+               test_fail "parsing path with source route (multiple) failed";
110572
 
+
110573
 
+       }
110574
 
+
110575
 
+       /* Bare */
110576
 
+       test_set "envelope.from" "@cola.rename-it.nl,@mx.utwente.nl,@smtp.iki.fi:stephan@rename-it.nl";
110577
 
+       if not envelope :domain :is "from" "rename-it.nl" {
110578
 
+               test_fail "parsing path with source route (bare) failed";
110579
 
+       }       
110580
 
+
110581
 
+       /* Whitespace */
110582
 
+       test_set "envelope.from" "   < @ cola . rename-it . nl , @ mx . utwente .   nl ,        @ smtp  .  iki  . fi    :   stephan             @     rename-it   .             nl >  ";
110583
 
+    if not envelope :domain :is "from" "rename-it.nl" {
110584
 
+        test_fail "parsing path with source route (whitespace) failed";
110585
 
+    }
110586
 
+}
110587
 
+
110588
 
+test "Envelope - source route errors" {
110589
 
+       test_set "envelope.to" "<cola.rename-it.nl:stephan@rename-it.nl>";
110590
 
+       if envelope :domain :contains "to" "" {
110591
 
+               test_fail "parsing syntactically incorrect path should have failed (1)";
110592
 
+       }
110593
 
+
110594
 
+       test_set "envelope.to" "<@.rename-it.nl:stephan@rename-it.nl>";
110595
 
+       if envelope :domain :contains "to" "" {
110596
 
+               test_fail "parsing syntactically incorrect path should have failed (2)";
110597
 
+       }
110598
 
+
110599
 
+       test_set "envelope.to" "<@cola..nl:stephan@rename-it.nl>";
110600
 
+       if envelope :domain :contains "to" "" {
110601
 
+               test_fail "parsing syntactically incorrect path should have failed (3)";
110602
 
+       }
110603
 
+
110604
 
+       test_set "envelope.to" "<@cola.rename-it.nlstephan@rename-it.nl>";
110605
 
+       if envelope :domain :contains "to" "" {
110606
 
+               test_fail "parsing syntactically incorrect path should have failed (4)";
110607
 
+       }
110608
 
+
110609
 
+       test_set "envelope.to" "<@cola.rename-it.nl@mx.utwente.nl:stephan@rename-it.nl>";
110610
 
+       if envelope :domain :contains "to" "" {
110611
 
+               test_fail "parsing syntactically incorrect path should have failed (5)";
110612
 
+       }
110613
 
+
110614
 
+       test_set "envelope.to" "<@cola.rename-it.nl,mx.utwente.nl:stephan@rename-it.nl>";
110615
 
+       if envelope :domain :contains "to" "" {
110616
 
+               test_fail "parsing syntactically incorrect path should have failed (6)";
110617
 
+       }
110618
 
+
110619
 
+       test_set "envelope.to" "<@cola.rename-it.nl,@mx.utwente.nl,stephan@rename-it.nl>";
110620
 
+       if envelope :domain :contains "to" "" {
110621
 
+               test_fail "parsing syntactically incorrect path should have failed (7)";
110622
 
+       }
110623
 
+
110624
 
+       if not envelope :all :is "to" "<@cola.rename-it.nl,@mx.utwente.nl,stephan@rename-it.nl>" {
110625
 
+               test_fail ":all address part mangled syntactically incorrect path";
110626
 
+       }
110627
 
+}
110628
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/environment/basic.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/environment/basic.svtest
110629
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/environment/basic.svtest    1970-01-01 01:00:00.000000000 +0100
110630
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/environment/basic.svtest     2009-04-13 21:35:39.000000000 +0200
110631
 
@@ -0,0 +1,26 @@
110632
 
+require "vnd.dovecot.testsuite";
110633
 
+require "environment";
110634
 
+
110635
 
+test "Name" {
110636
 
+       if not environment :contains "name" "dovecot" {
110637
 
+               test_fail "name environment returned invalid value";
110638
 
+       }
110639
 
+
110640
 
+       if not environment :contains "name" "sieve" {
110641
 
+               test_fail "name environment returned invalid value";
110642
 
+       }
110643
 
+
110644
 
+       if environment :contains "name" "cyrus" {
110645
 
+               test_fail "something is definitely wrong here";
110646
 
+       }
110647
 
+
110648
 
+       if not environment :is :comparator "i;octet" "name" "Dovecot Sieve" {
110649
 
+               test_fail "name environment does not match exactly with what is expected";
110650
 
+       }
110651
 
+}
110652
 
+
110653
 
+test "Host" {
110654
 
+       if not environment "host" "testsuite.example.com" {
110655
 
+               test_fail "wrong testsuite hostname";
110656
 
+       }
110657
 
+}
110658
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/environment/rfc.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/environment/rfc.svtest
110659
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/environment/rfc.svtest      1970-01-01 01:00:00.000000000 +0100
110660
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/environment/rfc.svtest       2009-04-13 21:35:39.000000000 +0200
110661
 
@@ -0,0 +1,28 @@
110662
 
+require "vnd.dovecot.testsuite";
110663
 
+require "environment";
110664
 
+require "relational";
110665
 
+
110666
 
+test "Non-existant" {
110667
 
+       if environment :contains "nonsense" "" {
110668
 
+               test_fail "matched unknown environment item";   
110669
 
+       }
110670
 
+}
110671
 
+
110672
 
+test "Exists" {
110673
 
+       if not environment :contains "version" "" {
110674
 
+               test_fail "failed to match known environment item";
110675
 
+       }
110676
 
+}
110677
 
+
110678
 
+test "Count" {
110679
 
+       if anyof (
110680
 
+                       environment :count "eq" "nonsense" "0",
110681
 
+                       environment :count "eq" "nonsense" "1"
110682
 
+               ) {
110683
 
+               test_fail "count should not match unknown environment item";
110684
 
+       }
110685
 
+               
110686
 
+       if not environment :count "eq" "host" "1" {
110687
 
+               test_fail "count of non-empty environment should be 1";
110688
 
+       }
110689
 
+}
110690
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/imap4flags/basic.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/imap4flags/basic.svtest
110691
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/imap4flags/basic.svtest     1970-01-01 01:00:00.000000000 +0100
110692
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/imap4flags/basic.svtest      2009-08-02 10:30:31.000000000 +0200
110693
 
@@ -0,0 +1,108 @@
110694
 
+require "vnd.dovecot.testsuite";
110695
 
+
110696
 
+require "imap4flags";
110697
 
+require "relational";
110698
 
+require "variables";
110699
 
+require "comparator-i;ascii-numeric";
110700
 
+
110701
 
+/*
110702
 
+ * Basic functionality tests
110703
 
+ */
110704
 
+
110705
 
+test "Hasflag empty" {
110706
 
+       if hasflag "\\Seen" {
110707
 
+               test_fail "hasflag sees initial \\seen flag were there should be none";
110708
 
+       }
110709
 
+       if hasflag "\\draft" {
110710
 
+               test_fail "hasflag sees initial \\draft flag were there should be none";
110711
 
+       }
110712
 
+       if hasflag "\\recent" {
110713
 
+               test_fail "hasflag sees initial \\recent flag were there should be none";
110714
 
+       }
110715
 
+       if hasflag "\\flagged" {
110716
 
+               test_fail "hasflag sees initial \\flagged flag were there should be none";
110717
 
+       }
110718
 
+       if hasflag "\\answered" {
110719
 
+               test_fail "hasflag sees initial \\answered flag were there should be none";
110720
 
+       }
110721
 
+       if hasflag "\\deleted" {
110722
 
+               test_fail "hasflag sees initial \\deleted flag were there should be none";
110723
 
+       }
110724
 
+
110725
 
+       if hasflag :comparator "i;ascii-numeric" :count "ge" "1" {
110726
 
+               test_fail "hasflag sees initial flags were there should be none";
110727
 
+       }
110728
 
+}
110729
 
+
110730
 
+test "Setflag; Hasflag one" {
110731
 
+       setflag "\\seen";
110732
 
+
110733
 
+       if not hasflag "\\Seen" {
110734
 
+               test_fail "flag not set of hasflag fails to see it";
110735
 
+       }
110736
 
+
110737
 
+       if not hasflag :comparator "i;ascii-numeric" :count "eq" "1" {
110738
 
+               test_fail "flag not set of hasflag fails to see it";
110739
 
+       }
110740
 
+
110741
 
+       if hasflag "$Nonsense" {
110742
 
+               test_fail "hasflag sees other flag that the one set";
110743
 
+       }
110744
 
+}
110745
 
+
110746
 
+test "Hasflag; duplicates" {
110747
 
+       set "Flags" "A B C D E F A B C D E F";
110748
 
+
110749
 
+       if hasflag :comparator "i;ascii-numeric" :count "gt" "Flags" "6" {
110750
 
+               test_fail "hasflag must ignore duplicates";
110751
 
+       }
110752
 
+
110753
 
+       if not hasflag :comparator "i;ascii-numeric" :count "eq" "Flags" "6" {
110754
 
+               test_fail "hasflag :count gives strange results";
110755
 
+       }
110756
 
+}
110757
 
+
110758
 
+test "Flag operations" {
110759
 
+       setflag "A";
110760
 
+
110761
 
+       if not hasflag "A" {
110762
 
+               test_fail "hasflag misses set flag";
110763
 
+       }
110764
 
+
110765
 
+       if hasflag :comparator "i;ascii-numeric" :count "gt" "1" {
110766
 
+               test_fail "hasflag sees more than one flag";
110767
 
+       }
110768
 
+
110769
 
+       addflag "B";
110770
 
+
110771
 
+       if not hasflag "B" {
110772
 
+               test_fail "flag \"B\" not added";
110773
 
+       }
110774
 
+       
110775
 
+       if not hasflag "A" {
110776
 
+               test_fail "flag \"A\" not retained";
110777
 
+       }
110778
 
+
110779
 
+       if hasflag :comparator "i;ascii-numeric" :count "gt" "2" {
110780
 
+                test_fail "hasflag sees more than two flags";
110781
 
+        }
110782
 
+
110783
 
+       addflag ["C", "D", "E F"];      
110784
 
+
110785
 
+       if not hasflag :comparator "i;ascii-numeric" :count "eq" "6" {
110786
 
+                test_fail "hasflag sees more than two flags";
110787
 
+        }
110788
 
+
110789
 
+       removeflag ["D"];
110790
 
+
110791
 
+       if not hasflag :comparator "i;ascii-numeric" :count "eq" "5" {
110792
 
+                test_fail "hasflag sees more than two flags";
110793
 
+        }      
110794
 
+       
110795
 
+       if hasflag "D" {
110796
 
+               test_fail "removed flag still present";
110797
 
+       }
110798
 
+}
110799
 
+
110800
 
+
110801
 
+
110802
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/imap4flags/errors/imapflags.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/imap4flags/errors/imapflags.sieve
110803
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/imap4flags/errors/imapflags.sieve   1970-01-01 01:00:00.000000000 +0100
110804
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/imap4flags/errors/imapflags.sieve    2009-02-04 22:48:19.000000000 +0100
110805
 
@@ -0,0 +1,4 @@
110806
 
+require "imapflags";
110807
 
+require "imap4flags";
110808
 
+
110809
 
+addflag "\\flagged";
110810
 
Binary files dovecot-1.2.4/dovecot-libsieve/tests/extensions/imap4flags/errors/imapflags.svbin and dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/imap4flags/errors/imapflags.svbin differ
110811
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/imap4flags/errors.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/imap4flags/errors.svtest
110812
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/imap4flags/errors.svtest    1970-01-01 01:00:00.000000000 +0100
110813
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/imap4flags/errors.svtest     2009-02-04 23:40:19.000000000 +0100
110814
 
@@ -0,0 +1,14 @@
110815
 
+require "vnd.dovecot.testsuite";
110816
 
+
110817
 
+require "comparator-i;ascii-numeric";
110818
 
+require "relational";
110819
 
+
110820
 
+test "Depricated imapflags extension used with imap4flags" {
110821
 
+       if test_script_compile "errors/imapflags.sieve" {
110822
 
+               test_fail "compile should have failed";
110823
 
+       }
110824
 
+
110825
 
+       if not test_error :count "eq" :comparator "i;ascii-numeric" "2" {
110826
 
+               test_fail "wrong number of errors reported";
110827
 
+       }
110828
 
+}
110829
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/imap4flags/execute/flags-side-effect.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/imap4flags/execute/flags-side-effect.sieve
110830
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/imap4flags/execute/flags-side-effect.sieve  1970-01-01 01:00:00.000000000 +0100
110831
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/imap4flags/execute/flags-side-effect.sieve   2009-02-04 21:30:41.000000000 +0100
110832
 
@@ -0,0 +1,18 @@
110833
 
+require "imap4flags"; 
110834
 
+require "fileinto";
110835
 
+
110836
 
+/*
110837
 
+ * When keep/fileinto is used multiple times in a script and duplicate 
110838
 
+ * message elimination is performed, the last flag list value MUST win.
110839
 
+ */
110840
 
+
110841
 
+setflag "IMPLICIT";
110842
 
+
110843
 
+fileinto :flags "\\Seen \\Draft" "INBOX.Junk";
110844
 
+fileinto :flags "NONSENSE" "INBOX.Junk";
110845
 
+
110846
 
+keep;
110847
 
+keep :flags "\\Seen";
110848
 
+
110849
 
+fileinto :flags "\\Seen" "Inbox.Nonsense";
110850
 
+fileinto "Inbox.Nonsense";
110851
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/imap4flags/execute/imapflags.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/imap4flags/execute/imapflags.sieve
110852
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/imap4flags/execute/imapflags.sieve  1970-01-01 01:00:00.000000000 +0100
110853
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/imap4flags/execute/imapflags.sieve   2009-02-05 00:20:18.000000000 +0100
110854
 
@@ -0,0 +1,7 @@
110855
 
+require "imapflags";
110856
 
+
110857
 
+mark;
110858
 
+unmark;
110859
 
+mark;
110860
 
+
110861
 
+addflag "$label1";
110862
 
Binary files dovecot-1.2.4/dovecot-libsieve/tests/extensions/imap4flags/execute/imapflags.svbin and dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/imap4flags/execute/imapflags.svbin differ
110863
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/imap4flags/execute.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/imap4flags/execute.svtest
110864
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/imap4flags/execute.svtest   1970-01-01 01:00:00.000000000 +0100
110865
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/imap4flags/execute.svtest    2009-07-31 17:34:58.000000000 +0200
110866
 
@@ -0,0 +1,22 @@
110867
 
+require "vnd.dovecot.testsuite";
110868
 
+
110869
 
+/*
110870
 
+ * Execution testing (currently just meant to trigger any segfaults)
110871
 
+ */
110872
 
+
110873
 
+test_mailbox :create "INBOX.Junk";
110874
 
+test_mailbox :create "INBOX.Nonsense";
110875
 
+
110876
 
+test "Flags Side Effect" {
110877
 
+       if not test_script_compile "execute/flags-side-effect.sieve" {
110878
 
+               test_fail "script compile failed";
110879
 
+       }
110880
 
+
110881
 
+       if not test_script_run {
110882
 
+               test_fail "script execute failed";
110883
 
+       }
110884
 
+
110885
 
+       if not test_result_execute {
110886
 
+               test_fail "result execute failed";      
110887
 
+       }
110888
 
+}
110889
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/imap4flags/flagstore.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/imap4flags/flagstore.svtest
110890
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/imap4flags/flagstore.svtest 1970-01-01 01:00:00.000000000 +0100
110891
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/imap4flags/flagstore.svtest  2009-08-02 14:39:59.000000000 +0200
110892
 
@@ -0,0 +1,146 @@
110893
 
+require "vnd.dovecot.testsuite";
110894
 
+require "fileinto";
110895
 
+require "imap4flags";
110896
 
+require "relational";
110897
 
+require "comparator-i;ascii-numeric";
110898
 
+require "mailbox";
110899
 
+
110900
 
+test_set "message" text:
110901
 
+From: Henry von Flockenstoffen <henry@example.com>
110902
 
+To: Dieter von Ausburg <dieter@example.com>
110903
 
+Subject: Test message.
110904
 
+
110905
 
+Test message.
110906
 
+.
110907
 
+;
110908
 
+
110909
 
+test "Basic" {
110910
 
+    if hasflag :comparator "i;ascii-numeric" :count "ge" "1" {
110911
 
+        test_fail "some flags or keywords are already set";
110912
 
+    }
110913
 
+       
110914
 
+       setflag "$label1 \\answered";
110915
 
+
110916
 
+       fileinto :create "Uninteresting";
110917
 
+
110918
 
+       if not test_result_execute {
110919
 
+               test_fail "failed to execute first result";
110920
 
+       }
110921
 
+
110922
 
+       test_result_reset;
110923
 
+
110924
 
+       setflag "\\draft \\seen Junk";
110925
 
+
110926
 
+       fileinto "Uninteresting";
110927
 
+
110928
 
+       if not test_result_execute {
110929
 
+               test_fail "failed to execute second result";
110930
 
+       }
110931
 
+
110932
 
+       test_result_reset;
110933
 
+
110934
 
+       fileinto :flags "\\flagged" "Uninteresting";
110935
 
+
110936
 
+    if not test_result_execute {
110937
 
+        test_fail "failed to execute third result";
110938
 
+    }
110939
 
+
110940
 
+    test_result_reset;
110941
 
+
110942
 
+       test_message :folder "Uninteresting" 0;
110943
 
+
110944
 
+       if not hasflag "$label1 \\answered" {
110945
 
+               test_fail "flags not stored for first message";
110946
 
+       }
110947
 
+
110948
 
+       if not hasflag :comparator "i;ascii-numeric" :count "eq" "2" {
110949
 
+        test_fail "invalid number of flags set for first message";
110950
 
+    }
110951
 
+
110952
 
+    test_result_reset;
110953
 
+
110954
 
+       test_message :folder "Uninteresting" 1;
110955
 
+
110956
 
+    if not hasflag "\\draft \\seen Junk" {
110957
 
+        test_fail "flags not stored for second message";
110958
 
+    }
110959
 
+
110960
 
+       if not hasflag :comparator "i;ascii-numeric" :count "eq" "3" {
110961
 
+        test_fail "invalid number of flags set for second message";
110962
 
+    }
110963
 
+
110964
 
+    test_result_reset;
110965
 
+
110966
 
+       test_message :folder "Uninteresting" 2;
110967
 
+
110968
 
+    if not hasflag "\\flagged" {
110969
 
+        test_fail "flags not stored for third message";
110970
 
+    }
110971
 
+
110972
 
+       if not hasflag :comparator "i;ascii-numeric" :count "eq" "1" {
110973
 
+        test_fail "invalid number of flags set for third message";
110974
 
+    }
110975
 
+}
110976
 
+
110977
 
+test_result_reset;
110978
 
+test_set "message" text:
110979
 
+From: Henry von Flockenstoffen <henry@example.com>
110980
 
+To: Dieter von Ausburg <dieter@example.com>
110981
 
+Subject: Test message.
110982
 
+
110983
 
+Test message.
110984
 
+.
110985
 
+;
110986
 
+
110987
 
+test "Flag changes between stores" {
110988
 
+    if hasflag :comparator "i;ascii-numeric" :count "ge" "1" {
110989
 
+        test_fail "some flags or keywords are already set";
110990
 
+    }
110991
 
+       
110992
 
+       setflag "$label1 \\answered";
110993
 
+       fileinto :create "FolderA";
110994
 
+
110995
 
+       setflag "$label2";
110996
 
+       fileinto :create "FolderB";
110997
 
+
110998
 
+       fileinto :create :flags "\\seen \\draft \\flagged" "FolderC";
110999
 
+
111000
 
+       if not test_result_execute {
111001
 
+               test_fail "failed to execute first result";
111002
 
+       }
111003
 
+
111004
 
+       test_result_reset;
111005
 
+       test_message :folder "FolderA" 0;
111006
 
+
111007
 
+       if not hasflag "\\answered $label1" {
111008
 
+               test_fail "flags not stored for first message";
111009
 
+       }
111010
 
+
111011
 
+       if not hasflag :comparator "i;ascii-numeric" :count "eq" "2" {
111012
 
+        test_fail "invalid number of flags set for first message";
111013
 
+    }
111014
 
+
111015
 
+    test_result_reset;
111016
 
+       test_message :folder "FolderB" 0;
111017
 
+
111018
 
+    if not hasflag "$label2" {
111019
 
+        test_fail "flag not stored for second message";
111020
 
+    }
111021
 
+
111022
 
+       if not hasflag :comparator "i;ascii-numeric" :count "eq" "1" {
111023
 
+        test_fail "invalid number of flags set for second message";
111024
 
+    }
111025
 
+
111026
 
+    test_result_reset;
111027
 
+       test_message :folder "FolderC" 0;
111028
 
+
111029
 
+    if not hasflag "\\seen \\flagged \\draft" {
111030
 
+        test_fail "flags not stored for third message";
111031
 
+    }
111032
 
+
111033
 
+       if not hasflag :comparator "i;ascii-numeric" :count "eq" "3" {
111034
 
+        test_fail "invalid number of flags set for third message";
111035
 
+    }
111036
 
+}
111037
 
+
111038
 
+
111039
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/imap4flags/hasflag.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/imap4flags/hasflag.svtest
111040
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/imap4flags/hasflag.svtest   1970-01-01 01:00:00.000000000 +0100
111041
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/imap4flags/hasflag.svtest    2009-08-02 10:30:48.000000000 +0200
111042
 
@@ -0,0 +1,91 @@
111043
 
+require "vnd.dovecot.testsuite";
111044
 
+
111045
 
+require "imap4flags";
111046
 
+require "relational";
111047
 
+require "variables";
111048
 
+require "comparator-i;ascii-numeric";
111049
 
+
111050
 
+/*
111051
 
+ * Generic tests
111052
 
+ */
111053
 
+
111054
 
+test "Ignoring \"\"" {
111055
 
+       setflag "";
111056
 
+
111057
 
+       if hasflag "" {
111058
 
+               test_fail "hasflag fails to ignore empty string";
111059
 
+       }
111060
 
+}
111061
 
+
111062
 
+/*
111063
 
+ * Variables
111064
 
+ */
111065
 
+
111066
 
+test "Multiple variables" {
111067
 
+       setflag "A" "Aflag";
111068
 
+       setflag "B" "Bflag";
111069
 
+       setflag "C" "Cflag";
111070
 
+
111071
 
+       if not hasflag ["a", "b", "c"] ["Bflag"] {
111072
 
+               test_fail "hasflag failed to match multiple flags variables";
111073
 
+       }
111074
 
+}
111075
 
+
111076
 
+/*
111077
 
+ * RFC examples
111078
 
+ */ 
111079
 
+
111080
 
+test "RFC hasflag example - :is" {
111081
 
+       setflag "A B";
111082
 
+
111083
 
+       if not hasflag ["b","A"] {
111084
 
+               test_fail "list representation did not match";
111085
 
+       }
111086
 
111087
 
+       if not hasflag :is "b A" {
111088
 
+               test_fail "string representation did not match";
111089
 
+       }
111090
 
+}
111091
 
+
111092
 
+test "RFC hasflag example - :contains variable" {
111093
 
+       set "MyVar" "NonJunk Junk gnus-forward $Forwarded NotJunk JunkRecorded $Junk $NotJunk";
111094
 
+
111095
 
+       if not hasflag :contains "MyVar" "Junk" {
111096
 
+               test_fail "failed true example 1";
111097
 
+       }
111098
 
+
111099
 
+       if not hasflag :contains "MyVar" "forward" {
111100
 
+               test_fail "failed true example 2";
111101
 
+       }
111102
 
+      
111103
 
+       if not hasflag :contains "MyVar" ["label", "forward"] {
111104
 
+               test_fail "failed true example 3";
111105
 
+       }
111106
 
+     
111107
 
+       if not hasflag :contains "MyVar" ["junk", "forward"] {
111108
 
+               test_fail "failed true example 4";
111109
 
+       }
111110
 
+
111111
 
+       if not hasflag :contains "MyVar" "junk forward" {
111112
 
+               test_fail "failed true example 4 (rewrite 1)";
111113
 
+       }
111114
 
+
111115
 
+       if not hasflag :contains "MyVar" "forward junk" {
111116
 
+               test_fail "failed true example 4 (rewrite 2)";
111117
 
+       }
111118
 
+
111119
 
+       if hasflag :contains "MyVar" "label" {
111120
 
+               test_fail "failed false example 1";
111121
 
+       }
111122
 
+
111123
 
+       if hasflag :contains "MyVar" ["label1", "label2"] {
111124
 
+               test_fail "failed false example 2";
111125
 
+       }
111126
 
+}
111127
 
+
111128
 
+test "RFC hasflag example - :count variable" {
111129
 
+       set "MyFlags" "A B";
111130
 
+       if not hasflag :count "ge" :comparator "i;ascii-numeric" "MyFlags" "2" {
111131
 
+               test_fail "failed count \"ge\" comparison";
111132
 
+       }
111133
 
+}
111134
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/errors/action-conflicts.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/errors/action-conflicts.sieve
111135
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/errors/action-conflicts.sieve       1970-01-01 01:00:00.000000000 +0100
111136
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/errors/action-conflicts.sieve        2008-09-06 12:59:49.000000000 +0200
111137
 
@@ -0,0 +1,4 @@
111138
 
+require "include";
111139
 
+
111140
 
+include "action-fileinto";
111141
 
+include "action-reject";
111142
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/errors/circular-1.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/errors/circular-1.sieve
111143
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/errors/circular-1.sieve     1970-01-01 01:00:00.000000000 +0100
111144
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/errors/circular-1.sieve      2008-08-04 10:39:20.000000000 +0200
111145
 
@@ -0,0 +1,5 @@
111146
 
+require "include";
111147
 
+
111148
 
+discard;
111149
 
+
111150
 
+include "circular-one.sieve";
111151
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/errors/circular-2.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/errors/circular-2.sieve
111152
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/errors/circular-2.sieve     1970-01-01 01:00:00.000000000 +0100
111153
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/errors/circular-2.sieve      2008-08-04 10:39:20.000000000 +0200
111154
 
@@ -0,0 +1,5 @@
111155
 
+require "include";
111156
 
+
111157
 
+discard;
111158
 
+
111159
 
+include "circular-two.sieve";
111160
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/errors/circular-3.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/errors/circular-3.sieve
111161
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/errors/circular-3.sieve     1970-01-01 01:00:00.000000000 +0100
111162
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/errors/circular-3.sieve      2008-08-04 10:39:20.000000000 +0200
111163
 
@@ -0,0 +1,5 @@
111164
 
+require "include";
111165
 
+
111166
 
+discard;
111167
 
+
111168
 
+include "circular-three";
111169
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/errors/generic.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/errors/generic.sieve
111170
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/errors/generic.sieve        1970-01-01 01:00:00.000000000 +0100
111171
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/errors/generic.sieve 2008-08-11 00:07:54.000000000 +0200
111172
 
@@ -0,0 +1,7 @@
111173
 
+require "include";
111174
 
+
111175
 
+# Non-existant sieve script
111176
 
+include "frop.sieve";
111177
 
+
111178
 
+# Use of / in script names
111179
 
+include "../frop.sieve";
111180
 
Binary files dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/errors/import-runtime.svbin and dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/errors/import-runtime.svbin differ
111181
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/errors/included/action-fileinto.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/errors/included/action-fileinto.sieve
111182
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/errors/included/action-fileinto.sieve       1970-01-01 01:00:00.000000000 +0100
111183
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/errors/included/action-fileinto.sieve        2008-09-06 12:59:49.000000000 +0200
111184
 
@@ -0,0 +1,3 @@
111185
 
+require "fileinto";
111186
 
+
111187
 
+fileinto "frop";
111188
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/errors/included/action-reject.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/errors/included/action-reject.sieve
111189
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/errors/included/action-reject.sieve 1970-01-01 01:00:00.000000000 +0100
111190
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/errors/included/action-reject.sieve  2008-09-06 12:59:49.000000000 +0200
111191
 
@@ -0,0 +1,3 @@
111192
 
+require "reject";
111193
 
+
111194
 
+reject "Ik heb geen zin in die rommel.";
111195
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/errors/included/circular-one.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/errors/included/circular-one.sieve
111196
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/errors/included/circular-one.sieve  1970-01-01 01:00:00.000000000 +0100
111197
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/errors/included/circular-one.sieve   2008-08-04 10:39:20.000000000 +0200
111198
 
@@ -0,0 +1,5 @@
111199
 
+require "include";
111200
 
+
111201
 
+keep;
111202
 
+
111203
 
+include "circular-one.sieve";
111204
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/errors/included/circular-three-2.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/errors/included/circular-three-2.sieve
111205
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/errors/included/circular-three-2.sieve      1970-01-01 01:00:00.000000000 +0100
111206
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/errors/included/circular-three-2.sieve       2008-08-04 10:39:20.000000000 +0200
111207
 
@@ -0,0 +1,3 @@
111208
 
+require "include";
111209
 
+
111210
 
+include "circular-three-3.sieve";
111211
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/errors/included/circular-three-3.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/errors/included/circular-three-3.sieve
111212
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/errors/included/circular-three-3.sieve      1970-01-01 01:00:00.000000000 +0100
111213
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/errors/included/circular-three-3.sieve       2008-08-04 10:39:20.000000000 +0200
111214
 
@@ -0,0 +1,3 @@
111215
 
+require "include";
111216
 
+
111217
 
+include "circular-three.sieve";
111218
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/errors/included/circular-three.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/errors/included/circular-three.sieve
111219
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/errors/included/circular-three.sieve        1970-01-01 01:00:00.000000000 +0100
111220
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/errors/included/circular-three.sieve 2008-08-04 10:39:20.000000000 +0200
111221
 
@@ -0,0 +1,7 @@
111222
 
+require "include";
111223
 
+
111224
 
+keep;
111225
 
+
111226
 
+include "circular-three-2.sieve";
111227
 
+
111228
 
+
111229
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/errors/included/circular-two-2.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/errors/included/circular-two-2.sieve
111230
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/errors/included/circular-two-2.sieve        1970-01-01 01:00:00.000000000 +0100
111231
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/errors/included/circular-two-2.sieve 2008-08-04 10:39:20.000000000 +0200
111232
 
@@ -0,0 +1,3 @@
111233
 
+require "include";
111234
 
+
111235
 
+include "circular-two.sieve";
111236
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/errors/included/circular-two.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/errors/included/circular-two.sieve
111237
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/errors/included/circular-two.sieve  1970-01-01 01:00:00.000000000 +0100
111238
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/errors/included/circular-two.sieve   2008-08-04 10:39:20.000000000 +0200
111239
 
@@ -0,0 +1,7 @@
111240
 
+require "include";
111241
 
+
111242
 
+keep;
111243
 
+
111244
 
+include "circular-two-2.sieve";
111245
 
+
111246
 
+
111247
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/errors/variables-inactive.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/errors/variables-inactive.sieve
111248
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/errors/variables-inactive.sieve     1970-01-01 01:00:00.000000000 +0100
111249
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/errors/variables-inactive.sieve      2009-04-10 15:23:24.000000000 +0200
111250
 
@@ -0,0 +1,7 @@
111251
 
+require "include";
111252
 
+require "fileinto";
111253
 
+
111254
 
+global "friep";
111255
 
+global "frop";
111256
 
+
111257
 
+fileinto "Frop";
111258
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/errors/variables.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/errors/variables.sieve
111259
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/errors/variables.sieve      1970-01-01 01:00:00.000000000 +0100
111260
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/errors/variables.sieve       2009-04-10 15:15:58.000000000 +0200
111261
 
@@ -0,0 +1,8 @@
111262
 
+require "include";
111263
 
+require "variables";
111264
 
+
111265
 
+keep;
111266
 
+
111267
 
+# Global after command not being require or global
111268
 
+global "friep";
111269
 
+
111270
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/errors.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/errors.svtest
111271
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/errors.svtest       1970-01-01 01:00:00.000000000 +0100
111272
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/errors.svtest        2009-04-10 15:23:50.000000000 +0200
111273
 
@@ -0,0 +1,77 @@
111274
 
+require "vnd.dovecot.testsuite";
111275
 
+
111276
 
+require "relational";
111277
 
+require "comparator-i;ascii-numeric";
111278
 
+
111279
 
+/*
111280
 
+ * Generic include errors
111281
 
+ */
111282
 
+
111283
 
+test "Generic" {
111284
 
+       if test_script_compile "errors/generic.sieve" {
111285
 
+               test_fail "compile should have failed";
111286
 
+       }
111287
 
+
111288
 
+       if not test_error :count "eq" :comparator "i;ascii-numeric" "3" {
111289
 
+               test_fail "wrong number of errors reported";
111290
 
+       }
111291
 
+}
111292
 
+
111293
 
+test "Circular - direct" {
111294
 
+       if test_script_compile "errors/circular-1.sieve" {
111295
 
+               test_fail "compile should have failed";
111296
 
+       }
111297
 
+
111298
 
+       if not test_error :count "eq" :comparator "i;ascii-numeric" "3" {
111299
 
+               test_fail "wrong number of errors reported";
111300
 
+       }
111301
 
+}
111302
 
+
111303
 
+test "Circular - one intermittent" {
111304
 
+       if test_script_compile "errors/circular-2.sieve" {
111305
 
+               test_fail "compile should have failed";
111306
 
+       }
111307
 
+
111308
 
+       if not test_error :count "eq" :comparator "i;ascii-numeric" "4" {
111309
 
+               test_fail "wrong number of errors reported";
111310
 
+       }
111311
 
+}
111312
 
+
111313
 
+test "Circular - two intermittent" {
111314
 
+       if test_script_compile "errors/circular-3.sieve" {
111315
 
+               test_fail "compile should have failed";
111316
 
+       }
111317
 
+
111318
 
+       if not test_error :count "eq" :comparator "i;ascii-numeric" "5" {
111319
 
+               test_fail "wrong number of errors reported";
111320
 
+       }
111321
 
+}
111322
 
+
111323
 
+/*
111324
 
+ * Using global without variables required
111325
 
+ */
111326
 
+
111327
 
+test "Variables inactive" {
111328
 
+       if test_script_compile "errors/variables-inactive.sieve" {
111329
 
+               test_fail "compile should have failed";
111330
 
+       }
111331
 
+
111332
 
+       if not test_error :count "eq" :comparator "i;ascii-numeric" "3" {
111333
 
+               test_fail "wrong number of errors reported";
111334
 
+       }
111335
 
+}
111336
 
+
111337
 
+/*
111338
 
+ * Generic variables errors
111339
 
+ */
111340
 
+
111341
 
+test "Variables" {
111342
 
+       if test_script_compile "errors/variables.sieve" {
111343
 
+               test_fail "compile should have failed";
111344
 
+       }
111345
 
+
111346
 
+       if not test_error :count "eq" :comparator "i;ascii-numeric" "2" {
111347
 
+               test_fail "wrong number of errors reported";
111348
 
+       }
111349
 
+}
111350
 
+
111351
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/execute/actions-fileinto.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/execute/actions-fileinto.sieve
111352
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/execute/actions-fileinto.sieve      1970-01-01 01:00:00.000000000 +0100
111353
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/execute/actions-fileinto.sieve       2009-08-21 00:52:15.000000000 +0200
111354
 
@@ -0,0 +1,5 @@
111355
 
+require "include";
111356
 
+
111357
 
+include "actions-fileinto1";
111358
 
+include "actions-fileinto2";
111359
 
+include "actions-fileinto3";
111360
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/execute/included/actions-fileinto1.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/execute/included/actions-fileinto1.sieve
111361
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/execute/included/actions-fileinto1.sieve    1970-01-01 01:00:00.000000000 +0100
111362
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/execute/included/actions-fileinto1.sieve     2009-08-21 00:52:15.000000000 +0200
111363
 
@@ -0,0 +1,3 @@
111364
 
+require "fileinto";
111365
 
+
111366
 
+fileinto "aaaa";
111367
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/execute/included/actions-fileinto2.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/execute/included/actions-fileinto2.sieve
111368
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/execute/included/actions-fileinto2.sieve    1970-01-01 01:00:00.000000000 +0100
111369
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/execute/included/actions-fileinto2.sieve     2009-08-21 00:52:15.000000000 +0200
111370
 
@@ -0,0 +1,4 @@
111371
 
+require "fileinto";
111372
 
+
111373
 
+fileinto "bbbb";
111374
 
+
111375
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/execute/included/actions-fileinto3.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/execute/included/actions-fileinto3.sieve
111376
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/execute/included/actions-fileinto3.sieve    1970-01-01 01:00:00.000000000 +0100
111377
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/execute/included/actions-fileinto3.sieve     2009-08-21 00:52:15.000000000 +0200
111378
 
@@ -0,0 +1,3 @@
111379
 
+require "fileinto";
111380
 
+
111381
 
+fileinto "aaaa";
111382
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/execute.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/execute.svtest
111383
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/execute.svtest      1970-01-01 01:00:00.000000000 +0100
111384
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/execute.svtest       2009-08-21 00:52:15.000000000 +0200
111385
 
@@ -0,0 +1,42 @@
111386
 
+require "vnd.dovecot.testsuite";
111387
 
+
111388
 
+test_set "message" text:
111389
 
+From: idiot@example.com
111390
 
+To: idiot@rename-it.nl
111391
 
+Subject: Frop!
111392
 
+
111393
 
+Frop.
111394
 
+.
111395
 
+;
111396
 
+
111397
 
+test "Actions Fileinto" {
111398
 
+       test_mailbox :create "aaaa";
111399
 
+       test_mailbox :create "bbbb";
111400
 
+       
111401
 
+       if not test_script_compile "execute/actions-fileinto.sieve" {
111402
 
+               test_fail "failed to compile sieve script";
111403
 
+       }
111404
 
+
111405
 
+       test_binary :save "actions-fileinto";
111406
 
+       test_binary :load "actions-fileinto";
111407
 
+
111408
 
+       if not test_script_run {
111409
 
+               test_fail "failed to execute sieve script";
111410
 
+       }
111411
 
+
111412
 
+       if not test_result_execute {
111413
 
+               test_fail "failed to execute result";
111414
 
+       }
111415
 
+
111416
 
+       test_message :folder "aaaa" 0;
111417
 
+
111418
 
+       if not header "subject" "Frop!" {
111419
 
+               test_fail "fileinto \"aaaa\" not executed.";
111420
 
+       }       
111421
 
+
111422
 
+       test_message :folder "aaaa" 0;
111423
 
+
111424
 
+       if not header "subject" "Frop!" {
111425
 
+               test_fail "fileinto \"bbbb\" not executed.";
111426
 
+       }       
111427
 
+}
111428
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/included/once-1.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/included/once-1.sieve
111429
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/included/once-1.sieve       1970-01-01 01:00:00.000000000 +0100
111430
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/included/once-1.sieve        2009-04-10 18:02:35.000000000 +0200
111431
 
@@ -0,0 +1,9 @@
111432
 
+require "include";
111433
 
+require "variables";
111434
 
+
111435
 
+global "result";
111436
 
+
111437
 
+set "result" "${result} ONE";
111438
 
+
111439
 
+return;
111440
 
+
111441
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/included/once-2.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/included/once-2.sieve
111442
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/included/once-2.sieve       1970-01-01 01:00:00.000000000 +0100
111443
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/included/once-2.sieve        2009-04-11 17:47:41.000000000 +0200
111444
 
@@ -0,0 +1,12 @@
111445
 
+require "include";
111446
 
+require "variables";
111447
 
+
111448
 
+global "result";
111449
 
+
111450
 
+set "result" "${result} TWO";
111451
 
+
111452
 
+keep;
111453
 
+
111454
 
+include :once "once-1.sieve";
111455
 
+
111456
 
+return;
111457
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/included/once-3.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/included/once-3.sieve
111458
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/included/once-3.sieve       1970-01-01 01:00:00.000000000 +0100
111459
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/included/once-3.sieve        2009-04-11 17:47:41.000000000 +0200
111460
 
@@ -0,0 +1,3 @@
111461
 
+require "include";
111462
 
+
111463
 
+include "once-4";
111464
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/included/once-4.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/included/once-4.sieve
111465
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/included/once-4.sieve       1970-01-01 01:00:00.000000000 +0100
111466
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/included/once-4.sieve        2009-04-11 17:47:41.000000000 +0200
111467
 
@@ -0,0 +1,3 @@
111468
 
+require "include";
111469
 
+
111470
 
+include :once "once-3";
111471
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/included/rfc-ex1-always_allow.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/included/rfc-ex1-always_allow.sieve
111472
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/included/rfc-ex1-always_allow.sieve 1970-01-01 01:00:00.000000000 +0100
111473
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/included/rfc-ex1-always_allow.sieve  2009-04-11 17:47:41.000000000 +0200
111474
 
@@ -0,0 +1,8 @@
111475
 
+if header :is "From" "boss@example.com"
111476
 
+{
111477
 
+     keep;
111478
 
+}
111479
 
+elsif header :is "From" "ceo@example.com"
111480
 
+{
111481
 
+     keep;
111482
 
+}
111483
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/included/rfc-ex1-mailing_lists.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/included/rfc-ex1-mailing_lists.sieve
111484
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/included/rfc-ex1-mailing_lists.sieve        1970-01-01 01:00:00.000000000 +0100
111485
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/included/rfc-ex1-mailing_lists.sieve 2009-04-11 17:47:41.000000000 +0200
111486
 
@@ -0,0 +1,10 @@
111487
 
+require ["fileinto"];
111488
 
+
111489
 
+if header :is "Sender" "owner-ietf-mta-filters@imc.org"
111490
 
+{
111491
 
+     fileinto "lists.sieve";
111492
 
+}
111493
 
+elsif header :is "Sender" "owner-ietf-imapext@imc.org"
111494
 
+{
111495
 
+     fileinto "lists.imapext";
111496
 
+}
111497
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/included/rfc-ex1-spam_tests.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/included/rfc-ex1-spam_tests.sieve
111498
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/included/rfc-ex1-spam_tests.sieve   1970-01-01 01:00:00.000000000 +0100
111499
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/included/rfc-ex1-spam_tests.sieve    2009-04-11 17:47:41.000000000 +0200
111500
 
@@ -0,0 +1,10 @@
111501
 
+require ["reject"];
111502
 
+
111503
 
+if header :contains "Subject" "XXXX"
111504
 
+{
111505
 
+       reject "Not wanted";
111506
 
+}
111507
 
+elsif header :is "From" "money@example.com"
111508
 
+{
111509
 
+       reject "Not wanted";
111510
 
+}
111511
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/included/rfc-ex2-spam_filter_script.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/included/rfc-ex2-spam_filter_script.sieve
111512
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/included/rfc-ex2-spam_filter_script.sieve   1970-01-01 01:00:00.000000000 +0100
111513
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/included/rfc-ex2-spam_filter_script.sieve    2009-04-11 17:47:41.000000000 +0200
111514
 
@@ -0,0 +1,8 @@
111515
 
+require ["variables", "include"];
111516
 
+global ["test", "test_mailbox"];
111517
 
+
111518
 
+if header :contains "Subject" "${test}"
111519
 
+{
111520
 
+       set "test_mailbox" "spam-${test}";
111521
 
+}
111522
 
+
111523
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/included/twice-1.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/included/twice-1.sieve
111524
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/included/twice-1.sieve      1970-01-01 01:00:00.000000000 +0100
111525
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/included/twice-1.sieve       2009-04-11 17:47:41.000000000 +0200
111526
 
@@ -0,0 +1,7 @@
111527
 
+require "include";
111528
 
+require "variables";
111529
 
+
111530
 
+global "result";
111531
 
+
111532
 
+set "result" "${result} TWO";
111533
 
+
111534
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/included/twice-2.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/included/twice-2.sieve
111535
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/included/twice-2.sieve      1970-01-01 01:00:00.000000000 +0100
111536
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/included/twice-2.sieve       2009-04-11 17:47:41.000000000 +0200
111537
 
@@ -0,0 +1,8 @@
111538
 
+require "include";
111539
 
+require "variables";
111540
 
+
111541
 
+global "result";
111542
 
+
111543
 
+set "result" "${result} THREE";
111544
 
+
111545
 
+include "twice-1.sieve";
111546
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/included/variables-included1.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/included/variables-included1.sieve
111547
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/included/variables-included1.sieve  1970-01-01 01:00:00.000000000 +0100
111548
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/included/variables-included1.sieve   2009-04-10 15:21:45.000000000 +0200
111549
 
@@ -0,0 +1,7 @@
111550
 
+require "include";
111551
 
+require "variables";
111552
 
+
111553
 
+global ["value1", "value2"];
111554
 
+global ["result1"];
111555
 
+
111556
 
+set "result1" "${value1} ${value2}";
111557
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/included/variables-included2.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/included/variables-included2.sieve
111558
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/included/variables-included2.sieve  1970-01-01 01:00:00.000000000 +0100
111559
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/included/variables-included2.sieve   2009-04-10 15:22:03.000000000 +0200
111560
 
@@ -0,0 +1,6 @@
111561
 
+require "include";
111562
 
+require "variables";
111563
 
+
111564
 
+global ["value3", "value4", "result2"];
111565
 
+
111566
 
+set "result2" "${value3} ${value4}";
111567
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/included/variables-included3.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/included/variables-included3.sieve
111568
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/included/variables-included3.sieve  1970-01-01 01:00:00.000000000 +0100
111569
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/included/variables-included3.sieve   2009-04-10 15:22:24.000000000 +0200
111570
 
@@ -0,0 +1,8 @@
111571
 
+require "include";
111572
 
+require "variables";
111573
 
+
111574
 
+global "result1";
111575
 
+global "result2";
111576
 
+global "result";
111577
 
+
111578
 
+set "result" "${result1} ${result2}";
111579
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/included-global/rfc-ex1-spam_tests.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/included-global/rfc-ex1-spam_tests.sieve
111580
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/included-global/rfc-ex1-spam_tests.sieve    1970-01-01 01:00:00.000000000 +0100
111581
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/included-global/rfc-ex1-spam_tests.sieve     2009-04-11 17:47:41.000000000 +0200
111582
 
@@ -0,0 +1,7 @@
111583
 
+require ["reject"];
111584
 
+
111585
 
+if anyof (header :contains "Subject" "$$",
111586
 
+       header :contains "Subject" "Make money")
111587
 
+{
111588
 
+       reject "Not wanted";
111589
 
+}
111590
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/once.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/once.svtest
111591
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/once.svtest 1970-01-01 01:00:00.000000000 +0100
111592
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/once.svtest  2009-04-11 17:47:41.000000000 +0200
111593
 
@@ -0,0 +1,24 @@
111594
 
+require "vnd.dovecot.testsuite";
111595
 
+require "include";
111596
 
+require "variables";
111597
 
+
111598
 
+global "result";
111599
 
+
111600
 
+set "result" "";
111601
 
+
111602
 
+test "Included Once" {
111603
 
+       include "once-1";
111604
 
+       include "once-2";
111605
 
+
111606
 
+       if string "${result}" " ONE TWO ONE" {
111607
 
+               test_fail "duplicate included :once script";
111608
 
+       }
111609
 
+
111610
 
+       if not string "${result}" " ONE TWO" {
111611
 
+               test_fail "unexpected result value: ${result}";
111612
 
+       }
111613
 
+}
111614
 
+
111615
 
+test "Included Once recursive" {
111616
 
+       include "once-3";
111617
 
+}
111618
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/rfc-ex1-default.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/rfc-ex1-default.sieve
111619
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/rfc-ex1-default.sieve       1970-01-01 01:00:00.000000000 +0100
111620
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/rfc-ex1-default.sieve        2009-04-11 17:47:41.000000000 +0200
111621
 
@@ -0,0 +1,6 @@
111622
 
+require ["include"];
111623
 
+
111624
 
+include :personal "rfc-ex1-always_allow";
111625
 
+include :global "rfc-ex1-spam_tests";
111626
 
+include :personal "rfc-ex1-spam_tests";
111627
 
+include :personal "rfc-ex1-mailing_lists";
111628
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/rfc-ex2-default.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/rfc-ex2-default.sieve
111629
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/rfc-ex2-default.sieve       1970-01-01 01:00:00.000000000 +0100
111630
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/rfc-ex2-default.sieve        2009-04-11 17:47:41.000000000 +0200
111631
 
@@ -0,0 +1,21 @@
111632
 
+require ["variables", "include", "relational", "fileinto"];
111633
 
+global "test";
111634
 
+global "test-mailbox";
111635
 
+
111636
 
+# The included script may contain repetitive code that is
111637
 
+# effectively a subroutine that can be factored out.
111638
 
+set "test" "$$";
111639
 
+include "rfc-ex2-spam_filter_script";
111640
 
+
111641
 
+set "test" "Make money";
111642
 
+include "rfc-ex2-spam_filter_script";
111643
 
+
111644
 
+# Message will be filed according to the test that matched last.
111645
 
+if string :count "eq" "${test_mailbox}" "1"
111646
 
+{
111647
 
+       fileinto "INBOX${test_mailbox}";
111648
 
+       stop;
111649
 
+}
111650
 
+
111651
 
+# If nothing matched, the message is implicitly kept.
111652
 
+
111653
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/rfc.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/rfc.svtest
111654
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/rfc.svtest  1970-01-01 01:00:00.000000000 +0100
111655
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/rfc.svtest   2009-04-11 17:47:41.000000000 +0200
111656
 
@@ -0,0 +1,13 @@
111657
 
+require "vnd.dovecot.testsuite";
111658
 
+
111659
 
+test "RFC example 1" {
111660
 
+       if not test_script_compile "rfc-ex1-default.sieve" {
111661
 
+               test_fail "failed to compile sieve script";
111662
 
+       }
111663
 
+}
111664
 
+
111665
 
+test "RFC example 2" {
111666
 
+       if not test_script_compile "rfc-ex2-default.sieve" {
111667
 
+               test_fail "failed to compile sieve script";
111668
 
+       }
111669
 
+}
111670
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/twice.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/twice.svtest
111671
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/twice.svtest        1970-01-01 01:00:00.000000000 +0100
111672
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/twice.svtest 2009-04-11 17:47:41.000000000 +0200
111673
 
@@ -0,0 +1,20 @@
111674
 
+require "vnd.dovecot.testsuite";
111675
 
+require "include";
111676
 
+require "variables";
111677
 
+
111678
 
+global "result";
111679
 
+
111680
 
+set "result" "ONE";
111681
 
+
111682
 
+test "Twice included" {
111683
 
+       include "twice-1";
111684
 
+       include "twice-2";
111685
 
+
111686
 
+       if string "${result}" "ONE TWO THREE" {
111687
 
+               test_fail "duplicate include failed";
111688
 
+       }
111689
 
+
111690
 
+       if not string "${result}" "ONE TWO THREE TWO" {
111691
 
+               test_fail "unexpected result: ${result}";
111692
 
+       }
111693
 
+}
111694
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/variables.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/variables.svtest
111695
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/include/variables.svtest    1970-01-01 01:00:00.000000000 +0100
111696
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/include/variables.svtest     2009-04-10 15:21:30.000000000 +0200
111697
 
@@ -0,0 +1,28 @@
111698
 
+require "vnd.dovecot.testsuite";
111699
 
+
111700
 
+require "include";
111701
 
+require "variables";
111702
 
+
111703
 
+global ["value1", "value2"];
111704
 
+global ["value3", "value4"];
111705
 
+global "result";
111706
 
+
111707
 
+set "value1" "Works";
111708
 
+set "value2" "fine.";
111709
 
+set "value3" "Yeah";
111710
 
+set "value4" "it does.";
111711
 
+
111712
 
+include "variables-included1";
111713
 
+include "variables-included2";
111714
 
+include "variables-included3";
111715
 
+
111716
 
+test "Basic" {
111717
 
+       if not string :is "${result}" "Works fine. Yeah it does." {
111718
 
+               test_fail "invalid result: ${result}";
111719
 
+       }
111720
 
+
111721
 
+       if string :is "${result}" "nonsense" {
111722
 
+               test_fail "string test succeeds inappropriately";
111723
 
+       }
111724
 
+}
111725
 
+
111726
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/mailbox/execute.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/mailbox/execute.svtest
111727
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/mailbox/execute.svtest      1970-01-01 01:00:00.000000000 +0100
111728
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/mailbox/execute.svtest       2009-08-02 09:44:14.000000000 +0200
111729
 
@@ -0,0 +1,80 @@
111730
 
+require "vnd.dovecot.testsuite";
111731
 
+require "mailbox";
111732
 
+require "fileinto";
111733
 
+
111734
 
+test "MailboxExists - None exist" {
111735
 
+       if mailboxexists "frop" {
111736
 
+               test_fail "mailboxexists confirms existance of unknown folder";
111737
 
+       }
111738
 
+}
111739
 
+
111740
 
+test_mailbox :create "frop";
111741
 
+test_mailbox :create "friep";
111742
 
+
111743
 
+test "MailboxExists - Not all exist" {
111744
 
+       if mailboxexists ["frop", "friep", "frml"] {
111745
 
+               test_fail "mailboxexists confirms existance of unknown folder";
111746
 
+       }
111747
 
+}
111748
 
+
111749
 
+test_mailbox :create "frml";
111750
 
+
111751
 
+test "MailboxExists - One exists" {
111752
 
+       if not mailboxexists ["frop"] {
111753
 
+               test_fail "mailboxexists fails to recognize folder";
111754
 
+       }
111755
 
+}
111756
 
+
111757
 
+test "MailboxExists - All exist" {
111758
 
+       if not mailboxexists ["frop", "friep", "frml"] {
111759
 
+               test_fail "mailboxexists fails to recognize folders";
111760
 
+       }
111761
 
+}
111762
 
+
111763
 
+test ":Create" {
111764
 
+       if mailboxexists "created" {
111765
 
+               test_fail "mailbox exists already";
111766
 
+       }
111767
 
+
111768
 
+       test_set "message" text:
111769
 
+From: stephan@rename-it.nl
111770
 
+To: nico@vestingbar.nl
111771
 
+Subject: Frop 1
111772
 
+
111773
 
+Frop!
111774
 
+.
111775
 
+       ;
111776
 
+
111777
 
+       fileinto :create "created";
111778
 
+
111779
 
+       if not test_result_execute {
111780
 
+               test_fail "execution of result failed";
111781
 
+       }
111782
 
+
111783
 
+       if not mailboxexists "created" {
111784
 
+               test_fail "mailbox somehow not created";
111785
 
+       }
111786
 
+
111787
 
+       test_result_reset;
111788
 
+
111789
 
+       test_set "message" text:
111790
 
+From: stephan@rename-it.nl
111791
 
+To: nico@vestingbar.nl
111792
 
+Subject: Frop 2
111793
 
+
111794
 
+Frop!
111795
 
+.
111796
 
+       ;
111797
 
+
111798
 
+       fileinto "created";
111799
 
+
111800
 
+       if not test_result_execute {
111801
 
+               test_fail "execution of result failed second time";
111802
 
+       }
111803
 
+
111804
 
+       test_message :folder "created" 0;
111805
 
+
111806
 
+       if not header :is "subject" "Frop 1" {
111807
 
+               test_fail "incorrect message read back from mail store";
111808
 
+       }
111809
 
+}
111810
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/regex/basic.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/regex/basic.svtest
111811
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/regex/basic.svtest  1970-01-01 01:00:00.000000000 +0100
111812
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/regex/basic.svtest   2008-08-25 10:25:08.000000000 +0200
111813
 
@@ -0,0 +1,21 @@
111814
 
+require "vnd.dovecot.testsuite";
111815
 
+
111816
 
+require "regex";
111817
 
+
111818
 
+test_set "message" text:
111819
 
+From: stephan+sieve@drunksnipers.com
111820
 
+To: tss@iki.fi
111821
 
+Subject: Test
111822
 
+
111823
 
+Test message.
111824
 
+.
111825
 
+;
111826
 
+
111827
 
+test "Basic example" {
111828
 
+       if not address :regex :comparator "i;ascii-casemap" "from" [
111829
 
+               "stephan(\\+.*)?@rename-it\\.com", 
111830
 
+               "stephan(\\+.*)?@drunksnipers\\.com" 
111831
 
+               ] {
111832
 
+               test_fail "failed to match";
111833
 
+       }
111834
 
+}      
111835
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/regex/errors/compile.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/regex/errors/compile.sieve
111836
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/regex/errors/compile.sieve  1970-01-01 01:00:00.000000000 +0100
111837
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/regex/errors/compile.sieve   2008-08-25 10:25:08.000000000 +0200
111838
 
@@ -0,0 +1,25 @@
111839
 
+require "regex";
111840
 
+require "comparator-i;ascii-numeric";
111841
 
+require "envelope";
111842
 
+
111843
 
+if address :regex :comparator "i;ascii-numeric" "from" "sirius(\\+.*)?@drunksnipers\\.com" {
111844
 
+       keep;
111845
 
+       stop;
111846
 
+}
111847
 
+
111848
 
+if address :regex "from" "sirius(+\\+.*)?@drunksnipers\\.com" {
111849
 
+       keep;
111850
 
+       stop;
111851
 
+}
111852
 
+
111853
 
+if header :regex "from" "sirius(\\+.*)?@drunk[]snipers.com" {
111854
 
+    keep;
111855
 
+    stop;
111856
 
+}
111857
 
+
111858
 
+if envelope :regex "from" "sirius(\\+.*)?@drunksni[]pers.com" {
111859
 
+    keep;
111860
 
+    stop;
111861
 
+}
111862
 
+
111863
 
+discard;
111864
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/regex/errors.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/regex/errors.svtest
111865
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/regex/errors.svtest 1970-01-01 01:00:00.000000000 +0100
111866
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/regex/errors.svtest  2009-01-06 00:15:52.000000000 +0100
111867
 
@@ -0,0 +1,14 @@
111868
 
+require "vnd.dovecot.testsuite";
111869
 
+
111870
 
+require "relational";
111871
 
+require "comparator-i;ascii-numeric";
111872
 
+
111873
 
+test "Compile errors" {
111874
 
+       if test_script_compile "errors/compile.sieve" {
111875
 
+               test_fail "compile should have failed";
111876
 
+       }
111877
 
+
111878
 
+       if not test_error :count "eq" :comparator "i;ascii-numeric" "5" {
111879
 
+               test_fail "wrong number of errors reported";
111880
 
+       }
111881
 
+}
111882
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/regex/match-values.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/regex/match-values.svtest
111883
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/regex/match-values.svtest   1970-01-01 01:00:00.000000000 +0100
111884
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/regex/match-values.svtest    2009-01-22 00:18:13.000000000 +0100
111885
 
@@ -0,0 +1,68 @@
111886
 
+require "vnd.dovecot.testsuite";
111887
 
+
111888
 
+require "regex";
111889
 
+require "variables";
111890
 
+
111891
 
+test_set "message" text:
111892
 
+From: Andy Howell <AndyHowell@example.com>
111893
 
+Sender: antlr-interest-bounces@antlr.org
111894
 
+To: Stephan Bosch <stephan@rename-it.nl>
111895
 
+Subject: [Dovecot] Sieve regex match problem
111896
 
+
111897
 
+Hi,
111898
 
+
111899
 
+I is broken.
111900
 
+.
111901
 
+;
111902
 
+
111903
 
+test "Basic match values 1" {
111904
 
+       if header :regex ["Sender"] ["([^-@]*)-([^-@]*)(-bounces)?@antlr.org"] {
111905
 
+
111906
 
+               if not string :is "${1}" "antlr" {
111907
 
+                       test_fail "first match value is not correct";
111908
 
+               }       
111909
 
+
111910
 
+               if not string :is "${2}" "interest" {
111911
 
+                       test_fail "second match value is not correct";
111912
 
+               }       
111913
 
+
111914
 
+               if not string :is "${3}" "-bounces" {
111915
 
+                       test_fail "third match value is not correct";
111916
 
+               }       
111917
 
+
111918
 
+               if string :is "${4}" "-bounces" {
111919
 
+                       test_fail "fourth match contains third value";
111920
 
+               }
111921
 
+       }
111922
 
+}
111923
 
+
111924
 
+test "Basic match values 2" {
111925
 
+       if header :regex ["Sender"] ["(.*>[ \\t]*,?[ \\t]*)?([^-@]*)-([^-@]*)(-bounces)?@antlr.org"] {
111926
 
+
111927
 
+               if not string :is "${1}" "" {
111928
 
+            test_fail "first match value is not correct: ${1}";
111929
 
+        }
111930
 
+
111931
 
+               if not string :is "${2}" "antlr" {
111932
 
+                       test_fail "second match value is not correct: ${2}";
111933
 
+               }       
111934
 
+
111935
 
+               if not string :is "${3}" "interest" {
111936
 
+                       test_fail "third match value is not correct: ${3}";
111937
 
+               }       
111938
 
+
111939
 
+               if not string :is "${4}" "-bounces" {
111940
 
+                       test_fail "fourth match value is not correct: ${4}";
111941
 
+               }       
111942
 
+
111943
 
+               if string :is "${5}" "-bounces" {
111944
 
+                       test_fail "fifth match contains fourth value: ${5}";
111945
 
+               }
111946
 
+       }
111947
 
+}
111948
 
+
111949
 
+
111950
 
+
111951
 
+
111952
 
+
111953
 
+
111954
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/reject/execute/basic.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/reject/execute/basic.sieve
111955
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/reject/execute/basic.sieve  1970-01-01 01:00:00.000000000 +0100
111956
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/reject/execute/basic.sieve   2008-10-04 10:41:25.000000000 +0200
111957
 
@@ -0,0 +1,8 @@
111958
 
+require "reject";
111959
 
+
111960
 
+if address :contains "to" "vestingbar" {
111961
 
+       reject "Don't send unrequested messages.";
111962
 
+       stop;
111963
 
+}
111964
 
+
111965
 
+keep;
111966
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/reject/execute.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/reject/execute.svtest
111967
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/reject/execute.svtest       1970-01-01 01:00:00.000000000 +0100
111968
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/reject/execute.svtest        2009-01-06 00:15:52.000000000 +0100
111969
 
@@ -0,0 +1,34 @@
111970
 
+require "vnd.dovecot.testsuite";
111971
 
+require "relational";
111972
 
+require "comparator-i;ascii-numeric";
111973
 
+
111974
 
+test_set "message" text:
111975
 
+To: nico@vestingbar.nl
111976
 
+From: stephan@rename-it.nl
111977
 
+Subject: Test
111978
 
+
111979
 
+Test.
111980
 
+.
111981
 
+;
111982
 
+
111983
 
+test "Execute" {
111984
 
+       if not test_script_compile "execute/basic.sieve" {
111985
 
+               test_fail "script compile failed";
111986
 
+       }
111987
 
+
111988
 
+       if not test_script_run {
111989
 
+               test_fail "script run failed";
111990
 
+       }
111991
 
+
111992
 
+       if not test_result :count "eq" :comparator "i;ascii-numeric" "1" {
111993
 
+               test_fail "invalid number of actions in result";
111994
 
+       }
111995
 
+
111996
 
+       if not test_result :index 1 "reject" {
111997
 
+               test_fail "reject action missing from result";
111998
 
+       }
111999
 
+
112000
 
+       if not test_result_execute {
112001
 
+               test_fail "result execute failed";
112002
 
+       }
112003
 
+}
112004
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/reject/smtp.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/reject/smtp.svtest
112005
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/reject/smtp.svtest  1970-01-01 01:00:00.000000000 +0100
112006
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/reject/smtp.svtest   2009-07-21 12:41:19.000000000 +0200
112007
 
@@ -0,0 +1,56 @@
112008
 
+require "vnd.dovecot.testsuite";
112009
 
+require "envelope";
112010
 
+require "reject";
112011
 
+
112012
 
+test_set "message" text:
112013
 
+From: stephan@rename-it.nl
112014
 
+To: tss@iki.fi
112015
 
+Subject: Frop!
112016
 
+
112017
 
+Frop!
112018
 
+.
112019
 
+;
112020
 
+
112021
 
+test_set "envelope.from" "sirius@rename-it.nl";
112022
 
+test_set "envelope.to" "timo@iki.fi";
112023
 
+
112024
 
+test "Basic" {
112025
 
+       reject "I don't want your mail";
112026
 
+
112027
 
+       if not test_result_execute {
112028
 
+        test_fail "failed to execute reject";
112029
 
+    }
112030
 
+
112031
 
+    test_message :smtp 0;
112032
 
+
112033
 
+    if not address :is "to" "sirius@rename-it.nl" {
112034
 
+        test_fail "to address incorrect";
112035
 
+    }
112036
 
+
112037
 
+    if not header :contains "from" "Mail Delivery Subsystem" {
112038
 
+        test_fail "from address incorrect";
112039
 
+    }
112040
 
+
112041
 
+       if not envelope :is "to" "sirius@rename-it.nl" {
112042
 
+               test_fail "envelope recipient incorrect";
112043
 
+       }
112044
 
+
112045
 
+       if not envelope :is "from" "" {
112046
 
+               test_fail "envelope sender not null";
112047
 
+       }
112048
 
+}
112049
 
+
112050
 
+test_result_reset;
112051
 
+test_set "envelope.from" "<>";
112052
 
+
112053
 
+test "Null Sender" {
112054
 
+       reject "I don't want your mail";
112055
 
+
112056
 
+       if not test_result_execute {
112057
 
+               test_fail "failed to execute reject";
112058
 
+       }
112059
 
+
112060
 
+       if test_message :smtp 0 {
112061
 
+               test_fail "reject sent message to NULL sender";
112062
 
+       }
112063
 
+}
112064
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/relational/basic.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/relational/basic.svtest
112065
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/relational/basic.svtest     1970-01-01 01:00:00.000000000 +0100
112066
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/relational/basic.svtest      2008-08-25 10:25:08.000000000 +0200
112067
 
@@ -0,0 +1,178 @@
112068
 
+require "vnd.dovecot.testsuite";
112069
 
+
112070
 
+require "relational";
112071
 
+require "comparator-i;ascii-numeric";
112072
 
+
112073
 
+/* 
112074
 
+ * Test message
112075
 
+ */
112076
 
+
112077
 
+test_set "message" text:
112078
 
+From: stephan@rename-it.nl
112079
 
+To: nico@vestingbar.nl
112080
 
+Cc: frop@rename-it.nl
112081
 
+CC: timo@rename-it.nl
112082
 
+X-Spam-Score: 300
112083
 
+X-Nonsense: 1000
112084
 
+X-Nonsense: 20
112085
 
+X-Alpha: abcdzyx
112086
 
+X-Count: a
112087
 
+X-Count: b
112088
 
+X-Count: c
112089
 
+X-Count: d
112090
 
+X-Count: e
112091
 
+X-Count: f
112092
 
+X-Count: g
112093
 
+X-Count: h
112094
 
+X-Count: i
112095
 
+X-Count: j
112096
 
+X-Count: k
112097
 
+X-Count: l
112098
 
+X-Count: m
112099
 
+X-Count: n
112100
 
+X-Count: o
112101
 
+X-Count: p
112102
 
+X-Count: q
112103
 
+X-Count: r
112104
 
+X-Count: s
112105
 
+X-Count: t
112106
 
+X-Count: u
112107
 
+X-Count: v
112108
 
+X-Count: w
112109
 
+X-Count: x
112110
 
+X-Count: y
112111
 
+X-Count: z
112112
 
+Subject: Test
112113
 
+Comment:                                    
112114
 
+
112115
 
+Test!
112116
 
+.
112117
 
+;
112118
 
+
112119
 
+/*
112120
 
+ * Empty strings
112121
 
+ */
112122
 
+
112123
 
+test "Value \"\" eq 40 (vs)" {
112124
 
+       if header :value "eq" :comparator "i;ascii-numeric" "comment" "40" {
112125
 
+               test_fail ":value matched empty string with i;ascii-numeric";
112126
 
+       }
112127
 
+
112128
 
+       if header :value "gt" :comparator "i;ascii-numeric" "x-spam-score" "" {
112129
 
+               test_fail ":value 300 exceeded empty string with i;ascii-numeric";
112130
 
+       }
112131
 
+
112132
 
+       if header :value "gt" :comparator "i;ascii-numeric" "x-spam-score" "" {
112133
 
+        test_fail ":count exceeded empty string with i;ascii-numeric";
112134
 
+    }
112135
 
+}
112136
 
+
112137
 
+/* 
112138
 
+ * Match type :value
112139
 
+ */
112140
 
+
112141
 
+test "Value 300 eq 2" {
112142
 
+       if header :value "eq" :comparator "i;ascii-numeric" "x-spam-score" "2" {
112143
 
+               test_fail "should not have matched";
112144
 
+       } 
112145
 
+}
112146
 
+
112147
 
+test "Value 300 lt 2" {
112148
 
+       if header :value "lt" :comparator "i;ascii-numeric" "x-spam-score" "2" {
112149
 
+               test_fail "should not have matched";
112150
 
+       }
112151
 
+}
112152
 
+
112153
 
+test "Value 300 le 300" {
112154
 
+       if not header :value "le" :comparator "i;ascii-numeric" "x-spam-score" "300" {
112155
 
+               test_fail "should have matched";
112156
 
+       }
112157
 
+}
112158
 
+
112159
 
+test "Value 300 le 302" {
112160
 
+       if not header :value "le" :comparator "i;ascii-numeric" "x-spam-score" "302" {
112161
 
+               test_fail "should have matched";
112162
 
+       }
112163
 
+}
112164
 
+
112165
 
+test "Value 302 le 00302" {
112166
 
+       if not header :value "le" :comparator "i;ascii-numeric" "x-spam-score" "00302" {
112167
 
+               test_fail "should have matched";
112168
 
+    }
112169
 
+}
112170
 
+
112171
 
+test "Value {1000,20} le 300" {
112172
 
+    if not header :value "le" :comparator "i;ascii-numeric" "x-nonsense" "300" {
112173
 
+        test_fail "should have matched";
112174
 
+    }
112175
 
+}
112176
 
+
112177
 
+test "Value {1000,20} lt 3" {
112178
 
+    if header :value "lt" :comparator "i;ascii-numeric" "x-nonsense" "3" {
112179
 
+        test_fail "should not have matched";
112180
 
+    }
112181
 
+}
112182
 
+
112183
 
+test "Value {1000,20} gt 3000" {
112184
 
+    if header :value "gt" :comparator "i;ascii-numeric" "x-nonsense" "3000" {
112185
 
+        test_fail "should not have matched";
112186
 
+    }
112187
 
+}
112188
 
+
112189
 
+test "Value {1000,20} gt {3000,30}" {
112190
 
+    if not header :value "gt" :comparator "i;ascii-numeric" "x-nonsense" ["3000","30"] {
112191
 
+        test_fail "should have matched";
112192
 
+    }
112193
 
+}
112194
 
+
112195
 
+test "Value {1000,20} lt {3, 19})" {
112196
 
+    if header :value "lt" :comparator "i;ascii-numeric" "x-nonsense" ["3","19"] {
112197
 
+        test_fail "should not have matched";
112198
 
+    }
112199
 
+}
112200
 
+
112201
 
+test "Value {1000,20} gt {3000,1001}" {
112202
 
+    if header :value "gt" :comparator "i;ascii-numeric" "x-nonsense" ["3000","1001"] {
112203
 
+        test_fail "should not have matched";
112204
 
+    }
112205
 
+}
112206
 
+
112207
 
+test "Value abcdzyz gt aaaaaaa" {
112208
 
+    if not header :value "gt" :comparator "i;octet" "x-alpha" "aaaaaaa" {
112209
 
+        test_fail "should have matched";
112210
 
+    }
112211
 
+}
112212
 
+
112213
 
+/* 
112214
 
+ * Match type :count
112215
 
+ */
112216
 
+
112217
 
+test "Count 2 ne 2" {
112218
 
+       if header :count "ne" :comparator "i;ascii-numeric" "cc" "2" {
112219
 
+               test_fail "should not have matched";
112220
 
+       }
112221
 
+}
112222
 
+
112223
 
+test "Count 2 ge 2" {
112224
 
+       if not header :count "ge" :comparator "i;ascii-numeric" "cc" "2" {
112225
 
+               test_fail "should have matched";
112226
 
+       }
112227
 
+}
112228
 
+
112229
 
+test "Count 2 ge 002" {
112230
 
+       if not header :count "ge" :comparator "i;ascii-numeric" "cc" "002" {
112231
 
+               test_fail "should have matched";
112232
 
+       }
112233
 
+}
112234
 
+
112235
 
+test "Count 26 lt {4,5,6,10,20}" {
112236
 
+       if header :count "lt" :comparator "i;ascii-numeric" "x-count" ["4","5","6","10","20"] {
112237
 
+               test_fail "should not have matched";
112238
 
+       }
112239
 
+}
112240
 
+
112241
 
+test "Count 26 lt {4,5,6,10,20,100}" {
112242
 
+       if not header :count "lt" :comparator "i;ascii-numeric" "x-count" ["4","5","6","10","20","100"] {
112243
 
+               test_fail "should have matched";
112244
 
+       }
112245
 
+}
112246
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/relational/errors/validation.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/relational/errors/validation.sieve
112247
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/relational/errors/validation.sieve  1970-01-01 01:00:00.000000000 +0100
112248
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/relational/errors/validation.sieve   2008-08-25 10:25:08.000000000 +0200
112249
 
@@ -0,0 +1,11 @@
112250
 
+require "relational";
112251
 
+
112252
 
+# Not a valid relation (1)
112253
 
+if header :value "gr" "from" "ah" {
112254
 
+       keep;
112255
 
+} 
112256
 
+
112257
 
+# Not a valid relation (1)
112258
 
+if header :count "lf" "from" "eek" {
112259
 
+       keep;
112260
 
+}
112261
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/relational/errors.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/relational/errors.svtest
112262
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/relational/errors.svtest    1970-01-01 01:00:00.000000000 +0100
112263
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/relational/errors.svtest     2009-01-06 00:15:52.000000000 +0100
112264
 
@@ -0,0 +1,15 @@
112265
 
+require "vnd.dovecot.testsuite";
112266
 
+
112267
 
+# A bit awkward to test the extension with itself
112268
 
+require "relational";
112269
 
+require "comparator-i;ascii-numeric";
112270
 
+
112271
 
+test "Validation errors" {
112272
 
+       if test_script_compile "errors/validation.sieve" {
112273
 
+               test_fail "compile should have failed";
112274
 
+       }
112275
 
+
112276
 
+       if test_error :count "ne" "3" {
112277
 
+               test_fail "wrong number of errors reported";
112278
 
+       }
112279
 
+}
112280
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/relational/rfc.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/relational/rfc.svtest
112281
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/relational/rfc.svtest       1970-01-01 01:00:00.000000000 +0100
112282
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/relational/rfc.svtest        2008-08-25 10:25:08.000000000 +0200
112283
 
@@ -0,0 +1,71 @@
112284
 
+require "vnd.dovecot.testsuite";
112285
 
+
112286
 
+require "relational";
112287
 
+require "comparator-i;ascii-numeric";
112288
 
+
112289
 
+test_set "message" text:
112290
 
+Received: ...
112291
 
+Received: ...
112292
 
+Subject: example
112293
 
+To: foo@example.com, baz@example.com
112294
 
+CC: qux@example.com
112295
 
+
112296
 
+RFC Example
112297
 
+.
112298
 
+;
112299
 
+
112300
 
+test "Example 1" {
112301
 
+       # The test:
112302
 
+
112303
 
+       if not address :count "ge" :comparator "i;ascii-numeric"
112304
 
+               ["to", "cc"] ["3"] {
112305
 
+       
112306
 
+               test_fail "should have counted three addresses";
112307
 
+       }
112308
 
+
112309
 
+    # would evaluate to true, and the test
112310
 
+
112311
 
+       if anyof ( 
112312
 
+                       address :count "ge" :comparator "i;ascii-numeric"
112313
 
+                               ["to"] ["3"],
112314
 
+                       address :count "ge" :comparator "i;ascii-numeric"
112315
 
+                               ["cc"] ["3"] 
112316
 
+       ) {
112317
 
+       
112318
 
+               test_fail "should not have counted three addresses";
112319
 
+       }
112320
 
+
112321
 
+       # would evaluate to false.
112322
 
+
112323
 
+       # To check the number of received fields in the header, the following
112324
 
+       # test may be used:
112325
 
+
112326
 
+       if header :count "ge" :comparator "i;ascii-numeric"
112327
 
+               ["received"] ["3"] {
112328
 
+       
112329
 
+               test_fail "should not have counted three received headers";
112330
 
+       }
112331
 
+
112332
 
+       # This would evaluate to false.  But
112333
 
+
112334
 
+       if not header :count "ge" :comparator "i;ascii-numeric"
112335
 
+               ["received", "subject"] ["3"] {
112336
 
+
112337
 
+               test_fail "should have counted three headers";
112338
 
+       }
112339
 
+
112340
 
+       # would evaluate to true.
112341
 
+       
112342
 
+       # The test:
112343
 
+
112344
 
+       if header :count "ge" :comparator "i;ascii-numeric"
112345
 
+               ["to", "cc"] ["3"] {
112346
 
+
112347
 
+               test_fail "should not have counted three to or cc headers";
112348
 
+       }
112349
 
+
112350
 
+       # will always evaluate to false on an RFC 2822 compliant message
112351
 
+       # [RFC2822], since a message can have at most one "to" field and at
112352
 
+       # most one "cc" field.  This test counts the number of fields, not the
112353
 
+       # number of addresses.
112354
 
+}
112355
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/subaddress/basic.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/subaddress/basic.svtest
112356
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/subaddress/basic.svtest     1970-01-01 01:00:00.000000000 +0100
112357
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/subaddress/basic.svtest      2009-07-19 15:54:39.000000000 +0200
112358
 
@@ -0,0 +1,111 @@
112359
 
+require "vnd.dovecot.testsuite";
112360
 
+require "envelope";
112361
 
+require "subaddress";
112362
 
+
112363
 
+test_set "message" text:
112364
 
+From: stephan+sieve@renane-it.nl
112365
 
+To: test+failed@example.com
112366
 
+Subject: subaddress test
112367
 
+
112368
 
+Test!
112369
 
+.
112370
 
+;
112371
 
+
112372
 
+test_set "envelope.to" "friep+frop@dovecot.org";
112373
 
+test_set "envelope.from" "list+request@lists.dovecot.org";
112374
 
+
112375
 
+test "Address from :user" {
112376
 
+       if not address :is :user "from" "stephan" {
112377
 
+               test_fail "wrong user part extracted";
112378
 
+       }
112379
 
+
112380
 
+       if address :is :user "from" "nonsence" {
112381
 
+               test_fail "address test failed";
112382
 
+       }
112383
 
+}
112384
 
+
112385
 
+test "Address from :detail" {
112386
 
+       if not address :is :detail "from" "sieve" {
112387
 
+               test_fail "wrong user part extracted";
112388
 
+       }
112389
 
+
112390
 
+       if address :is :detail "from" "nonsence" {
112391
 
+               test_fail "address test failed";
112392
 
+       }
112393
 
+}
112394
 
+
112395
 
+test "Address to :user" {
112396
 
+       if not address :contains :user "to" "est" {
112397
 
+               test_fail "wrong user part extracted";
112398
 
+       }
112399
 
+
112400
 
+       if address :contains :user "to" "ail" {
112401
 
+               test_fail "address test failed";
112402
 
+       }
112403
 
+}
112404
 
+
112405
 
+test "Address to :detail" {
112406
 
+       if not address :contains :detail "to" "fai" {
112407
 
+               test_fail "wrong user part extracted";
112408
 
+       }
112409
 
+
112410
 
+       if address :contains :detail "to" "sen" {
112411
 
+               test_fail "address test failed";
112412
 
+       }
112413
 
+}
112414
 
+
112415
 
+
112416
 
+test "Envelope :user" {
112417
 
+    if not envelope :is :user "to" "friep" {
112418
 
+        test_fail "wrong user part extracted 1";
112419
 
+    }
112420
 
+
112421
 
+    if not envelope :comparator "i;ascii-casemap" :is :user "to" "FRIEP" {
112422
 
+        test_fail "wrong user part extracted";
112423
 
+    }
112424
 
+
112425
 
+    if envelope :comparator "i;ascii-casemap" :is :user "to" "FROP" {
112426
 
+        test_fail "envelope test failed";
112427
 
+    }
112428
 
+}
112429
 
+
112430
 
+test "Envelope :detail" {
112431
 
+    if not envelope :comparator "i;ascii-casemap" :contains :detail "from" "QUES" {
112432
 
+        test_fail "wrong user part extracted";
112433
 
+    }
112434
 
+
112435
 
+    if envelope :comparator "i;ascii-casemap" :contains :detail "from" "LIS" {
112436
 
+        test_fail "address test failed";
112437
 
+    }
112438
 
+}
112439
 
+
112440
 
+test_set "message" text:
112441
 
+From: frop@examples.com
112442
 
+To: undisclosed-recipients:;
112443
 
+Subject: subaddress test
112444
 
+
112445
 
+Test!
112446
 
+.
112447
 
+;
112448
 
+
112449
 
+test "Undisclosed-recipients" {
112450
 
+       if address :detail :contains "to" "undisclosed-recipients" {
112451
 
+               test_fail ":detail matched group name";
112452
 
+       }
112453
 
+
112454
 
+       if address :user :contains "to" "undisclosed-recipients" {
112455
 
+               test_fail ":user matched group name";
112456
 
+       }
112457
 
+}
112458
 
+
112459
 
+test_set "envelope.to" "frop@sieve.nl";
112460
 
+
112461
 
+test "No detail" {
112462
 
+       if envelope :detail "to" "virus" {
112463
 
+               test_fail ":detail matched non-existant detail element in envelope (separator is missing)";
112464
 
+       }
112465
 
+
112466
 
+       if address :detail "from" "virus" {
112467
 
+               test_fail ":detail matched non-existant detail element in from header (separator is missing)";          
112468
 
+       }
112469
 
+}
112470
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/subaddress/rfc.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/subaddress/rfc.svtest
112471
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/subaddress/rfc.svtest       1970-01-01 01:00:00.000000000 +0100
112472
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/subaddress/rfc.svtest        2008-08-25 10:25:08.000000000 +0200
112473
 
@@ -0,0 +1,59 @@
112474
 
+require "vnd.dovecot.testsuite";
112475
 
+
112476
 
+require "subaddress";
112477
 
+
112478
 
+test_set "message" text:
112479
 
+From: stephan+@rename-it.nl
112480
 
+To: timo+spam@iki.fi
112481
 
+CC: nico@example.com
112482
 
+Subject: fetch my spam
112483
 
+
112484
 
+Mouhahahaha... Spam!
112485
 
+.
112486
 
+;
112487
 
+
112488
 
+
112489
 
+/*
112490
 
+ * The ":user" argument specifies the user sub-part of the local-part of
112491
 
+ * an address.  If the address is not encoded to contain a detail sub-
112492
 
+ * part, then ":user" specifies the entire left side of the address
112493
 
+ * (equivalent to ":localpart").
112494
 
+ */
112495
 
+
112496
 
+test "User sub-part" {
112497
 
+       if not address :user "cc" "nico" {
112498
 
+               test_fail "wrong :user part extracted (1)";
112499
 
+       }
112500
 
+
112501
 
+       if not address :user "to" "timo" {
112502
 
+               test_fail "wrong :user part extracted (2)";
112503
 
+       }
112504
 
+
112505
 
+       if not address :user "from" "stephan" {
112506
 
+               test_fail "wrong :user part extracted (3)";
112507
 
+       }
112508
 
+}
112509
 
+
112510
 
+/* The ":detail" argument specifies the detail sub-part of the local-
112511
 
+ * part of an address.  If the address is not encoded to contain a
112512
 
+ * detail sub-part, then the address fails to match any of the specified
112513
 
+ * keys.  If a zero-length string is encoded as the detail sub-part,
112514
 
+ * then ":detail" resolves to the empty value ("").
112515
 
+ */
112516
 
+
112517
 
+test "Detail sub-part" {
112518
 
+       if not address :detail "to" "spam" {
112519
 
+               test_fail "wrong :detail part extracted";
112520
 
+       }       
112521
 
+
112522
 
+       if anyof (
112523
 
+               address :detail :matches "cc" ["*", "?"],
112524
 
+               address :detail :contains "cc" "",
112525
 
+               address :detail :is "cc" "" ) {
112526
 
+               test_fail ":detail inappropriately matched missing detail sub-part";
112527
 
+       }
112528
 
+
112529
 
+       if not address :detail "from" "" {
112530
 
+               test_fail "wrong empty :detail part extracted";
112531
 
+       }               
112532
 
+}
112533
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/vacation/errors/conflict-reject.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/vacation/errors/conflict-reject.sieve
112534
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/vacation/errors/conflict-reject.sieve       1970-01-01 01:00:00.000000000 +0100
112535
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/vacation/errors/conflict-reject.sieve        2008-09-06 12:59:49.000000000 +0200
112536
 
@@ -0,0 +1,5 @@
112537
 
+require "vacation";
112538
 
+require "reject";
112539
 
+
112540
 
+vacation "Ik ben ff weg.";
112541
 
+reject "Ik heb nu geen zin aan mail.";
112542
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/vacation/errors.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/vacation/errors.svtest
112543
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/vacation/errors.svtest      1970-01-01 01:00:00.000000000 +0100
112544
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/vacation/errors.svtest       2009-01-06 00:15:52.000000000 +0100
112545
 
@@ -0,0 +1,19 @@
112546
 
+require "vnd.dovecot.testsuite";
112547
 
+
112548
 
+require "relational";
112549
 
+require "comparator-i;ascii-numeric";
112550
 
+
112551
 
+test "Action conflicts: reject <-> vacation" {
112552
 
+       if not test_script_compile "errors/conflict-reject.sieve" {
112553
 
+               test_fail "compile failed";
112554
 
+       }
112555
 
+
112556
 
+       if test_script_run {
112557
 
+               test_fail "execution should have failed";
112558
 
+       }
112559
 
+
112560
 
+       if test_error :count "gt" :comparator "i;ascii-numeric" "1" {
112561
 
+               test_fail "too many runtime errors reported";
112562
 
+       }
112563
 
+}
112564
 
+
112565
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/vacation/execute/action.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/vacation/execute/action.sieve
112566
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/vacation/execute/action.sieve       1970-01-01 01:00:00.000000000 +0100
112567
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/vacation/execute/action.sieve        2009-02-11 21:38:58.000000000 +0100
112568
 
@@ -0,0 +1,4 @@
112569
 
+require "vacation";
112570
 
+
112571
 
+vacation :addresses "stephan@rename-it.nl" "I am not at home today";
112572
 
+keep;
112573
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/vacation/execute/no-handle.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/vacation/execute/no-handle.sieve
112574
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/vacation/execute/no-handle.sieve    1970-01-01 01:00:00.000000000 +0100
112575
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/vacation/execute/no-handle.sieve     2008-09-06 12:59:49.000000000 +0200
112576
 
@@ -0,0 +1,7 @@
112577
 
+require "vacation";
112578
 
+require "variables";
112579
 
+
112580
 
+set "reason" "I have a conference in Seattle";
112581
 
+
112582
 
+vacation :subject "I am not in: ${reason}" :from "stephan@rename-it.nl" "I am gone for today: ${reason}.";
112583
 
+
112584
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/vacation/execute.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/vacation/execute.svtest
112585
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/vacation/execute.svtest     1970-01-01 01:00:00.000000000 +0100
112586
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/vacation/execute.svtest      2009-01-06 00:15:52.000000000 +0100
112587
 
@@ -0,0 +1,43 @@
112588
 
+require "vnd.dovecot.testsuite";
112589
 
+require "relational";
112590
 
+require "comparator-i;ascii-numeric";
112591
 
+
112592
 
+test "Action" {
112593
 
+       if not test_script_compile "execute/action.sieve" {
112594
 
+               test_fail "script compile failed";
112595
 
+       }
112596
 
+
112597
 
+       if not test_script_run {
112598
 
+               test_fail "script run failed";
112599
 
+       }
112600
 
+
112601
 
+       if not test_result :count "eq" :comparator "i;ascii-numeric" "2" {
112602
 
+               test_fail "invalid number of actions in result";
112603
 
+       }
112604
 
+
112605
 
+       if not test_result :index 1 "vacation" {
112606
 
+               test_fail "vacation action is not present as first item in result";
112607
 
+       }
112608
 
+       
112609
 
+       if not test_result :index 2 "keep" {
112610
 
+               test_fail "keep action is missing in result";
112611
 
+       }
112612
 
+
112613
 
+       if not test_result_execute {
112614
 
+               test_fail "result execute failed";
112615
 
+       }
112616
 
+}
112617
 
+
112618
 
+test "No :handle specified" {
112619
 
+       if not test_script_compile "execute/no-handle.sieve" {
112620
 
+               test_fail "script compile failed";
112621
 
+       }
112622
 
+
112623
 
+       if not test_script_run {
112624
 
+               test_fail "script execute failed";
112625
 
+       }
112626
 
+
112627
 
+       if not test_result_execute {
112628
 
+               test_fail "result execute failed";
112629
 
+       }
112630
 
+}
112631
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/vacation/message.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/vacation/message.svtest
112632
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/vacation/message.svtest     1970-01-01 01:00:00.000000000 +0100
112633
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/vacation/message.svtest      2009-07-15 17:59:21.000000000 +0200
112634
 
@@ -0,0 +1,48 @@
112635
 
+require "vnd.dovecot.testsuite";
112636
 
+require "vacation";
112637
 
+
112638
 
+test_set "message" text:
112639
 
+From: stephan@rename-it.nl
112640
 
+Subject: frop
112641
 
+References: <1234@local.machine.example> <3456@example.net>
112642
 
+ <435444@ttms.com> <4223@froop.nl> <m345444444@message-id.exp>
112643
 
+Message-ID: <432df324@rename-it.nl>
112644
 
+To: nico@vestingbar.nl
112645
 
+
112646
 
+Frop
112647
 
+.
112648
 
+;
112649
 
+
112650
 
+test "References" {
112651
 
+       vacation "I am not in today!";
112652
 
+
112653
 
+       if not test_result_execute {
112654
 
+               test_fail "execution of result failed";
112655
 
+       }
112656
 
+
112657
 
+       test_message :smtp 0;
112658
 
+
112659
 
+       if not header :contains "references" "432df324@rename-it.nl" {
112660
 
+               test_fail "references header does not contain new id";
112661
 
+       }
112662
 
+
112663
 
+       if anyof ( 
112664
 
+               not header :contains "references" "1234@local.machine.example", 
112665
 
+               not header :contains "references" "3456@example.net",
112666
 
+               not header :contains "references" "435444@ttms.com", 
112667
 
+               not header :contains "references" "4223@froop.nl", 
112668
 
+               not header :contains "references" "m345444444@message-id.exp" 
112669
 
+               ) {
112670
 
+               test_fail "references header does not contain all existing ids";
112671
 
+       }
112672
 
+
112673
 
+       if header :contains "references" "hutsefluts" {
112674
 
+               test_fail "references header contains nonsense";
112675
 
+       }
112676
 
+}
112677
 
+
112678
 
+test "In-Reply-To" {
112679
 
+       if not header :is "in-reply-to" "<432df324@rename-it.nl>" {
112680
 
+               test_fail "in-reply-to header set incorrectly";
112681
 
+       }
112682
 
+}
112683
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/vacation/references.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/vacation/references.sieve
112684
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/vacation/references.sieve   1970-01-01 01:00:00.000000000 +0100
112685
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/vacation/references.sieve    2008-12-18 00:22:42.000000000 +0100
112686
 
@@ -0,0 +1,4 @@
112687
 
+require "vacation";
112688
 
+
112689
 
+vacation "I am on vacation.";
112690
 
+discard;
112691
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/vacation/smtp.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/vacation/smtp.svtest
112692
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/vacation/smtp.svtest        1970-01-01 01:00:00.000000000 +0100
112693
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/vacation/smtp.svtest 2009-07-21 12:44:25.000000000 +0200
112694
 
@@ -0,0 +1,56 @@
112695
 
+require "vnd.dovecot.testsuite";
112696
 
+require "envelope";
112697
 
+require "vacation";
112698
 
+
112699
 
+test_set "message" text:
112700
 
+From: stephan@rename-it.nl
112701
 
+To: tss@iki.fi
112702
 
+Subject: Frop!
112703
 
+
112704
 
+Frop!
112705
 
+.
112706
 
+;
112707
 
+
112708
 
+test_set "envelope.from" "sirius@rename-it.nl";
112709
 
+test_set "envelope.to" "timo@iki.fi";
112710
 
+
112711
 
+test "Basic" {
112712
 
+       vacation :addresses "tss@iki.fi" :from "Timo Sirainen <tss@iki.fi>" "I am gone";
112713
 
+
112714
 
+       if not test_result_execute {
112715
 
+        test_fail "failed to execute vacation";
112716
 
+    }
112717
 
+
112718
 
+    test_message :smtp 0;
112719
 
+
112720
 
+    if not address :is "to" "sirius@rename-it.nl" {
112721
 
+        test_fail "to address incorrect";
112722
 
+    }
112723
 
+
112724
 
+    if not address :is "from" "tss@iki.fi" {
112725
 
+        test_fail "from address incorrect";
112726
 
+    }
112727
 
+
112728
 
+       if not envelope :is "to" "sirius@rename-it.nl" {
112729
 
+               test_fail "envelope recipient incorrect";
112730
 
+       }
112731
 
+
112732
 
+       if not envelope :is "from" "" {
112733
 
+               test_fail "envelope sender not null";
112734
 
+       }
112735
 
+}
112736
 
+
112737
 
+test_result_reset;
112738
 
+test_set "envelope.from" "<>";
112739
 
+
112740
 
+test "Null Sender" {
112741
 
+       vacation :addresses "tss@iki.fi" "I am gone";
112742
 
+
112743
 
+       if not test_result_execute {
112744
 
+               test_fail "failed to execute vacation";
112745
 
+       }
112746
 
+
112747
 
+       if test_message :smtp 0 {
112748
 
+               test_fail "reject sent message to NULL sender";
112749
 
+       }
112750
 
+}
112751
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/variables/basic.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/variables/basic.svtest
112752
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/variables/basic.svtest      1970-01-01 01:00:00.000000000 +0100
112753
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/variables/basic.svtest       2008-08-13 00:27:45.000000000 +0200
112754
 
@@ -0,0 +1,223 @@
112755
 
+require "vnd.dovecot.testsuite";
112756
 
+require "variables";
112757
 
+
112758
 
+test_set "message" text:
112759
 
+From: stephan@rename-it.nl
112760
 
+To: test@example.com
112761
 
+Subject: Variables test
112762
 
+
112763
 
+Testing variables...
112764
 
+.
112765
 
+;
112766
 
+
112767
 
+/*
112768
 
+ * Substitution syntax
112769
 
+ */
112770
 
+
112771
 
+test "Unknown variables" {
112772
 
+       set "q" "a";
112773
 
+       set "qw" "bb";
112774
 
+       set "qwe" "ccc";
112775
 
+       set "qwer" "dddd";
112776
 
+       set "qwert" "ccc";
112777
 
+
112778
 
+       if anyof (
112779
 
+               not string "[${qwerty}]" "[]",
112780
 
+               not string "[${20}]" "[]"
112781
 
+       ) {
112782
 
+               test_fail "unknown variable not substituted with empty string";
112783
 
+       }
112784
 
+}
112785
 
+
112786
 
+test "One pass" {
112787
 
+       set "something" "value";
112788
 
+       set "s" "$";
112789
 
+       
112790
 
+       if string "${s}{something}" "value" {
112791
 
+               test_fail "somehow variable string is scanned multiple times";
112792
 
+       }
112793
 
+
112794
 
+       if not string :matches "${s}{something}" "?{something}" {
112795
 
+               test_fail "unexpected result";
112796
 
+       }
112797
 
+}
112798
 
+
112799
 
+test "Syntax errors" {
112800
 
+       set "s" "$";
112801
 
+       set "variable" "nonsense";
112802
 
+
112803
 
+       if anyof ( 
112804
 
+               not string "$" "${s}",
112805
 
+               not string "${" "${s}{",
112806
 
+               not string "${a" "${s}{a",
112807
 
+               not string "${$}" "${s}{$}",
112808
 
+               not string "${%%%%}" "${s}{%%%%}",
112809
 
+               not string "${0.s}" "${s}{0.s}",
112810
 
+               not string "&%${}!" "&%${s}{}!",
112811
 
+               not string "${doh!}" "${s}{doh!}" )
112812
 
+       {
112813
 
+               test_fail "variables substitution changed substring not matching variable-ref";
112814
 
+       }       
112815
 
+}
112816
 
+
112817
 
+test "RFC syntax examples" {
112818
 
+       # The variable "company" holds the value "ACME".  No other variables
112819
 
+    # are set. 
112820
 
+       set "company" "ACME";
112821
 
+
112822
 
+       # "${full}"         => the empty string
112823
 
+       if not string :is "${full}" "" {
112824
 
+               test_fail "unknown variable did not yield empty string";
112825
 
+       }
112826
 
+
112827
 
+       # "${company}"      => "ACME"
112828
 
+       if not string :is "${company}" "ACME" {
112829
 
+               test_fail "assigned variable did not get substituted";
112830
 
+       }
112831
 
+
112832
 
+       # "${BAD${Company}" => "${BADACME"
112833
 
+       if not string :is "${BAD${Company}" "${BADACME" {
112834
 
+               test_fail "'BADACME' test did not yield expected result";
112835
 
+       }
112836
 
+
112837
 
+       #"${President, ${Company} Inc.}" 
112838
 
+       #                        => "${President, ACME Inc.}"
112839
 
+       if not string "${President, ${Company} Inc.}"
112840
 
+               "${President, ACME Inc.}" {
112841
 
+               test_fail "'Company president' test did not yield expected result";
112842
 
+       }
112843
 
+}
112844
 
+
112845
 
+/*
112846
 
+ * Variable assignments
112847
 
+ */
112848
 
+
112849
 
+test "Basic assignment" {
112850
 
+       set "test" "Value";
112851
 
+
112852
 
+       if not string :is "${test}" "Value" {
112853
 
+               test_fail "variable assignment failed";
112854
 
+       }
112855
 
+
112856
 
+       if string :is "${test}" "value" {
112857
 
+               test_fail "string test failed";
112858
 
+       }
112859
 
+}
112860
 
+
112861
 
+test "Assignment overwritten" {
112862
 
+       set "test" "Value";
112863
 
+       set "test" "More";
112864
 
+
112865
 
+       if not string :is "${test}" "More" {
112866
 
+               test_fail "variable assignment failed";
112867
 
+       }
112868
 
+
112869
 
+       if string :is "${test}" "Value" {
112870
 
+               test_fail "value not overwritten";
112871
 
+       }
112872
 
+
112873
 
+       if string :is "${test}" "nonsense" {
112874
 
+               test_fail "string test failed";
112875
 
+       }
112876
 
+}
112877
 
+
112878
 
+test "Two assignments" {
112879
 
+       set "test" "Value";
112880
 
+       set "test2" "More";
112881
 
+
112882
 
+       if not string :is "${test}" "Value" {
112883
 
+               test_fail "variable assignment failed";
112884
 
+       }
112885
 
+
112886
 
+       if string :is "${test}" "More" {
112887
 
+               test_fail "assignments to different variables overlap";
112888
 
+       }
112889
 
+
112890
 
+       if string :is "${test}" "nonsense" {
112891
 
+               test_fail "string test failed";
112892
 
+       }
112893
 
+}
112894
 
+
112895
 
+test "Variables case-insensitive" {
112896
 
+       set "VeRyElAboRATeVaRIABLeName" "interesting value";
112897
 
+
112898
 
+       if not string "${veryelaboratevariablename}" "interesting value" {
112899
 
+               test_fail "variable names are case sensitive (lower case try)";
112900
 
+       }
112901
 
+
112902
 
+       if not string "${VERYELABORATEVARIABLENAME}" "interesting value" {
112903
 
+               test_fail "variable names are case sensitive (upper case try)";
112904
 
+       }
112905
 
+}
112906
 
+
112907
 
+test "RFC set command example" {
112908
 
+       set "honorific"  "Mr";
112909
 
+       set "first_name" "Wile";
112910
 
+       set "last_name"  "Coyote";
112911
 
+       set "vacation" text:
112912
 
+Dear ${HONORIFIC} ${last_name},
112913
 
+I'm out, please leave a message after the meep.
112914
 
+.
112915
 
+;
112916
 
+       if not string :is :comparator "i;octet" "${VAcaTION}" text:
112917
 
+Dear Mr Coyote,
112918
 
+I'm out, please leave a message after the meep.
112919
 
+.
112920
 
+       {
112921
 
+               test_fail "failed to set variable correctly: ${VAcaTION}";
112922
 
+       }
112923
 
+}
112924
 
+
112925
 
+/*
112926
 
+ * Variable substitution
112927
 
+ */
112928
 
+
112929
 
+test "Multi-line string substitution" {
112930
 
+       set "name" "Stephan Bosch";
112931
 
+       set "address" "stephan@rename-it.nl";
112932
 
+       set "subject" "Test message";
112933
 
+       
112934
 
+       set "message" text: # Message with substitutions
112935
 
+From: ${name} <${address}>
112936
 
+To: Bertus van Asseldonk <b.vanasseldonk@hetkennet.nl>
112937
 
+Subject: ${subject}
112938
 
+
112939
 
+This is a test message.
112940
 
+.
112941
 
+;
112942
 
+       if not string :is "${message}" text:
112943
 
+From: Stephan Bosch <stephan@rename-it.nl>
112944
 
+To: Bertus van Asseldonk <b.vanasseldonk@hetkennet.nl>
112945
 
+Subject: Test message
112946
 
+
112947
 
+This is a test message.
112948
 
+.
112949
 
+       {
112950
 
+               test_fail "variable substitution failed";
112951
 
+       }
112952
 
+}
112953
 
+
112954
 
+test "Multiple substitutions" {
112955
 
+       set "a" "the monkey";
112956
 
+       set "b" "a nut";
112957
 
+       set "c" "the fish";
112958
 
+       set "d" "on fire";
112959
 
+       set "e" "eats";
112960
 
+       set "f" "is";
112961
 
+
112962
 
+       if not string :is "${a} ${e} ${b}" "the monkey eats a nut" {
112963
 
+               test_fail "variable substitution failed (1)";
112964
 
+       }
112965
 
+
112966
 
+       if not string :is "${c} ${f} ${d}" "the fish is on fire" {
112967
 
+               test_fail "variable substitution failed (2)";
112968
 
+       }
112969
 
+
112970
 
+       set :upperfirst "sentence" "${a} ${e} ${b}";
112971
 
+
112972
 
+       if not string :is "${sentence}" "The monkey eats a nut" {
112973
 
+               test_fail "modified variable substitution failed";
112974
 
+       }       
112975
 
+}
112976
 
+
112977
 
+
112978
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/variables/errors/limits.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/variables/errors/limits.sieve
112979
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/variables/errors/limits.sieve       1970-01-01 01:00:00.000000000 +0100
112980
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/variables/errors/limits.sieve        2008-08-13 00:27:45.000000000 +0200
112981
 
@@ -0,0 +1,287 @@
112982
 
+require "variables";
112983
 
+
112984
 
+# Not an error (0)
112985
 
+set "var123456789012345678901234567890" "value";
112986
 
+
112987
 
+# Exceed the maximum variable name length (1)
112988
 
+set "var123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" "value";
112989
 
+
112990
 
+# Must yield unknown namespace error (no limit exceeded) (1)
112991
 
+set "namespace.sub.sub.variable" "value"; 
112992
 
+
112993
 
+# Must yield unknown namespace error (exceeds element limit) (1)
112994
 
+set "namespace.sub.sub.sub.variable" "value";
112995
 
+
112996
 
+# Not an error (0)
112997
 
+if string "${32}" "value" {
112998
 
+       stop;
112999
 
+}
113000
 
+
113001
 
+# Exceed the maximum match value index (1)
113002
 
+if string "${33}" "value" {
113003
 
+       stop;
113004
 
+}
113005
 
+
113006
 
+# Exceed the maximum number of declared variables (1!)
113007
 
+set "var001" "value";
113008
 
+set "var002" "value";
113009
 
+set "var003" "value";
113010
 
+set "var004" "value";
113011
 
+set "var005" "value";
113012
 
+set "var006" "value";
113013
 
+set "var007" "value";
113014
 
+set "var008" "value";
113015
 
+set "var009" "value";
113016
 
+set "var010" "value";
113017
 
+set "var011" "value";
113018
 
+set "var012" "value";
113019
 
+set "var013" "value";
113020
 
+set "var014" "value";
113021
 
+set "var015" "value";
113022
 
+set "var016" "value";
113023
 
+set "var017" "value";
113024
 
+set "var018" "value";
113025
 
+set "var019" "value";
113026
 
+set "var020" "value";
113027
 
+set "var021" "value";
113028
 
+set "var022" "value";
113029
 
+set "var023" "value";
113030
 
+set "var024" "value";
113031
 
+set "var025" "value";
113032
 
+set "var026" "value";
113033
 
+set "var027" "value";
113034
 
+set "var028" "value";
113035
 
+set "var029" "value";
113036
 
+set "var030" "value";
113037
 
+set "var031" "value";
113038
 
+set "var032" "value";
113039
 
+set "var033" "value";
113040
 
+set "var034" "value";
113041
 
+set "var035" "value";
113042
 
+set "var036" "value";
113043
 
+set "var037" "value";
113044
 
+set "var038" "value";
113045
 
+set "var039" "value";
113046
 
+set "var040" "value";
113047
 
+set "var041" "value";
113048
 
+set "var042" "value";
113049
 
+set "var043" "value";
113050
 
+set "var044" "value";
113051
 
+set "var045" "value";
113052
 
+set "var046" "value";
113053
 
+set "var047" "value";
113054
 
+set "var048" "value";
113055
 
+set "var049" "value";
113056
 
+set "var050" "value";
113057
 
+set "var051" "value";
113058
 
+set "var052" "value";
113059
 
+set "var053" "value";
113060
 
+set "var054" "value";
113061
 
+set "var055" "value";
113062
 
+set "var056" "value";
113063
 
+set "var057" "value";
113064
 
+set "var058" "value";
113065
 
+set "var059" "value";
113066
 
+set "var060" "value";
113067
 
+set "var061" "value";
113068
 
+set "var062" "value";
113069
 
+set "var063" "value";
113070
 
+set "var064" "value";
113071
 
+set "var065" "value";
113072
 
+set "var066" "value";
113073
 
+set "var067" "value";
113074
 
+set "var068" "value";
113075
 
+set "var069" "value";
113076
 
+set "var070" "value";
113077
 
+set "var071" "value";
113078
 
+set "var072" "value";
113079
 
+set "var073" "value";
113080
 
+set "var074" "value";
113081
 
+set "var075" "value";
113082
 
+set "var076" "value";
113083
 
+set "var077" "value";
113084
 
+set "var078" "value";
113085
 
+set "var079" "value";
113086
 
+set "var080" "value";
113087
 
+set "var081" "value";
113088
 
+set "var082" "value";
113089
 
+set "var083" "value";
113090
 
+set "var084" "value";
113091
 
+set "var085" "value";
113092
 
+set "var086" "value";
113093
 
+set "var087" "value";
113094
 
+set "var088" "value";
113095
 
+set "var089" "value";
113096
 
+set "var090" "value";
113097
 
+set "var091" "value";
113098
 
+set "var092" "value";
113099
 
+set "var093" "value";
113100
 
+set "var094" "value";
113101
 
+set "var095" "value";
113102
 
+set "var096" "value";
113103
 
+set "var097" "value";
113104
 
+set "var098" "value";
113105
 
+set "var099" "value";
113106
 
+
113107
 
+set "var100" "value";
113108
 
+set "var101" "value";
113109
 
+set "var102" "value";
113110
 
+set "var103" "value";
113111
 
+set "var104" "value";
113112
 
+set "var105" "value";
113113
 
+set "var106" "value";
113114
 
+set "var107" "value";
113115
 
+set "var108" "value";
113116
 
+set "var109" "value";
113117
 
+set "var110" "value";
113118
 
+set "var111" "value";
113119
 
+set "var112" "value";
113120
 
+set "var113" "value";
113121
 
+set "var114" "value";
113122
 
+set "var115" "value";
113123
 
+set "var116" "value";
113124
 
+set "var117" "value";
113125
 
+set "var118" "value";
113126
 
+set "var119" "value";
113127
 
+set "var120" "value";
113128
 
+set "var121" "value";
113129
 
+set "var122" "value";
113130
 
+set "var123" "value";
113131
 
+set "var124" "value";
113132
 
+set "var125" "value";
113133
 
+set "var126" "value";
113134
 
+set "var127" "value";
113135
 
+set "var128" "value";
113136
 
+set "var129" "value";
113137
 
+set "var130" "value";
113138
 
+set "var131" "value";
113139
 
+set "var132" "value";
113140
 
+set "var133" "value";
113141
 
+set "var134" "value";
113142
 
+set "var135" "value";
113143
 
+set "var136" "value";
113144
 
+set "var137" "value";
113145
 
+set "var138" "value";
113146
 
+set "var139" "value";
113147
 
+set "var140" "value";
113148
 
+set "var141" "value";
113149
 
+set "var142" "value";
113150
 
+set "var143" "value";
113151
 
+set "var144" "value";
113152
 
+set "var145" "value";
113153
 
+set "var146" "value";
113154
 
+set "var147" "value";
113155
 
+set "var148" "value";
113156
 
+set "var149" "value";
113157
 
+set "var150" "value";
113158
 
+set "var151" "value";
113159
 
+set "var152" "value";
113160
 
+set "var153" "value";
113161
 
+set "var154" "value";
113162
 
+set "var155" "value";
113163
 
+set "var156" "value";
113164
 
+set "var157" "value";
113165
 
+set "var158" "value";
113166
 
+set "var159" "value";
113167
 
+set "var160" "value";
113168
 
+set "var161" "value";
113169
 
+set "var162" "value";
113170
 
+set "var163" "value";
113171
 
+set "var164" "value";
113172
 
+set "var165" "value";
113173
 
+set "var166" "value";
113174
 
+set "var167" "value";
113175
 
+set "var168" "value";
113176
 
+set "var169" "value";
113177
 
+set "var170" "value";
113178
 
+set "var171" "value";
113179
 
+set "var172" "value";
113180
 
+set "var173" "value";
113181
 
+set "var174" "value";
113182
 
+set "var175" "value";
113183
 
+set "var176" "value";
113184
 
+set "var177" "value";
113185
 
+set "var178" "value";
113186
 
+set "var179" "value";
113187
 
+set "var180" "value";
113188
 
+set "var181" "value";
113189
 
+set "var182" "value";
113190
 
+set "var183" "value";
113191
 
+set "var184" "value";
113192
 
+set "var185" "value";
113193
 
+set "var186" "value";
113194
 
+set "var187" "value";
113195
 
+set "var188" "value";
113196
 
+set "var189" "value";
113197
 
+set "var190" "value";
113198
 
+set "var191" "value";
113199
 
+set "var192" "value";
113200
 
+set "var193" "value";
113201
 
+set "var194" "value";
113202
 
+set "var195" "value";
113203
 
+set "var196" "value";
113204
 
+set "var197" "value";
113205
 
+set "var198" "value";
113206
 
+set "var199" "value";
113207
 
+set "var200" "value";
113208
 
+
113209
 
+set "var201" "value";
113210
 
+set "var202" "value";
113211
 
+set "var203" "value";
113212
 
+set "var204" "value";
113213
 
+set "var205" "value";
113214
 
+set "var206" "value";
113215
 
+set "var207" "value";
113216
 
+set "var208" "value";
113217
 
+set "var209" "value";
113218
 
+set "var210" "value";
113219
 
+set "var211" "value";
113220
 
+set "var212" "value";
113221
 
+set "var213" "value";
113222
 
+set "var214" "value";
113223
 
+set "var215" "value";
113224
 
+set "var216" "value";
113225
 
+set "var217" "value";
113226
 
+set "var218" "value";
113227
 
+set "var219" "value";
113228
 
+set "var220" "value";
113229
 
+set "var221" "value";
113230
 
+set "var222" "value";
113231
 
+set "var223" "value";
113232
 
+set "var224" "value";
113233
 
+set "var225" "value";
113234
 
+set "var226" "value";
113235
 
+set "var227" "value";
113236
 
+set "var228" "value";
113237
 
+set "var229" "value";
113238
 
+set "var230" "value";
113239
 
+set "var231" "value";
113240
 
+set "var232" "value";
113241
 
+set "var233" "value";
113242
 
+set "var234" "value";
113243
 
+set "var235" "value";
113244
 
+set "var236" "value";
113245
 
+set "var237" "value";
113246
 
+set "var238" "value";
113247
 
+set "var239" "value";
113248
 
+set "var240" "value";
113249
 
+set "var241" "value";
113250
 
+set "var242" "value";
113251
 
+set "var243" "value";
113252
 
+set "var244" "value";
113253
 
+set "var245" "value";
113254
 
+set "var246" "value";
113255
 
+set "var247" "value";
113256
 
+set "var248" "value";
113257
 
+set "var249" "value";
113258
 
+set "var250" "value";
113259
 
+set "var251" "value";
113260
 
+set "var252" "value";
113261
 
+set "var253" "value";
113262
 
+set "var254" "value";
113263
 
+set "var255" "value";
113264
 
+set "var256" "value";
113265
 
+set "var257" "value";
113266
 
+set "var258" "value";
113267
 
+set "var259" "value";
113268
 
+set "var260" "value";
113269
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/variables/errors/namespace.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/variables/errors/namespace.sieve
113270
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/variables/errors/namespace.sieve    1970-01-01 01:00:00.000000000 +0100
113271
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/variables/errors/namespace.sieve     2008-08-04 10:39:20.000000000 +0200
113272
 
@@ -0,0 +1,8 @@
113273
 
+require "variables";
113274
 
+require "fileinto";
113275
 
+
113276
 
+set "namespace.frop" "value";
113277
 
+set "complex.struct.frop" "value";
113278
 
+
113279
 
+fileinto "${namespace.frop}";
113280
 
+fileinto "${complex.struct.frop}";
113281
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/variables/errors/set.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/variables/errors/set.sieve
113282
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/variables/errors/set.sieve  1970-01-01 01:00:00.000000000 +0100
113283
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/variables/errors/set.sieve   2008-08-04 10:39:20.000000000 +0200
113284
 
@@ -0,0 +1,19 @@
113285
 
+require "variables";
113286
 
+
113287
 
+# Invalid variable name
113288
 
+set "${frop}" "frop";
113289
 
+set "...." "frop";
113290
 
+set "name." "frop";
113291
 
+set ".name" "frop";
113292
 
+
113293
 
+# Not an error
113294
 
+set "\n\a\m\e" "frop";
113295
 
+
113296
 
+# Trying to assign match variable;
113297
 
+set "0" "frop";
113298
 
+
113299
 
+# Not an error
113300
 
+set :UPPER "name" "frop";
113301
 
+
113302
 
+# Invalid tag
113303
 
+set :inner "name" "frop";
113304
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/variables/errors.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/variables/errors.svtest
113305
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/variables/errors.svtest     1970-01-01 01:00:00.000000000 +0100
113306
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/variables/errors.svtest      2009-01-06 00:15:52.000000000 +0100
113307
 
@@ -0,0 +1,34 @@
113308
 
+require "vnd.dovecot.testsuite";
113309
 
+
113310
 
+require "comparator-i;ascii-numeric";
113311
 
+require "relational";
113312
 
+
113313
 
+test "Invalid namespaces (FIXME: count only)" {
113314
 
+       if test_script_compile "errors/namespace.sieve" {
113315
 
+               test_fail "compile should have failed";
113316
 
+       }
113317
 
+
113318
 
+       if not test_error :count "eq" :comparator "i;ascii-numeric" "5" {
113319
 
+               test_fail "wrong number of errors reported";
113320
 
+       }
113321
 
+}
113322
 
+
113323
 
+test "Invalid set command invocations (FIXME: count only)" {
113324
 
+       if test_script_compile "errors/set.sieve" {
113325
 
+               test_fail "compile should have failed";
113326
 
+       }
113327
 
+
113328
 
+       if not test_error :count "eq" :comparator "i;ascii-numeric" "7" {
113329
 
+               test_fail "wrong number of errors reported";
113330
 
+       }
113331
 
+}
113332
 
+
113333
 
+test "Limits (FIXME: count only)" {
113334
 
+       if test_script_compile "errors/limits.sieve" {
113335
 
+               test_fail "compile should have failed";
113336
 
+       }
113337
 
+
113338
 
+       if not test_error :count "eq" :comparator "i;ascii-numeric" "6" {
113339
 
+               test_fail "wrong number of errors reported";
113340
 
+       }
113341
 
+}
113342
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/variables/match.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/variables/match.svtest
113343
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/variables/match.svtest      1970-01-01 01:00:00.000000000 +0100
113344
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/variables/match.svtest       2009-02-11 22:16:39.000000000 +0100
113345
 
@@ -0,0 +1,365 @@
113346
 
+require "vnd.dovecot.testsuite";
113347
 
+
113348
 
+require "variables";
113349
 
+
113350
 
+/*
113351
 
+ * RFC compliance
113352
 
+ */
113353
 
+
113354
 
+# Test acceptance of leading zeroes
113355
 
+test "RFC - leading zeroes" {
113356
 
+       if not string :matches "frop:frup:frop" "*:*:*" {
113357
 
+               test_fail "failed to match";
113358
 
+       }
113359
 
+
113360
 
+       if not string :is "${0000002}" "frup" {
113361
 
+               test_fail "incorrect match value (0000002): ${0000002}";
113362
 
+       }
113363
 
+}
113364
 
+
113365
 
+# Test non-greedyness
113366
 
+test "RFC - not greedy" {
113367
 
+       if not string :matches "frop.......frop.........frop...." "?*frop*" {
113368
 
+               test_fail "failed to match";
113369
 
+       }
113370
 
+
113371
 
+       if not string :is "${1}${2}${3}" "frop................frop...." {
113372
 
+               test_fail "incorrect match values: ${1}${2}${3}";
113373
 
+       }
113374
 
+}
113375
 
+
113376
 
+# Index out of range
113377
 
+test "RFC - index out of range" {
113378
 
+       if not string :matches "test" "*" {
113379
 
+               test_fail "failed to match (impossible)";
113380
 
+       }
113381
 
+
113382
 
+       if not string :is "${2}" "" {
113383
 
+               test_fail "incorrect match value: '${2}'";
113384
 
+       }
113385
 
+}
113386
 
+
113387
 
+# Index 0
113388
 
+test "RFC - index 0" {
113389
 
+       if not string :matches "a b c d e f g" "? ? ? ? ? ? ?" {
113390
 
+               test_fail "failed to match";
113391
 
+       }
113392
 
+
113393
 
+       if not string :is "${0}" "a b c d e f g" {
113394
 
+        test_fail "incorrect match value: ${0}";
113395
 
+    }
113396
 
+}
113397
 
+
113398
 
+# Test short-circuit
113399
 
+test "RFC - test short-circuit" {
113400
 
+       if not anyof (
113401
 
+               string :matches "a b c d e f g" "? ?",
113402
 
+               string :matches "puk pok puk pok" "pu*ok",
113403
 
+               string :matches "snot kip snot" "snot*snot"
113404
 
+       ) {
113405
 
+               test_fail "failed to match any";
113406
 
+       }
113407
 
+
113408
 
+       if string :is "${1}" " kip " {
113409
 
+               test_fail "did not short-circuit test execution or intented test failed.";
113410
 
+       }
113411
 
+
113412
 
+       if not string :is "${1}" "k pok puk p" {
113413
 
+               test_fail "incorrect match value: ${1}";
113414
 
+       }
113415
 
+}
113416
 
+
113417
 
+# Test overwriting only on match 
113418
 
+test "RFC - values overwrite" {
113419
 
+       set "sentence1" "the cat jumps off the table";
113420
 
+       set "sentence2" "the dog barks at the cat in the alley";
113421
 
+
113422
 
+       if not string :matches "${sentence1}" "the * jumps off the *" {
113423
 
+               test_fail "failed to match first sentence";
113424
 
+       } 
113425
 
+       
113426
 
+       if not string :is "${1}:${2}" "cat:table" {
113427
 
+               test_fail "invalid match values";
113428
 
+       }
113429
 
+
113430
 
+       if string :matches "${sentence2}" "the * barks at the * in the store" {
113431
 
+               test_fail "should not have matched second sentence";
113432
 
+       }
113433
 
+
113434
 
+       if not string :is "${1}:${2}" "cat:table" {
113435
 
+               test_fail "should have preserved match values";
113436
 
+       }
113437
 
+
113438
 
+       if not string :matches "${sentence2}" "the * barks at the * in the alley" {
113439
 
+               test_fail "failed to match the second sentence (second time)";
113440
 
+       }
113441
 
+
113442
 
+       if not string :is "${1}:${2}" "dog:cat" {
113443
 
+               test_fail "should have overwritten match values";
113444
 
+       }
113445
 
+}
113446
 
+
113447
 
+test "RFC - example" {
113448
 
+       test_set "message" text:
113449
 
+Subject: [acme-users] [fwd] version 1.0 is out
113450
 
+List-Id: Dovecot Mailing List <dovecot@dovecot.org>     
113451
 
+To: coyote@ACME.Example.COM
113452
 
+Fom: stephan@rename-it.nl
113453
 
+
113454
 
+Test message.
113455
 
+.
113456
 
+;
113457
 
+       if header :matches "List-ID" "*<*@*" {  
113458
 
+               if not string "INBOX.lists.${2}" "INBOX.lists.dovecot" {
113459
 
+                       test_fail "incorrect match value: INBOX.lists.${2}";
113460
 
+               }
113461
 
+       } else {
113462
 
+               test_fail "failed to match list header";
113463
 
+       }
113464
 
+
113465
 
+       # Imagine the header
113466
 
+       # Subject: [acme-users] [fwd] version 1.0 is out
113467
 
+       if header :matches "Subject" "[*] *" {
113468
 
+               # ${1} will hold "acme-users",
113469
 
+               # ${2} will hold "[fwd] version 1.0 is out"
113470
 
+
113471
 
+               if anyof (
113472
 
+                       not string "${1}" "acme-users",
113473
 
+                       not string "${2}" "[fwd] version 1.0 is out"
113474
 
+               ) {
113475
 
+                       test_fail "invalid match values: ${1} ${2}";
113476
 
+               }
113477
 
+       } else {
113478
 
+               test_fail "failed to match subject";
113479
 
+       }
113480
 
+
113481
 
+       # Imagine the header
113482
 
+       # To: coyote@ACME.Example.COM
113483
 
+       if address :matches ["To", "Cc"] ["coyote@**.com", 
113484
 
+               "wile@**.com"] {
113485
 
+               # ${0} is the matching address
113486
 
+               # ${1} is always the empty string
113487
 
+               # ${2} is part of the domain name ("ACME.Example")
113488
 
+
113489
 
+               if anyof (
113490
 
+                       not string "${0}" "coyote@ACME.Example.COM",
113491
 
+                       not string "${1}" "",
113492
 
+                       not string "${2}" "ACME.Example"
113493
 
+               ) {
113494
 
+                       test_fail "invalid match values: ${0}, ${1}, ${2}";
113495
 
+               }      
113496
 
+       } else {
113497
 
+               # Control wouldn't reach this block if any match was
113498
 
+               # successful, so no match variables are set at this
113499
 
+               # point.
113500
 
+
113501
 
+               test_fail "failed to match to address";
113502
 
+       }
113503
 
+
113504
 
+       if anyof (true, address :domain :matches "To" "*.com") {
113505
 
+               # The second test is never evaluated, so there are
113506
 
+               # still no match variables set.
113507
 
+               
113508
 
+               /* FIXME: not compliant */
113509
 
+       }
113510
 
+}
113511
 
+
113512
 
+/*
113513
 
+ * Generic tests
113514
 
+ */
113515
 
+
113516
 
+set "match1" "Test of general stupidity";
113517
 
+
113518
 
+test "Begin" {
113519
 
+       if not string :matches "${match1}" "Test of *" {
113520
 
+               test_fail "should have matched";
113521
 
+       } 
113522
 
+
113523
 
+       if not string :is "${1}" "general stupidity" {
113524
 
+               test_fail "match value incorrect";
113525
 
+       }
113526
 
+}
113527
 
+
113528
 
+test "Begin no match" {
113529
 
+       if string :matches "${match1}" "of *" {
113530
 
+               test_fail "should not have matched";
113531
 
+       }
113532
 
+}
113533
 
+
113534
 
+set "match2" "toptoptop";
113535
 
+
113536
 
+test "End" {
113537
 
+       if not string :matches "${match2}" "*top" {
113538
 
+               test_fail "should have matched";
113539
 
+       }
113540
 
+
113541
 
+       if not string :is "${1}" "toptop" {
113542
 
+               test_fail "match value incorrect";
113543
 
+       }
113544
 
+}
113545
 
+
113546
 
+set "match3" "ik ben een tukker met grote oren en een lelijke broek.";
113547
 
+
113548
 
+test "Multiple" {
113549
 
+       if not string :matches "${match3}" "ik ben * met * en *." {
113550
 
+               test_fail "should have matched";
113551
 
+       } 
113552
 
+
113553
 
+       set "line" "Hij is ${1} met ${2} en ${3}!";
113554
 
+
113555
 
+       if not string :is "${line}"
113556
 
+               "Hij is een tukker met grote oren en een lelijke broek!" {
113557
 
+               test_fail "match values incorrect: ${line}";
113558
 
+       }
113559
 
+}
113560
 
+
113561
 
+set "match4" "beter van niet?";
113562
 
+
113563
 
+test "Escape" {
113564
 
+       if not string :matches "${match4}" "*\\?" {
113565
 
+               test_fail "should have matched";
113566
 
+       } 
113567
 
+
113568
 
+       if not string :is "${1}" "beter van niet" {
113569
 
+               test_fail "match value incorrect: ${1}";
113570
 
+       }
113571
 
+}
113572
 
+
113573
 
+set "match5" "The quick brown fox jumps over the lazy dog.";
113574
 
+
113575
 
+test "Alphabet ?" {
113576
 
+       if not string :matches "${match5}" "T?? ????? ????? ?o? ?u??? o?er ?he ???? ?o?." {
113577
 
+               test_fail "should have matched";
113578
 
+       } 
113579
 
+
113580
 
+       set "alphabet" "${22}${8}${6}${25}${2}${13}${26}${1}${5}${15}${7}${21}${16}${12}${10}${17}${3}${9}${18}${20}${4}${19}${11}${14}${24}${23}";
113581
 
+
113582
 
+       if not string :is "${alphabet}" "abcdefghijklmnopqrstuvwxyz" {
113583
 
+               test_fail "match values incorrect: ${alphabet}";
113584
 
+       }
113585
 
+
113586
 
+       if string :matches "${match5}" "T?? ????? ?w??? ?o? ?u??? o?er ?he ???? ?o?." {
113587
 
+               test_fail "should not have matched";
113588
 
+       }
113589
 
+}
113590
 
+
113591
 
+set "match6" "zero:one:zero|three;one;zero/five";
113592
 
+
113593
 
+test "Words sep ?" {
113594
 
+
113595
 
+       if not string :matches "${match6}" "*one?zero?five" {
113596
 
+               test_fail "should have matched";
113597
 
+       }
113598
 
+
113599
 
+       if not string :is "${1}${2}${3}" "zero:one:zero|three;;/" {
113600
 
+               test_fail "incorrect match values: ${1} ${2} ${3}";
113601
 
+       }
113602
 
+}
113603
 
+
113604
 
+set "match7" "frop";
113605
 
+
113606
 
+test "Letters begin ?" {
113607
 
+       if not string :matches "${match7}" "??op" {
113608
 
+               test_fail "should have matched";
113609
 
+       }
113610
 
+               
113611
 
+       set "val" "${0}:${1}:${2}:${3}:";
113612
 
+       
113613
 
+       if not string :is "${val}" "frop:f:r::" {
113614
 
+               test_fail "incorrect match values: ${val}";
113615
 
+       }
113616
 
+}
113617
 
+
113618
 
+test "Letters end ?" {
113619
 
+    if not string :matches "${match7}" "fr??" {
113620
 
+        test_fail "should have matched";
113621
 
+    }
113622
 
+
113623
 
+    set "val" "${0}:${1}:${2}:${3}:";
113624
 
+
113625
 
+    if not string :is "${val}" "frop:o:p::" {
113626
 
+        test_fail "incorrect match values: ${val}";
113627
 
+    }
113628
 
+}
113629
 
+
113630
 
+set "match8" "klopfropstroptop";
113631
 
+
113632
 
+test "Letters words *? - 1" {
113633
 
+       if not string :matches "${match8}" "*fr??*top" {
113634
 
+               test_fail "should have matched";
113635
 
+       }
113636
 
+
113637
 
+       set "val" ":${0}:${1}:${2}:${3}:${4}:${5}:";
113638
 
+       
113639
 
+       if not string :is "${val}" ":klopfropstroptop:klop:o:p:strop::" {
113640
 
+               test_fail "incorrect match values: ${val}";
113641
 
+       }
113642
 
+}
113643
 
+
113644
 
+test "Letters words *? - 2" {
113645
 
+       if not string :matches "${match8}" "?*fr??*top" {
113646
 
+               test_fail "should have matched";
113647
 
+       }
113648
 
+       
113649
 
+       set "val" ":${0}:${1}:${2}:${3}:${4}:${5}:${6}:";
113650
 
+
113651
 
+       if not string :is "${val}" ":klopfropstroptop:k:lop:o:p:strop::" {
113652
 
+               test_fail "incorrect match values: ${val}";
113653
 
+       }
113654
 
+}
113655
 
+
113656
 
+test "Letters words *? backtrack" {
113657
 
+       if not string :matches "${match8}" "*?op" {
113658
 
+               test_fail "should have matched";
113659
 
+       }
113660
 
+
113661
 
+       set "val" ":${0}:${1}:${2}:${3}:${4}:";
113662
 
+       
113663
 
+       if not string :is "${val}" ":klopfropstroptop:klopfropstrop:t:::" {
113664
 
+               test_fail "incorrect match values: ${val}";
113665
 
+       }
113666
 
+}
113667
 
+
113668
 
+test "Letters words *? first" {
113669
 
+       if not string :matches "${match8}" "*?op*" {
113670
 
+               test_fail "failed to match";
113671
 
+       }
113672
 
+
113673
 
+       set "val" ":${0}:${1}:${2}:${3}:${4}:";
113674
 
+
113675
 
+       if not string :is "${val}" ":klopfropstroptop:k:l:fropstroptop::" {
113676
 
+               test_fail "incorrect match values: ${val}";
113677
 
+       }
113678
 
+}
113679
 
+
113680
 
+/*
113681
 
+ * Specific tests
113682
 
+ */
113683
 
+
113684
 
+test_set "message" text:
113685
 
+Return-path: <stephan@xi.rename-it.nl>
113686
 
+Envelope-to: stephan@xi.rename-it.nl
113687
 
+Delivery-date: Sun, 01 Feb 2009 11:29:57 +0100
113688
 
+Received: from stephan by xi.rename-it.nl with local (Exim 4.69)
113689
 
+       (envelope-from <stephan@xi.rename-it.nl>)
113690
 
+       id 1LTZaP-0007h3-2e
113691
 
+       for stephan@xi.rename-it.nl; Sun, 01 Feb 2009 11:29:57 +0100
113692
 
+From: Dovecot Debian Builder <stephan.rename-it.nl@xi.rename-it.nl>
113693
 
+To: stephan@xi.rename-it.nl
113694
 
+Subject: Log for failed build of dovecot_2:1.2.alpha5-0~auto+159 (dist=hardy)
113695
 
+Message-Id: <E1LTZaP-0007h3-2e@xi.rename-it.nl>
113696
 
+Date: Sun, 01 Feb 2009 11:29:57 +0100
113697
 
+
113698
 
+Automatic build of dovecot_1.2.alpha5-0~auto+159 on xi by sbuild/i386 0.57.7
113699
 
+.
113700
 
+;
113701
 
+
113702
 
+test "Match combined" {
113703
 
+       if not header :matches "subject" "Log for ?* build of *" {
113704
 
+               test_fail "failed to match";
113705
 
+       }
113706
 
+
113707
 
+       if not string "${1}${2}" "failed" {
113708
 
+               test_fail "incorrect match values: ${1}${2}";
113709
 
+       }
113710
 
+}
113711
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/variables/modifiers.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/variables/modifiers.svtest
113712
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/variables/modifiers.svtest  1970-01-01 01:00:00.000000000 +0100
113713
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/variables/modifiers.svtest   2008-08-01 19:59:33.000000000 +0200
113714
 
@@ -0,0 +1,140 @@
113715
 
+require "vnd.dovecot.testsuite";
113716
 
+require "variables";
113717
 
+
113718
 
+/*
113719
 
+ * Modifiers
113720
 
+ */
113721
 
+
113722
 
+test "Modifier :lower" {
113723
 
+       set :lower "test" "VaLuE";
113724
 
+
113725
 
+       if not string :is "${test}" "value" {
113726
 
+               test_fail "modified variable assignment failed";
113727
 
+       }
113728
 
+}
113729
 
+
113730
 
+test "Modifiers :lower :upperfirst" {
113731
 
+       set :lower :upperfirst "test" "vAlUe";
113732
 
+
113733
 
+       if string :is "${test}" "value" {
113734
 
+               test_fail "modifiers applied with wrong precedence";
113735
 
+       }
113736
 
+
113737
 
+       if not string :is "${test}" "Value" {
113738
 
+               test_fail "modified variable assignment failed";
113739
 
+       }
113740
 
+}
113741
 
+
113742
 
+test "Modifiers :upperfirst :lower" {
113743
 
+       set :upperfirst :lower "test" "vAlUe";
113744
 
+
113745
 
+       if string :is "${test}" "value" {
113746
 
+               test_fail "modifiers applied with wrong precedence";
113747
 
+       }
113748
 
+
113749
 
+       if not string :is "${test}" "Value" {
113750
 
+               test_fail "modified variable assignment failed";
113751
 
+       }
113752
 
+}
113753
 
+
113754
 
+test "Modifier :upper" {
113755
 
+       set :upper "test" "vAlUe";
113756
 
+
113757
 
+       if not string :is "${test}" "VALUE" {
113758
 
+               test_fail "modified variable assignment failed";
113759
 
+       }
113760
 
+}
113761
 
+
113762
 
+test "Modifiers :upper :lowerfirst" {
113763
 
+       set :upper :lowerfirst "test" "VaLuE";
113764
 
+
113765
 
+       if string :is "${test}" "VALUE" {
113766
 
+               test_fail "modifiers applied with wrong precedence";
113767
 
+       }
113768
 
+
113769
 
+       if not string :is "${test}" "vALUE" {
113770
 
+               test_fail "modified variable assignment failed";
113771
 
+       }
113772
 
+}
113773
 
+
113774
 
+test "Modifiers :lowerfirst :upper" {
113775
 
+       set :lowerfirst :upper "test" "VaLuE";
113776
 
+
113777
 
+       if string :is "${test}" "VALUE" {
113778
 
+               test_fail "modifiers applied with wrong precedence";
113779
 
+       }
113780
 
+
113781
 
+       if not string :is "${test}" "vALUE" {
113782
 
+               test_fail "modified variable assignment failed";
113783
 
+       }
113784
 
+}
113785
 
+
113786
 
+test "Modifier :length" {
113787
 
+       set :length "test" "VaLuE";
113788
 
+
113789
 
+       if not string :is "${test}" "5" {
113790
 
+               test_fail "modified variable assignment failed";
113791
 
+       }
113792
 
+}
113793
 
+
113794
 
+test "Modifier :length (elaborate)" {
113795
 
+       set "a" "abcdefghijklmnopqrstuvwxyz";
113796
 
+       set "b" "1234567890";
113797
 
+       set :length "test" " ${a}:${b}  ";
113798
 
+
113799
 
+       if not string :is "${test}" "40" {
113800
 
+               test_fail "modified variable assignment failed";
113801
 
+       }
113802
 
+}
113803
 
+
113804
 
+test "Modifier :quotewildcard" {
113805
 
+       set :quotewildcard "test" "^^***??**^^";
113806
 
+
113807
 
+       if not string :is "${test}" "^^\\*\\*\\*\\?\\?\\*\\*^^" {
113808
 
+               test_fail "modified variable assignment failed";
113809
 
+       }
113810
 
+}
113811
 
+
113812
 
+test "Modifier :length :quotewildcard" {
113813
 
+       set :length :quotewildcard "test" "^^***??**^^";
113814
 
+
113815
 
+       if string :is "${test}" "11" {
113816
 
+               test_fail "modifiers applied with wrong precedence";
113817
 
+       }
113818
 
+
113819
 
+       if not string :is "${test}" "18" {
113820
 
+               test_fail "modified variable assignment failed";
113821
 
+       }
113822
 
+}
113823
 
+
113824
 
+test "RFC examples" {
113825
 
+       set "a" "juMBlEd lETteRS";             # => "juMBlEd lETteRS"
113826
 
+       if not string "${a}" "juMBlEd lETteRS" {
113827
 
+               test_fail "modified assignment failed (1): ${a}";
113828
 
+       }
113829
 
+       
113830
 
+       set :length "b" "${a}";                # => "15"
113831
 
+       if not string "${b}" "15" {
113832
 
+               test_fail "modified assignment failed (2): ${a}";
113833
 
+       }
113834
 
+       
113835
 
+       set :lower "b" "${a}";                 #  => "jumbled letters"
113836
 
+       if not string "${b}" "jumbled letters" {
113837
 
+               test_fail "modified assignment failed (3): ${a}";
113838
 
+       }
113839
 
+       
113840
 
+    set :upperfirst "b" "${a}";            # => "JuMBlEd lETteRS"
113841
 
+       if not string "${b}" "JuMBlEd lETteRS" {
113842
 
+               test_fail "modified assignment failed (4): ${a}";
113843
 
+       }
113844
 
+       
113845
 
+       set :upperfirst :lower "b" "${a}";     # => "Jumbled letters"
113846
 
+       if not string "${b}" "Jumbled letters" {
113847
 
+               test_fail "modified assignment failed (5): ${a}";
113848
 
+       }
113849
 
+       
113850
 
+       set :quotewildcard "b" "Rock*";        # => "Rock\*"
113851
 
+       if not string "${b}" "Rock\\*" {
113852
 
+               test_fail "modified assignment failed (6): ${a}";
113853
 
+       }       
113854
 
+}
113855
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/variables/quoting.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/variables/quoting.svtest
113856
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/variables/quoting.svtest    1970-01-01 01:00:00.000000000 +0100
113857
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/variables/quoting.svtest     2008-08-01 16:55:54.000000000 +0200
113858
 
@@ -0,0 +1,36 @@
113859
 
+require "vnd.dovecot.testsuite";
113860
 
+
113861
 
+require "variables";
113862
 
+require "encoded-character";
113863
 
+
113864
 
+test "Encodings - RFC examples" {
113865
 
+       set "s" "$";
113866
 
+       set "foo" "bar";
113867
 
+
113868
 
+       # "${fo\o}"  => ${foo}  => the expansion of variable foo.
113869
 
+       if not string :is "${fo\o}" "bar" {
113870
 
+               test_fail "failed 'the expansion of variable foo (${s}{fo\\o})'";
113871
 
+       }
113872
 
+
113873
 
+       # "${fo\\o}" => ${fo\o} => illegal identifier => left verbatim.      
113874
 
+       if not string :is "${fo\\o}" "${s}{fo\\o}" {
113875
 
+               test_fail "failed 'illegal identifier => left verbatim'";
113876
 
+       }
113877
 
+
113878
 
+       # "\${foo}"  => ${foo}  => the expansion of variable foo.
113879
 
+       if not string "\${foo}" "bar" {
113880
 
+               test_fail "failed 'the expansion of variable foo (\\${s}{foo})'";
113881
 
+       }
113882
 
+
113883
 
+       # "\\${foo}" => \${foo} => a backslash character followed by the
113884
 
+       #                          expansion of variable foo.
113885
 
+       if not string "\\${foo}" "\\bar" {
113886
 
+               test_fail "failed 'a backslash character followed by expansion of variable foo";
113887
 
+       }
113888
 
+
113889
 
+       set "name" "Ethelbert";
113890
 
+       if not string "dear${hex:20 24 7b 4e}ame}" "dear Ethelbert" {
113891
 
+               test_fail "failed 'dear Ethelbert' example";
113892
 
+    }
113893
 
+}
113894
 
+
113895
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/variables/regex.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/variables/regex.svtest
113896
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/variables/regex.svtest      1970-01-01 01:00:00.000000000 +0100
113897
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/variables/regex.svtest       2008-08-25 10:25:08.000000000 +0200
113898
 
@@ -0,0 +1,35 @@
113899
 
+require "vnd.dovecot.testsuite";
113900
 
+
113901
 
+require "regex";
113902
 
+require "variables";
113903
 
+
113904
 
+# Test overwriting only on match 
113905
 
+test "RFC - values overwrite" {
113906
 
+       set "sentence1" "the cat jumps off the table";
113907
 
+       set "sentence2" "the dog barks at the cat in the alley";
113908
 
+
113909
 
+       if not string :regex "${sentence1}" "the (.*) jumps off the (.*)" {
113910
 
+               test_fail "failed to match first sentence";
113911
 
+       } 
113912
 
+       
113913
 
+       if not string :is "${1}:${2}" "cat:table" {
113914
 
+               test_fail "invalid match values";
113915
 
+       }
113916
 
+
113917
 
+       if string :regex "${sentence2}" "the (.*) barks at the (.*) in the store" {
113918
 
+               test_fail "should not have matched second sentence";
113919
 
+       }
113920
 
+
113921
 
+       if not string :is "${1}:${2}" "cat:table" {
113922
 
+               test_fail "should have preserved match values";
113923
 
+       }
113924
 
+
113925
 
+       if not string :regex "${sentence2}" "the (.*) barks at the (.*) in the alley" {
113926
 
+               test_fail "failed to match the second sentence (second time)";
113927
 
+       }
113928
 
+
113929
 
+       if not string :is "${1}:${2}" "dog:cat" {
113930
 
+               test_fail "should have overwritten match values";
113931
 
+       }
113932
 
+}
113933
 
+
113934
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/extensions/variables/string.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/variables/string.svtest
113935
 
--- dovecot-1.2.4/dovecot-libsieve/tests/extensions/variables/string.svtest     1970-01-01 01:00:00.000000000 +0100
113936
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/extensions/variables/string.svtest      2008-08-04 10:39:20.000000000 +0200
113937
 
@@ -0,0 +1,37 @@
113938
 
+require "vnd.dovecot.testsuite";
113939
 
+
113940
 
+require "relational";
113941
 
+require "comparator-i;ascii-numeric";
113942
 
+
113943
 
+require "variables";
113944
 
+
113945
 
+test "String - :count" {
113946
 
+       if not string :count "eq" :comparator "i;ascii-numeric" ["a", "b", "c"] "3" {
113947
 
+               test_fail "string test failed :count match";
113948
 
+       }
113949
 
+}
113950
 
+
113951
 
+test "String - :count \"\"" {
113952
 
+       if not string :count "eq" :comparator "i;ascii-numeric" ["a", "", "c"] "2" {
113953
 
+               test_fail "string test failed :count match";
113954
 
+       }
113955
 
+}
113956
 
+
113957
 
+test "RFC example" {
113958
 
+       set "state" "${state} pending";
113959
 
+
113960
 
+       if not string :matches " ${state} " "* pending *" {
113961
 
+       # the above test always succeeds
113962
 
+               
113963
 
+               test_fail "test should have matched: \" ${state} \"";
113964
 
+       }
113965
 
+}
113966
 
+
113967
 
+test "No whitespace stripping" {
113968
 
+       set "vara" "      value       ";
113969
 
+       set "varb" "value";
113970
 
+
113971
 
+       if not string :is :comparator "i;octet" "${vara}" "      ${varb}       " {
113972
 
+               test_fail "string test seems to have stripped white space";
113973
 
+       }
113974
 
+}
113975
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/header.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/header.svtest
113976
 
--- dovecot-1.2.4/dovecot-libsieve/tests/header.svtest  1970-01-01 01:00:00.000000000 +0100
113977
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/header.svtest   2008-11-19 20:58:39.000000000 +0100
113978
 
@@ -0,0 +1,57 @@
113979
 
+require "vnd.dovecot.testsuite";
113980
 
+
113981
 
+test_set "message" text:
113982
 
+From: stephan@rename-it.nl
113983
 
+To: nico@vestingbar.nl
113984
 
+Subject:         Help        
113985
 
+X-A:     Text
113986
 
+X-B: Text            
113987
 
+X-Multiline: This is a multi-line
113988
 
+ header body, which should be
113989
 
+ unfolded correctly.
113990
 
+
113991
 
+Text
113992
 
+
113993
 
+.
113994
 
+;
113995
 
+
113996
 
+test "Strip center" {
113997
 
+       if not header :is "subject" "Help" {
113998
 
+               test_fail "header test does not strip leading or trailing whitespace";
113999
 
+       }
114000
 
+}
114001
 
+
114002
 
+test "Strip lead" {
114003
 
+    if not header :is "x-a" "Text" {
114004
 
+        test_fail "header test does not strip leading whitespace";
114005
 
+    }
114006
 
+}
114007
 
+
114008
 
+test "Strip trail" {
114009
 
+    if not header :is "x-b" "Text" {
114010
 
+        test_fail "header test does not strip trailing whitespace";
114011
 
+    }
114012
 
+}
114013
 
+
114014
 
+test "Contains empty - exist" {
114015
 
+       if not header :contains "subject" "" {
114016
 
+               test_fail "header test :contains match type fails to match \"\" on existing header";
114017
 
+       }
114018
 
+
114019
 
+       if header :contains "subject" "a" {
114020
 
+               test_fail "header test :contains match type matches nonsense";
114021
 
+       }
114022
 
+}
114023
 
+
114024
 
+test "Contains empty - not exist" {
114025
 
+       if header :contains "x-nonsense" "" {
114026
 
+               test_fail "header test :contains match type matches \"\" on non-existant header";
114027
 
+       }
114028
 
+}
114029
 
+
114030
 
+test "Folded - equals" {
114031
 
+       if not header :is "x-multiline" 
114032
 
+               "This is a multi-line header body, which should be unfolded correctly." {
114033
 
+               test_fail "failed to properly unfold folded header.";
114034
 
+       }
114035
 
+}
114036
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/lexer.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/lexer.svtest
114037
 
--- dovecot-1.2.4/dovecot-libsieve/tests/lexer.svtest   1970-01-01 01:00:00.000000000 +0100
114038
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/lexer.svtest    2008-07-30 15:17:37.000000000 +0200
114039
 
@@ -0,0 +1,39 @@
114040
 
+require "vnd.dovecot.testsuite";
114041
 
+require "variables";
114042
 
+
114043
 
+/* Test conformance to RFC 5228 - 2.4.2. Strings */
114044
 
+
114045
 
+set "text" text: # Comment
114046
 
+Line 1
114047
 
+.Line 2
114048
 
+..Line 3
114049
 
+.Line 4
114050
 
+Line 5
114051
 
+.
114052
 
+;
114053
 
+
114054
 
+set "quoted"
114055
 
+"Line 1
114056
 
+.Line 2
114057
 
+.Line 3
114058
 
+.Line 4
114059
 
+Line 5
114060
 
+";
114061
 
+
114062
 
+test "String Literal" {
114063
 
+       if not string :is "${text}" "${quoted}" {
114064
 
+               test_fail "lexer messed-up dot stuffing";
114065
 
+       }
114066
 
+
114067
 
+       if string :is "${text}" "" {
114068
 
+               test_fail "variable substitution failed";
114069
 
+       }
114070
 
+}
114071
 
+
114072
 
+test "Unknown Escapes" {
114073
 
+       if not string :is "\a\a\a\a\a" "aaaaa" {
114074
 
+               test_fail "unknown quoted string escape sequences are handled inappropriately";
114075
 
+       }
114076
 
+}
114077
 
+
114078
 
+
114079
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/match-types/contains.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/match-types/contains.svtest
114080
 
--- dovecot-1.2.4/dovecot-libsieve/tests/match-types/contains.svtest    1970-01-01 01:00:00.000000000 +0100
114081
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/match-types/contains.svtest     2008-08-01 20:51:44.000000000 +0200
114082
 
@@ -0,0 +1,81 @@
114083
 
+require "vnd.dovecot.testsuite";
114084
 
+
114085
 
+test_set "message" text:
114086
 
+From: stephan@rename-it.nl
114087
 
+Cc: frop@example.com
114088
 
+To: test@dovecot.org
114089
 
+X-Bullshit: f fr fro frop frob frobn frobnitzn
114090
 
+Subject: Test Message
114091
 
+Comment:                                 
114092
 
+
114093
 
+Test!
114094
 
+.
114095
 
+;
114096
 
+
114097
 
+# Match tests
114098
 
+
114099
 
+test "Match empty" {
114100
 
+       if not header :contains "x-bullshit" "" {
114101
 
+               test_fail "contains tests fails to match \"\" against non-empty string";
114102
 
+       }
114103
 
+
114104
 
+       if not header :contains "comment" "" {
114105
 
+        test_fail "contains tests fails to match \"\" against empty string";
114106
 
+    }
114107
 
+}
114108
 
+
114109
 
+test "Match full" {
114110
 
+       if not address :contains "from" "stephan@rename-it.nl" {
114111
 
+               test_fail "should have matched";
114112
 
+       }
114113
 
+}
114114
 
+
114115
 
+test "Match begin" {
114116
 
+       if not address :contains "from" "stephan" {
114117
 
+               test_fail "should have matched";
114118
 
+       }
114119
 
+}
114120
 
+
114121
 
+test "Match end" {
114122
 
+       if not address :contains "from" "rename-it.nl" {
114123
 
+               test_fail "should have matched";
114124
 
+       }
114125
 
+}
114126
 
+
114127
 
+test "Match middle" {
114128
 
+       if not address :contains "from" "@" {
114129
 
+               test_fail "should have matched";
114130
 
+       }
114131
 
+}
114132
 
+
114133
 
+test "Match similar beginnings" {
114134
 
+       if not header :contains "x-bullshit" "frobnitzn" {
114135
 
+               test_fail "should have matched";
114136
 
+       }
114137
 
+}
114138
 
+
114139
 
+test "Match case-insensitive" {
114140
 
+       if not address :contains :comparator "i;ascii-casemap" "from" "RENAME-IT" {
114141
 
+               test_fail "match fails to apply correct comparator";    
114142
 
+       }
114143
 
+
114144
 
+       if not address :contains "from" "RENAME-IT" {
114145
 
+        test_fail "default comparator is wrong";
114146
 
+    }
114147
 
+}
114148
 
+
114149
 
+# Non-match tests
114150
 
+
114151
 
+test "No match full (typo)" {
114152
 
+       if address :contains "to" "frob@example.com" {
114153
 
+               test_fail "should not have matched";
114154
 
+       }
114155
 
+}
114156
 
+
114157
 
+test "No match end (typo)" {
114158
 
+       if header :contains "x-bullshit" "frobnitzm" {
114159
 
+               test_fail "should not have matched";
114160
 
+       }
114161
 
+}
114162
 
+
114163
 
+
114164
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/match-types/is.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/match-types/is.svtest
114165
 
--- dovecot-1.2.4/dovecot-libsieve/tests/match-types/is.svtest  1970-01-01 01:00:00.000000000 +0100
114166
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/match-types/is.svtest   2008-08-01 20:49:51.000000000 +0200
114167
 
@@ -0,0 +1,22 @@
114168
 
+require "vnd.dovecot.testsuite";
114169
 
+
114170
 
+test_set "message" text:
114171
 
+From: Stephan Bosch <stephan@rename-it.nl>
114172
 
+To: nico@vestingbar.nl
114173
 
+Subject: Test message
114174
 
+Comment:                                     
114175
 
+
114176
 
+Test!
114177
 
+
114178
 
+.
114179
 
+;
114180
 
+
114181
 
+test "Empty key" {
114182
 
+       if header :is "from" "" {
114183
 
+               test_fail "erroneously matched empty key against non-empty string"; 
114184
 
+       }
114185
 
+
114186
 
+       if not header :is "comment" "" {
114187
 
+               test_fail "failed to match empty string";
114188
 
+       }
114189
 
+}
114190
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/match-types/matches.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/match-types/matches.svtest
114191
 
--- dovecot-1.2.4/dovecot-libsieve/tests/match-types/matches.svtest     1970-01-01 01:00:00.000000000 +0100
114192
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/match-types/matches.svtest      2009-02-02 10:17:30.000000000 +0100
114193
 
@@ -0,0 +1,214 @@
114194
 
+require "vnd.dovecot.testsuite";
114195
 
+
114196
 
+test_set "message" text:
114197
 
+From: stephan+sieve@drunksnipers.com
114198
 
+To: sirius@rename-it.nl
114199
 
+To: nico@vestingbar.nl
114200
 
+Cc: me@example.com
114201
 
+Cc: timo@dovecot.com
114202
 
+X-Hufter: TRUE
114203
 
+Subject: make your money very fast!!!
114204
 
+X-Spam-Score: **********
114205
 
+X-Bullshit: 33333???a
114206
 
+Message-ID: <90a02fe01fc25e131d0e9c4c45975894@example.com>
114207
 
+Comment:                                            
114208
 
+X-Subject: Log for successful build of Dovecot.
114209
 
+
114210
 
+Het werkt!
114211
 
+.
114212
 
+;
114213
 
+
114214
 
+/*
114215
 
+ * General conformance testing
114216
 
+ */
114217
 
+
114218
 
+/*
114219
 
+test "Empty string" {
114220
 
+       if not header :matches "comment" "" {
114221
 
+               test_fail "failed to match \"\" against \"\"";
114222
 
+       }
114223
 
+
114224
 
+       if not header :matches "comment" "*" {
114225
 
+               test_fail "failed to match \"\" against \"*\"";
114226
 
+       }
114227
 
+
114228
 
+       if header :matches "comment" "?" {
114229
 
+               test_fail "inappropriately matched \"\" against \"?\"";
114230
 
+       }
114231
 
+}
114232
 
+
114233
 
+test "Multiple '*'" {
114234
 
+       if not address :matches "from" "*@d*ksn*ers.com" {
114235
 
+               test_fail "should have matched";
114236
 
+       }
114237
 
+
114238
 
+       if address :matches "from" "*@d*kn*ers.com" {
114239
 
+               test_fail "should not have matched";
114240
 
+       }
114241
 
+}
114242
 
+
114243
 
+test "End '*'" {
114244
 
+       if not address :matches "from" "stephan+sieve@drunksnipers.*" {
114245
 
+               test_fail "should have matched";
114246
 
+       }
114247
 
+
114248
 
+       if address :matches "from" "stepan+sieve@drunksnipers.*" {
114249
 
+               test_fail "should not have matched";
114250
 
+       }
114251
 
+}
114252
 
+
114253
 
+test "Begin '*'" {
114254
 
+       if not address :matches "from" "*+sieve@drunksnipers.com" {
114255
 
+               test_fail "should have matched";
114256
 
+       }
114257
 
+
114258
 
+       if address :matches "from" "*+sieve@drunksnipers.om" {
114259
 
+               test_fail "should not have matched";
114260
 
+       }
114261
 
+}
114262
 
+
114263
 
+test "Middle '?'" {
114264
 
+       if not address :matches "from" "stephan+sieve?drunksnipers.com" {
114265
 
+               test_fail "should have matched";
114266
 
+       }
114267
 
+
114268
 
+       if address :matches "from" "stephan+sieve?drunksipers.com" {
114269
 
+               test_fail "should not have matched";
114270
 
+       }
114271
 
+}
114272
 
+
114273
 
+test "Begin '?'" {
114274
 
+       if not address :matches "from" "?tephan+sieve@drunksnipers.com" {
114275
 
+               test_fail "should have matched";
114276
 
+       }
114277
 
+
114278
 
+       if address :matches "from" "?tephan+sievedrunksnipers.com" {
114279
 
+               test_fail "should not have matched";
114280
 
+       }
114281
 
+}
114282
 
+
114283
 
+test "End '?'" {
114284
 
+       if not address :matches "from" "stephan+sieve@drunksnipers.co?" {
114285
 
+               test_fail "should have matched";
114286
 
+       }
114287
 
+
114288
 
+       if address :matches "from" "sephan+sieve@drunksnipers.co?" {
114289
 
+               test_fail "should not have matched";
114290
 
+       }
114291
 
+}
114292
 
+
114293
 
+test "Multiple '?'" {
114294
 
+       if not address :matches "from" "?t?phan?sieve?drunksnip?rs.co?" {
114295
 
+               test_fail "should have matched";
114296
 
+       }
114297
 
+
114298
 
+       if address :matches "from" "?t?phan?sieve?dunksnip?rs.co?" {
114299
 
+               test_fail "should not have matched";
114300
 
+       }
114301
 
+}
114302
 
+
114303
 
+test "Escaped '?'" {
114304
 
+       if not header :matches "x-bullshit" "33333\\?\\?\\??" {
114305
 
+               test_fail "should have matched";
114306
 
+       }
114307
 
+
114308
 
+       if header :matches "x-bullshit" "33333\\?\\?\\?" {
114309
 
+               test_fail "should not have matched";
114310
 
+       }
114311
 
+}
114312
 
+
114313
 
+test "Escaped '?' following '*'" {
114314
 
+       if not header :matches "x-bullshit" "33333*\\?\\??" {
114315
 
+               test_fail "should have matched";
114316
 
+       }
114317
 
+
114318
 
+}
114319
 
+
114320
 
+test "Escaped '?' directly following initial '*'" {
114321
 
+       if not header :matches "X-Bullshit" "*\\?\\?\\?a" {
114322
 
+               test_fail "should have matched";
114323
 
+       }
114324
 
+}
114325
 
+
114326
 
+test "Escaped '?' following initial '*'" {
114327
 
+       if not header :matches "x-bullshit" "*3333\\?\\?\\?a" {
114328
 
+               test_fail "should have matched";
114329
 
+       }
114330
 
+}
114331
 
+
114332
 
+test "Escaped '*' with active '*' at the end" {
114333
 
+       if not header :matches "x-spam-score" "\\*\\*\\*\\*\\**" {
114334
 
+               test_fail "should have matched";
114335
 
+       }
114336
 
+}
114337
 
+
114338
 
+test "All escaped '*'" {
114339
 
+       if not header :matches "x-spam-score" "\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*" {
114340
 
+               test_fail "should have matched";
114341
 
+       }
114342
 
+
114343
 
+       if header :matches "x-spam-score" "\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*" {
114344
 
+               test_fail "should not have matched";
114345
 
+       }
114346
 
+}
114347
 
+
114348
 
+test "Middle not escaped '*'" {
114349
 
+       if not header :matches "x-spam-score" "\\*\\*\\***\\*\\*" {
114350
 
+               test_fail "should have matched";
114351
 
+       }
114352
 
+}
114353
 
+
114354
 
+test "Escaped '*' alternating with '?'" {
114355
 
+       if not header :matches "x-spam-score" "\\*?\\*?\\*?\\*?\\*?" {
114356
 
+               test_fail "should have matched";
114357
 
+       }
114358
 
+
114359
 
+       if header :matches "x-spam-score" "\\*?\\*?\\*?\\*?\\*??" {
114360
 
+               test_fail "should not have matched";
114361
 
+       }
114362
 
+}
114363
 
+
114364
 
+test "All escaped" {
114365
 
+       if header :matches "x-bullshit" "\\*3333\\?\\?\\?a" {
114366
 
+               test_fail "should not have matched";
114367
 
+       }
114368
 
+
114369
 
+
114370
 
+       if header :matches "x-bullshit" "33333\\?\\?\\?aa" {
114371
 
+               test_fail "should not have matched";
114372
 
+       }
114373
 
+
114374
 
+       if header :matches "x-bullshit" "\\f3333\\?\\?\\?a" {
114375
 
+               test_fail "should not have matched";
114376
 
+       }
114377
 
+}
114378
 
+
114379
 
+test "Put '*' directly before '?'" {
114380
 
+       if header :matches "x-subject" "Log for *??????????? build of *" {
114381
 
+               test_fail "should not have matched";
114382
 
+       }
114383
 
+
114384
 
+       if not header :matches "x-subject" "Log for *?????????? build of *" {
114385
 
+               test_fail "should have matched";
114386
 
+       }
114387
 
+
114388
 
+       if not header :matches "x-subject" "Log for *? build of *" {
114389
 
+               test_fail "should have matched";
114390
 
+       }
114391
 
+}*/
114392
 
+
114393
 
+test "Put '?' directly before '*'" {
114394
 
+       if header :matches "x-subject" "Log for ???????????* build of *" {
114395
 
+               test_fail "should not have matched";
114396
 
+       }
114397
 
+
114398
 
+       if not header :matches "x-subject" "Log for ??????????* build of *" {
114399
 
+               test_fail "should have matched";
114400
 
+       }
114401
 
+
114402
 
+       if not header :matches "x-subject" "Log for ?* build of *" {
114403
 
+               test_fail "should have matched";
114404
 
+       }
114405
 
+}
114406
 
+
114407
 
+
114408
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/multiscript/basic.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/multiscript/basic.svtest
114409
 
--- dovecot-1.2.4/dovecot-libsieve/tests/multiscript/basic.svtest       1970-01-01 01:00:00.000000000 +0100
114410
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/multiscript/basic.svtest        2009-01-06 00:15:52.000000000 +0100
114411
 
@@ -0,0 +1,91 @@
114412
 
+require "vnd.dovecot.testsuite";
114413
 
+
114414
 
+test_set "message" text:
114415
 
+From: stephan@rename-it.nl
114416
 
+Message-ID: <frop33333333333333333@frutsens.nl>
114417
 
+To: nico@vestingbar.nl
114418
 
+Subject: Frop.
114419
 
+
114420
 
+Friep.
114421
 
+.
114422
 
+;
114423
 
+
114424
 
+test "Append" {
114425
 
+       if not allof (
114426
 
+               test_script_compile "fileinto-inbox.sieve",
114427
 
+               test_script_run ){
114428
 
+               test_fail "failed to compile and run first script";
114429
 
+       }
114430
 
+
114431
 
+       if not allof ( 
114432
 
+               test_script_compile "vacation.sieve",
114433
 
+               test_script_run :append_result ) {
114434
 
+               test_fail "failed to compile and run second script";
114435
 
+       }
114436
 
+
114437
 
+       if not allof ( 
114438
 
+               test_script_compile "notify.sieve",
114439
 
+               test_script_run :append_result ) {
114440
 
+               test_fail "failed to compile and run third script";
114441
 
+       }
114442
 
+
114443
 
+       if not test_result :index 1 "store" {
114444
 
+               test_fail "first action is not 'store'";
114445
 
+       }
114446
 
+
114447
 
+       if not test_result :index 2 "vacation" {
114448
 
+               test_fail "second action is not 'vacation'";
114449
 
+       }
114450
 
+
114451
 
+       if not test_result :index 3 "notify" {
114452
 
+               test_fail "third action is not 'notify'";
114453
 
+       }
114454
 
+
114455
 
+       if not test_result_execute {
114456
 
+               test_fail "result execute failed";
114457
 
+       }
114458
 
+}
114459
 
+
114460
 
+test "Sequential Execute" {
114461
 
+       if not allof (
114462
 
+               test_script_compile "fileinto-inbox.sieve",
114463
 
+               test_script_run ) {
114464
 
+               test_fail "failed to compile and run first script";
114465
 
+       }
114466
 
+
114467
 
+       if not test_result_execute {
114468
 
+               test_fail "result execute failed after first script";
114469
 
+       }
114470
 
+
114471
 
+       if not allof (
114472
 
+               test_script_compile "vacation.sieve",
114473
 
+               test_script_run :append_result ) {
114474
 
+               test_fail "failed to compile and run second script";
114475
 
+       }
114476
 
+
114477
 
+       if not test_result_execute {
114478
 
+               test_fail "result execute failed after second script";
114479
 
+       }
114480
 
+
114481
 
+       if not allof (
114482
 
+               test_script_compile "notify.sieve",
114483
 
+               test_script_run :append_result ) {
114484
 
+               test_fail "failed to compile and run third script";
114485
 
+       }
114486
 
+
114487
 
+       if not test_result_execute {
114488
 
+               test_fail "result execute failed after third script";
114489
 
+       }
114490
 
+
114491
 
+       if not test_result :index 1 "store" {
114492
 
+               test_fail "first action is not 'store'";
114493
 
+       }
114494
 
+
114495
 
+       if not test_result :index 2 "vacation" {
114496
 
+               test_fail "second action is not 'vacation'";
114497
 
+       }
114498
 
+
114499
 
+       if not test_result :index 3 "notify" {
114500
 
+               test_fail "third action is not 'notify'";
114501
 
+       }
114502
 
+}
114503
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/multiscript/conflicts.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/multiscript/conflicts.svtest
114504
 
--- dovecot-1.2.4/dovecot-libsieve/tests/multiscript/conflicts.svtest   1970-01-01 01:00:00.000000000 +0100
114505
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/multiscript/conflicts.svtest    2009-01-06 00:15:52.000000000 +0100
114506
 
@@ -0,0 +1,94 @@
114507
 
+require "vnd.dovecot.testsuite";
114508
 
+
114509
 
+test_set "message" text:
114510
 
+From: stephan@rename-it.nl
114511
 
+Message-ID: <frop33333333333333333@frutsens.nl>
114512
 
+To: nico@vestingbar.nl
114513
 
+Subject: Frop.
114514
 
+
114515
 
+Friep.
114516
 
+.
114517
 
+;
114518
 
+
114519
 
+test "Graceful Conflicts" {
114520
 
+       if not allof (
114521
 
+               test_script_compile "fileinto-inbox.sieve",
114522
 
+               test_script_run ){
114523
 
+               test_fail "failed to compile and run first script";
114524
 
+       }
114525
 
+
114526
 
+       if not test_result_execute {
114527
 
+               test_fail "result execute failed after first script";
114528
 
+       }
114529
 
+
114530
 
+       if not allof ( 
114531
 
+               test_script_compile "reject-1.sieve",
114532
 
+               test_script_run :append_result ) {
114533
 
+               test_fail "failed to compile and run second script";
114534
 
+       }
114535
 
+
114536
 
+       if not test_result_execute {
114537
 
+               test_fail "result execute failed after second script";
114538
 
+       }
114539
 
+
114540
 
+       if not allof ( 
114541
 
+               test_script_compile "reject-2.sieve",
114542
 
+               test_script_run :append_result ) {
114543
 
+               test_fail "failed to compile and run third script";
114544
 
+       }
114545
 
+
114546
 
+       if not test_result_execute {
114547
 
+               test_fail "result execute failed after third script";
114548
 
+       }
114549
 
+
114550
 
+       if not test_result :index 1 "store" {
114551
 
+               test_fail "first action is not 'store'";
114552
 
+       }
114553
 
+
114554
 
+       if test_result :index 2 "reject" {
114555
 
+               test_fail "reject action not discarded";
114556
 
+       }
114557
 
+}
114558
 
+
114559
 
+test "Duplicates" {
114560
 
+       if not allof (
114561
 
+               test_script_compile "fileinto-inbox.sieve",
114562
 
+               test_script_run ){
114563
 
+               test_fail "failed to compile and run first script";
114564
 
+       }
114565
 
+
114566
 
+       if not test_result_execute {
114567
 
+               test_fail "result execute failed after first script";
114568
 
+       }
114569
 
+
114570
 
+       if not allof ( 
114571
 
+               test_script_compile "fileinto-inbox.sieve",
114572
 
+               test_script_run :append_result ) {
114573
 
+               test_fail "failed to compile and run second script";
114574
 
+       }
114575
 
+
114576
 
+       if not test_result_execute {
114577
 
+               test_fail "result execute failed after second script";
114578
 
+       }
114579
 
+
114580
 
+       if not allof ( 
114581
 
+               test_script_compile "keep.sieve",
114582
 
+               test_script_run :append_result ) {
114583
 
+               test_fail "failed to compile and run third script";
114584
 
+       }
114585
 
+
114586
 
+       if not test_result_execute {
114587
 
+               test_fail "result execute failed after third script";
114588
 
+       }
114589
 
+
114590
 
+       test_result_print;
114591
 
+
114592
 
+       if not test_result :index 1 "keep" {
114593
 
+               test_fail "first action is not 'keep'";
114594
 
+       }
114595
 
+
114596
 
+       if test_result :index 2 "store" {
114597
 
+               test_fail "fileinto action not discarded";
114598
 
+       }
114599
 
+}
114600
 
+
114601
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/multiscript/fileinto-frop.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/multiscript/fileinto-frop.sieve
114602
 
--- dovecot-1.2.4/dovecot-libsieve/tests/multiscript/fileinto-frop.sieve        1970-01-01 01:00:00.000000000 +0100
114603
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/multiscript/fileinto-frop.sieve 2009-01-06 00:15:52.000000000 +0100
114604
 
@@ -0,0 +1,3 @@
114605
 
+require "fileinto";
114606
 
+
114607
 
+fileinto "frop";
114608
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/multiscript/fileinto-inbox.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/multiscript/fileinto-inbox.sieve
114609
 
--- dovecot-1.2.4/dovecot-libsieve/tests/multiscript/fileinto-inbox.sieve       1970-01-01 01:00:00.000000000 +0100
114610
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/multiscript/fileinto-inbox.sieve        2009-01-06 00:15:52.000000000 +0100
114611
 
@@ -0,0 +1,4 @@
114612
 
+require "fileinto";
114613
 
+
114614
 
+fileinto "INBOX";
114615
 
+
114616
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/multiscript/keep.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/multiscript/keep.sieve
114617
 
--- dovecot-1.2.4/dovecot-libsieve/tests/multiscript/keep.sieve 1970-01-01 01:00:00.000000000 +0100
114618
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/multiscript/keep.sieve  2009-01-06 00:15:52.000000000 +0100
114619
 
@@ -0,0 +1 @@
114620
 
+keep;
114621
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/multiscript/notify.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/multiscript/notify.sieve
114622
 
--- dovecot-1.2.4/dovecot-libsieve/tests/multiscript/notify.sieve       1970-01-01 01:00:00.000000000 +0100
114623
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/multiscript/notify.sieve        2009-01-06 00:15:52.000000000 +0100
114624
 
@@ -0,0 +1,3 @@
114625
 
+require "enotify";
114626
 
+
114627
 
+notify "mailto:stephan@rename-it.nl";
114628
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/multiscript/reject-1.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/multiscript/reject-1.sieve
114629
 
--- dovecot-1.2.4/dovecot-libsieve/tests/multiscript/reject-1.sieve     1970-01-01 01:00:00.000000000 +0100
114630
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/multiscript/reject-1.sieve      2009-01-06 00:15:52.000000000 +0100
114631
 
@@ -0,0 +1,3 @@
114632
 
+require "reject";
114633
 
+
114634
 
+reject "Message is not wanted.";
114635
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/multiscript/reject-2.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/multiscript/reject-2.sieve
114636
 
--- dovecot-1.2.4/dovecot-libsieve/tests/multiscript/reject-2.sieve     1970-01-01 01:00:00.000000000 +0100
114637
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/multiscript/reject-2.sieve      2009-01-06 00:15:52.000000000 +0100
114638
 
@@ -0,0 +1,3 @@
114639
 
+require "reject";
114640
 
+
114641
 
+reject "Will not accept this nonsense.";
114642
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/multiscript/vacation.sieve dovecot-1.2.4.debian/dovecot-libsieve/tests/multiscript/vacation.sieve
114643
 
--- dovecot-1.2.4/dovecot-libsieve/tests/multiscript/vacation.sieve     1970-01-01 01:00:00.000000000 +0100
114644
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/multiscript/vacation.sieve      2009-01-06 00:15:52.000000000 +0100
114645
 
@@ -0,0 +1,3 @@
114646
 
+require "vacation";
114647
 
+
114648
 
+vacation "I am not home";
114649
 
diff -urN dovecot-1.2.4/dovecot-libsieve/tests/testsuite.svtest dovecot-1.2.4.debian/dovecot-libsieve/tests/testsuite.svtest
114650
 
--- dovecot-1.2.4/dovecot-libsieve/tests/testsuite.svtest       1970-01-01 01:00:00.000000000 +0100
114651
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/tests/testsuite.svtest        2009-01-06 00:15:52.000000000 +0100
114652
 
@@ -0,0 +1,75 @@
114653
 
+require "vnd.dovecot.testsuite";
114654
 
+require "envelope";
114655
 
+
114656
 
+/* Test message environment */
114657
 
+
114658
 
+test "Message Environment" {
114659
 
+       test_set "message" text:
114660
 
+From: sirius@rename-it.nl
114661
 
+To: nico@vestingbar.nl
114662
 
+Subject: Frop!
114663
 
+
114664
 
+Frop!
114665
 
+.
114666
 
+       ;
114667
 
+
114668
 
+       if not header :contains "from" "rename-it.nl" {
114669
 
+               test_fail "message data not set properly.";
114670
 
+       }
114671
 
+
114672
 
+       test_set "message" text:
114673
 
+From: nico@vestingbar.nl
114674
 
+To: stephan@zuiphol.nl
114675
 
+Subject: Friep!
114676
 
+
114677
 
+Friep!
114678
 
+.
114679
 
+       ;
114680
 
+
114681
 
+       if not header :is "from" "nico@vestingbar.nl" {
114682
 
+       test_fail "message data not set properly.";
114683
 
+       } 
114684
 
+
114685
 
+       keep;
114686
 
+}
114687
 
+
114688
 
+/* Test envelope environment */
114689
 
+
114690
 
+test "Envelope Environment" {
114691
 
+       test_set "envelope.from" "stephan@hutsefluts.nl";
114692
 
+
114693
 
+       if not envelope :is "from" "stephan@hutsefluts.nl" {
114694
 
+        test_fail "envelope.from data not set properly (1).";
114695
 
+    }
114696
 
+
114697
 
+       test_set "envelope.to" "news@rename-it.nl";
114698
 
+
114699
 
+       if not envelope :is "to" "news@rename-it.nl" {
114700
 
+        test_fail "envelope.to data not set properly (1).";
114701
 
+    }
114702
 
+
114703
 
+       test_set "envelope.auth" "sirius";
114704
 
+
114705
 
+    if not envelope :is "auth" "sirius" {
114706
 
+        test_fail "envelope.auth data not set properly (1).";
114707
 
+    }
114708
 
+
114709
 
+       test_set "envelope.from" "stephan@rename-it.nl";
114710
 
+
114711
 
+       if not envelope :is "from" "stephan@rename-it.nl" {
114712
 
+        test_fail "envelope.from data not reset properly (2).";
114713
 
+    }
114714
 
+
114715
 
+       test_set "envelope.to" "past-news@rename-it.nl";
114716
 
+
114717
 
+       if not envelope :is "to" "past-news@rename-it.nl" {
114718
 
+        test_fail "envelope.to data not reset properly (2).";
114719
 
+    }
114720
 
+
114721
 
+       test_set "envelope.auth" "zilla";
114722
 
+
114723
 
+    if not envelope :is "auth" "zilla" {
114724
 
+        test_fail "envelope.auth data not reset properly (2).";
114725
 
+    }
114726
 
+}
114727
 
+
114728
 
diff -urN dovecot-1.2.4/dovecot-libsieve/TODO dovecot-1.2.4.debian/dovecot-libsieve/TODO
114729
 
--- dovecot-1.2.4/dovecot-libsieve/TODO 1970-01-01 01:00:00.000000000 +0100
114730
 
+++ dovecot-1.2.4.debian/dovecot-libsieve/TODO  2009-08-21 00:52:15.000000000 +0200
114731
 
@@ -0,0 +1,99 @@
114732
 
+Current activities:
114733
 
+
114734
 
+* Build a sieve tool to filter an entire existing mailbox through a Sieve 
114735
 
+  script:
114736
 
+       - Add commandline options to fully customize execution
114737
 
+       - Write manual page
114738
 
+
114739
 
+Next (in order of descending priority/precedence):
114740
 
+
114741
 
+* Implement namespace support for variables extension (to complete include 
114742
 
+  extension)
114743
 
+* Update include extension to latest draft:
114744
 
+       - Perform script name check
114745
 
+       - Implement global namespace
114746
 
+       - Allow placing the global command anywhere in the script
114747
 
+* Implement mechanism for implicitly including an account's aliases in the
114748
 
+  vacation command's :addresses list.
114749
 
+* Improve error handling. Now it is not very consistent, especially for the 
114750
 
+  Sieve command line tools. 
114751
 
+* Detect permission errors when writing global script binaries and advise the 
114752
 
+  administrator on using sievec to precompile the scripts. 
114753
 
+* Improve debugging support in the sieve-test tool:
114754
 
+       - Improve trace debugging towards something more intuitively readable.
114755
 
+       - Give trace debugging multiple levels of verbosity (e.g. to include more 
114756
 
+    messy output like value matching).
114757
 
+* Implement dropping errors in the user's mailbox as a mail message.
114758
 
+* Implement a better way to encode source line numbers into a binary for
114759
 
+  reporting errors at runtime. Currently, this is done explicitly for each 
114760
 
+  command that adds actions to the result. However, some tests, match types etc. 
114761
 
+  will also need this when the variables extension is active. Many of the RFC 
114762
 
+  deviations listed below depend on this. Also trace debugging will benefit.
114763
 
+* Fix remaining RFC deviations:
114764
 
+       - Fix issues listed in doc/rfc/RFC-questions.txt based on answers
114765
 
+       - Allow for the existance of dynamic comparators (i.e. specified by 
114766
 
+         variables). 
114767
 
+       - Allow for :regex matching with variable key.
114768
 
+       - Detect assignment of too large constant values to variables at compile
114769
 
+         time.
114770
 
+       - Verify outgoing mail addresses at runtime when necessary
114771
 
+         (e.g. after variables substitution)
114772
 
+       - Vacation: the ":subject" parameter specifies a subject line to attach to 
114773
 
+         any vacation response that is generated. UTF-8 characters can be used in
114774
 
+         the string argument; implementations MUST convert the string to [RFC2047]
114775
 
+         encoded words if and only if non-ASCII characters are present.
114776
 
+       - Body: contains various issues that need to be resolved for standards
114777
 
+         compliance. Body test support currently matches but barely exceeds the
114778
 
+         original CMU Sieve implentation in terms of standards compliance.
114779
 
+       - Improve handling of invalid addresses in headers (requires Dovecot changes)
114780
 
+* Add normalize() method to comparators to normalize the string before matching
114781
 
+  (for efficiency).
114782
 
+* Properly implement Sieve internationalization support (utf-8 handling), 
114783
 
+  currently it is not complete:
114784
 
+       - Make this implementation conform section 2.7.2 of RFC5228 (Comparisons 
114785
 
+         Across Character Sets). 
114786
 
+       - Verify validity of utf8 where necessary.
114787
 
+       - Implement comparator-i;unicode-casemap.
114788
 
+* Make testsuite much more exhaustive:
114789
 
+       - add support for testing the content of result actions
114790
 
+       - test as many error/warning/info conditions as possible. 
114791
 
+       - review the specification documents and check whether the given conditions
114792
 
+         are tested at least once.
114793
 
+* Code cleanup:
114794
 
+       - Make address handling more uniform. 
114795
 
+       - Review all FIXMEs 
114796
 
+
114797
 
+* Build a server with test mail accounts that processes lots and lots of mail 
114798
 
+  (e.g. spam, mailing lists etc.)
114799
 
+
114800
 
+* ## MAKE A SECOND RELEASE (0.2.x) ##
114801
 
+
114802
 
+* Provide a solution for mail_get_headers_utf8 reparsing the whole message each
114803
 
+  time it is called (header and address test; Timo might provide solution from
114804
 
+  within Dovecot)
114805
 
+* Optimize code containing true/false tests to omit explicit JMP opcodes
114806
 
+  (i.e. optimize the test away and any code that negatively depends on it)
114807
 
+* Use lib/str-find.h for :contains and :matches match types 
114808
 
+* Warn during compile if using non-existent folders.
114809
 
+* Implement index extension
114810
 
+* Enotify extension: detect use of variable values extracted from the message 
114811
 
+  that are used in the method argument. RFC reports this as a security issue.
114812
 
+* Implement editheader extension
114813
 
+* Implement mimeloop extension
114814
 
+* Import ManageSieve into this package and provide support for alternate types
114815
 
+  of script storage like LDAP or SQL database.
114816
 
+
114817
 
+* Implement IMAP plugin for IMAPSieve support:
114818
 
+       - This may include support for manually running a script on a set of messages
114819
 
+         through IMAP (no specification for something like this is available; we will 
114820
 
+         have to provide our own)
114821
 
+* Variables extension: implement compile time evaluation of constant values
114822
 
+* Make the engine and its extensions much more configurable. Possibly this can 
114823
 
+  be merged with Dovecot's new master config implementation.
114824
 
+* Add development documentation, i.e. comment on library functions and document
114825
 
+  the binary and byte-code format. 
114826
 
+* Give the byte code format some more thought, it is currently quite rough and
114827
 
+  to the point. 
114828
 
+* Implement proposed notify mechanisms other than mailto. Currently defined: 
114829
 
+  xmpp and sip
114830
 
+