Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F117886168
sieved.c
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
26 KB
Referenced Files
None
Subscribers
None
sieved.c
View Options
/* sieved.c -- bytecode decompiler
* Jen Smith
*
* Copyright (c) 1994-2008 Carnegie Mellon University. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The name "Carnegie Mellon University" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For permission or any legal
* details, please contact
* Carnegie Mellon University
* Center for Technology Transfer and Enterprise Creation
* 4615 Forbes Avenue
* Suite 302
* Pittsburgh, PA 15213
* (412) 268-7393, fax: (412) 268-7395
* innovation@andrew.cmu.edu
*
* 4. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by Computing Services
* at Carnegie Mellon University (http://www.cmu.edu/computing/)."
*
* CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
* THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifdef HAVE_CONFIG_H
#include
<config.h>
#endif
#include
"sieve_interface.h"
#include
"bytecode.h"
#include
"script.h"
#include
"xmalloc.h"
#include
<sys/types.h>
#include
<sys/stat.h>
#include
<fcntl.h>
#include
<unistd.h>
#include
<netinet/in.h>
#include
<string.h>
#include
"map.h"
static
void
dump2
(
bytecode_input_t
*
d
,
int
len
);
static
int
dump2_test
(
bytecode_input_t
*
d
,
int
i
,
int
version
);
/* from bc_eval.c */
int
unwrap_string
(
bytecode_input_t
*
bc
,
int
pos
,
const
char
**
str
,
int
*
len
);
/*this is called by xmalloc*/
EXPORTED
void
fatal
(
const
char
*
s
,
int
code
)
{
fprintf
(
stderr
,
"Fatal error: %s (%d)
\r\n
"
,
s
,
code
);
exit
(
1
);
}
static
int
load
(
int
fd
,
bytecode_input_t
**
d
)
{
const
char
*
data
=
NULL
;
struct
stat
sbuf
;
size_t
len
=
0
;
if
(
fstat
(
fd
,
&
sbuf
)
==
-1
)
{
fprintf
(
stderr
,
"IOERROR: fstating sieve script: %m"
);
return
SIEVE_FAIL
;
}
/*this reads in data and length from file*/
map_refresh
(
fd
,
1
,
&
(
data
),
&
len
,
sbuf
.
st_size
,
"sievescript"
,
""
);
*
d
=
(
bytecode_input_t
*
)
data
;
printf
(
"
\n
"
);
return
(
len
/
sizeof
(
int
));
}
int
main
(
int
argc
,
char
*
argv
[])
{
bytecode_input_t
*
bc
=
NULL
;
int
script_fd
;
unsigned
long
len
;
if
(
argc
!=
2
)
{
fprintf
(
stderr
,
"usage:
\n
%s script
\n
"
,
argv
[
0
]);
exit
(
1
);
}
/*get script*/
script_fd
=
open
(
argv
[
1
],
O_RDONLY
);
if
(
script_fd
==
-1
)
{
fprintf
(
stderr
,
"can not open script '%s'
\n
"
,
argv
[
1
]);
exit
(
1
);
}
len
=
load
(
script_fd
,
&
bc
);
close
(
script_fd
);
if
(
bc
)
{
dump2
(
bc
,
len
);
exit
(
0
);
}
else
{
exit
(
1
);
}
}
static
int
write_list
(
int
list_len
,
int
i
,
bytecode_input_t
*
d
)
{
int
x
;
i
++
;
for
(
x
=
0
;
x
<
list_len
;
x
++
)
{
const
char
*
data
;
int
len
;
i
=
unwrap_string
(
d
,
i
,
&
data
,
&
len
);
printf
(
"{%d}%s
\n
"
,
len
,
data
);
}
return
i
;
}
static
int
printComparison
(
bytecode_input_t
*
d
,
int
i
)
{
printf
(
"Comparison: "
);
switch
(
ntohl
(
d
[
i
].
value
))
{
case
B_IS
:
printf
(
"Is"
);
break
;
case
B_CONTAINS
:
printf
(
"Contains"
);
break
;
case
B_MATCHES
:
printf
(
"Matches"
);
break
;
case
B_REGEX
:
printf
(
"Regex"
);
break
;
case
B_LIST
:
printf
(
"List"
);
break
;
case
B_COUNT
:
printf
(
"Count"
);
switch
(
ntohl
(
d
[
i
+
1
].
value
))
{
case
B_GT
:
printf
(
" greater than "
);
break
;
case
B_GE
:
printf
(
" greater than or equal "
);
break
;
case
B_LT
:
printf
(
" less than "
);
break
;
case
B_LE
:
printf
(
" less than or equal "
);
break
;
case
B_NE
:
printf
(
" not equal "
);
break
;
case
B_EQ
:
printf
(
" equal "
);
break
;
}
break
;
case
B_VALUE
:
printf
(
"Value"
);
switch
(
ntohl
(
d
[
i
+
1
].
value
))
{
case
B_GT
:
printf
(
" greater than "
);
break
;
case
B_GE
:
printf
(
" greater than or equal "
);
break
;
case
B_LT
:
printf
(
" less than "
);
break
;
case
B_LE
:
printf
(
" less than or equal "
);
break
;
case
B_NE
:
printf
(
" not equal "
);
break
;
case
B_EQ
:
printf
(
" equal "
);
break
;
}
break
;
default
:
exit
(
1
);
}
switch
(
ntohl
(
d
[
i
+
2
].
value
))
{
case
B_ASCIICASEMAP
:
printf
(
" (ascii-casemap) "
);
break
;
case
B_OCTET
:
printf
(
" (octet) "
);
break
;
case
B_ASCIINUMERIC
:
printf
(
" (ascii-numeric) "
);
break
;
default
:
exit
(
1
);
}
printf
(
"
\n
"
);
return
i
+
3
;
}
static
int
dump2_test
(
bytecode_input_t
*
d
,
int
i
,
int
version
)
{
int
l
,
x
,
index
;
int
opcode
;
int
has_index
=
0
;
/* used to differentiate between pre and post index tests */
opcode
=
ntohl
(
d
[
i
].
value
);
switch
(
opcode
)
{
case
BC_FALSE
:
printf
(
"false"
);
i
++
;
break
;
case
BC_TRUE
:
printf
(
"true"
);
i
++
;
break
;
case
BC_NOT
:
/*2*/
/* XXX
there is a value being skipped in the second pass...
no idea what it does, but it isn't carried to here...
see bytecodee.c */
printf
(
" not("
);
i
=
dump2_test
(
d
,
i
+
1
,
version
);
printf
(
")
\n
"
);
break
;
case
BC_EXISTS
:
printf
(
"exists"
);
i
=
write_list
(
ntohl
(
d
[
i
+
1
].
len
),
i
+
2
,
d
);
break
;
case
BC_VALIDEXTLIST
:
printf
(
"valid_ext_list"
);
i
=
write_list
(
ntohl
(
d
[
i
+
1
].
len
),
i
+
2
,
d
);
break
;
case
BC_SIZE
:
printf
(
"size"
);
if
(
ntohl
(
d
[
i
+
1
].
value
)
==
B_OVER
)
{
/* over */
printf
(
"over %d"
,
ntohl
(
d
[
i
+
2
].
value
));
}
else
{
/* under */
printf
(
"under %d"
,
ntohl
(
d
[
i
+
2
].
value
));
}
i
+=
3
;
break
;
case
BC_ANYOF
:
/*5*/
printf
(
"any of
\n
("
);
l
=
ntohl
(
d
[
i
+
1
].
len
);
i
+=
3
;
for
(
x
=
0
;
x
<
l
;
x
++
)
{
i
=
dump2_test
(
d
,
i
,
version
);
if
((
x
+
1
)
<
l
)
printf
(
" OR "
);
}
printf
(
")
\n
"
);
break
;
case
BC_ALLOF
:
/*6*/
printf
(
"all of
\n
("
);
l
=
ntohl
(
d
[
i
+
1
].
len
);
i
+=
3
;
for
(
x
=
0
;
x
<
l
;
x
++
)
{
i
=
dump2_test
(
d
,
i
,
version
);
if
((
x
+
1
)
<
l
)
printf
(
" AND "
);
}
printf
(
")
\n
"
);
break
;
case
BC_ADDRESS
:
/*13*/
has_index
=
1
;
/*fall-through*/
case
BC_ADDRESS_PRE_INDEX
:
/*7*/
if
(
0x07
==
version
&&
BC_ADDRESS_PRE_INDEX
==
opcode
)
{
/* There was a version of the bytecode that had the index extension
* but did not update the bytecode codepoints, nor did it increment
* the bytecode version number. This tests if the index extension
* was in the bytecode based on the position of the match-type
* argument.
* We test for the applicable version number explicitly.
*/
switch
(
ntohl
(
d
[
i
+
2
].
value
))
{
case
B_IS
:
case
B_CONTAINS
:
case
B_MATCHES
:
case
B_REGEX
:
case
B_COUNT
:
case
B_VALUE
:
has_index
=
1
;
break
;
default
:
has_index
=
0
;
}
}
printf
(
"Address ["
);
index
=
has_index
?
ntohl
(
d
[
++
i
].
value
)
:
0
;
i
=
printComparison
(
d
,
i
+
1
);
printf
(
" type: "
);
switch
(
ntohl
(
d
[
i
++
].
value
))
{
case
B_ALL
:
printf
(
"all"
);
break
;
case
B_LOCALPART
:
printf
(
"localpart"
);
break
;
case
B_DOMAIN
:
printf
(
"domain"
);
break
;
case
B_USER
:
printf
(
"user"
);
break
;
case
B_DETAIL
:
printf
(
"detail"
);
break
;
}
printf
(
"
\n
"
);
if
(
index
!=
0
)
{
printf
(
" Index: %d %s
\n
"
,
abs
(
index
),
index
<
0
?
"[LAST]"
:
""
);
}
printf
(
" Headers:"
);
i
=
write_list
(
ntohl
(
d
[
i
].
len
),
i
+
1
,
d
);
printf
(
" Data:"
);
i
=
write_list
(
ntohl
(
d
[
i
].
len
),
i
+
1
,
d
);
printf
(
" ]
\n
"
);
break
;
case
BC_ENVELOPE
:
/*8*/
printf
(
"Envelope ["
);
i
=
printComparison
(
d
,
i
+
1
);
printf
(
" type: "
);
switch
(
ntohl
(
d
[
i
++
].
value
))
{
case
B_ALL
:
printf
(
"all"
);
break
;
case
B_LOCALPART
:
printf
(
"localpart"
);
break
;
case
B_DOMAIN
:
printf
(
"domain"
);
break
;
case
B_USER
:
printf
(
"user"
);
break
;
case
B_DETAIL
:
printf
(
"detail"
);
break
;
}
printf
(
" Headers:"
);
i
=
write_list
(
ntohl
(
d
[
i
].
len
),
i
+
1
,
d
);
printf
(
" Data:"
);
i
=
write_list
(
ntohl
(
d
[
i
].
len
),
i
+
1
,
d
);
printf
(
" ]
\n
"
);
break
;
case
BC_HEADER
:
/*14*/
has_index
=
1
;
/*fall-through*/
case
BC_HEADER_PRE_INDEX
:
/*9*/
if
(
0x07
==
version
&&
BC_HEADER_PRE_INDEX
==
opcode
)
{
/* There was a version of the bytecode that had the index extension
* but did not update the bytecode codepoints, nor did it increment
* the bytecode version number. This tests if the index extension
* was in the bytecode based on the position of the match-type
* argument.
* We test for the applicable version number explicitly.
*/
switch
(
ntohl
(
d
[
i
+
2
].
value
))
{
case
B_IS
:
case
B_CONTAINS
:
case
B_MATCHES
:
case
B_REGEX
:
case
B_COUNT
:
case
B_VALUE
:
has_index
=
1
;
break
;
default
:
has_index
=
0
;
}
}
printf
(
"Header ["
);
index
=
has_index
?
ntohl
(
d
[
++
i
].
value
)
:
0
;
i
=
printComparison
(
d
,
i
+
1
);
if
(
index
!=
0
)
{
printf
(
" Index: %d %s
\n
"
,
abs
(
index
),
index
<
0
?
"[LAST]"
:
""
);
}
printf
(
" Headers: "
);
i
=
write_list
(
ntohl
(
d
[
i
].
len
),
i
+
1
,
d
);
printf
(
" Data: "
);
i
=
write_list
(
ntohl
(
d
[
i
].
len
),
i
+
1
,
d
);
printf
(
" ]
\n
"
);
break
;
case
BC_HASFLAG
:
/*15*/
case
BC_STRING
:
/*21*/
if
(
BC_HASFLAG
==
opcode
)
{
printf
(
"Hasflag ["
);
}
else
{
printf
(
"String ["
);
}
i
=
printComparison
(
d
,
i
+
1
);
printf
(
" Variables: "
);
i
=
write_list
(
ntohl
(
d
[
i
].
len
),
i
+
1
,
d
);
printf
(
" Data: "
);
i
=
write_list
(
ntohl
(
d
[
i
].
len
),
i
+
1
,
d
);
printf
(
" ]
\n
"
);
break
;
case
BC_BODY
:
/*10*/
printf
(
"Body ["
);
i
=
printComparison
(
d
,
i
+
1
);
printf
(
" Transform: "
);
switch
(
ntohl
(
d
[
i
++
].
value
))
{
case
B_RAW
:
printf
(
"raw"
);
break
;
case
B_TEXT
:
printf
(
"text"
);
break
;
case
B_CONTENT
:
printf
(
"content"
);
break
;
}
printf
(
"
\t
Offset: %d
\n
"
,
ntohl
(
d
[
i
++
].
value
));
printf
(
" Content-Types:"
);
i
=
write_list
(
ntohl
(
d
[
i
].
len
),
i
+
1
,
d
);
printf
(
" Data:"
);
i
=
write_list
(
ntohl
(
d
[
i
].
len
),
i
+
1
,
d
);
printf
(
" ]
\n
"
);
break
;
case
BC_DATE
:
/*11*/
has_index
=
1
;
case
BC_CURRENTDATE
:
/*12*/
if
(
0x07
==
version
)
{
/* There was a version of the bytecode that had the index extension
* but did not update the bytecode codepoints, nor did it increment
* the bytecode version number. This tests if the index extension
* was in the bytecode based on the position of the match-type
* or comparator argument. This will correctly identify whether
* the index extension was supported in every case except the case
* of a timezone that is 61 minutes offset (since 61 corresponds to
* B_ORIGINALZONE).
* There was also an unnumbered version of BC_CURRENTDATE that did
* allow :index. This also covers that case.
* We test for the applicable version number explicitly.
*/
switch
(
ntohl
(
d
[
i
+
4
].
value
))
{
/* if the 4th parameter is a comparator, we have neither :index nor
* :zone tags. B_ORIGINALZONE is the first parameter.
*/
case
B_ASCIICASEMAP
:
case
B_OCTET
:
case
B_ASCIINUMERIC
:
has_index
=
0
;
break
;
default
:
/* otherwise, we either have a :zone tag, an :index tag, or
* both
*/
switch
(
ntohl
(
d
[
i
+
5
].
value
))
{
/* if the 5th paramater is a comparator, we have either :index
* or :zone, but not both.
*/
case
B_ASCIICASEMAP
:
case
B_OCTET
:
case
B_ASCIINUMERIC
:
/* The ambiguous case is B_TIMEZONE as 1st parameter and
* B_ORIGINALZONE as second parameter, which could mean
* either ':index 60 :originalzone' or ':zone "+0101"'
*/
if
(
B_TIMEZONE
==
ntohl
(
d
[
i
+
1
].
value
)
&&
B_ORIGINALZONE
==
ntohl
(
d
[
i
+
2
].
value
))
{
/* This is the ambiguous case. Resolve the ambiguity
* by assuming that there is no :index tag since the
* unnumbered bytecode that shipped with Kolab
* Groupware 3.3 included support for the date
* extension, but not for the index extension.
*/
has_index
=
0
;
}
else
if
(
B_TIMEZONE
==
ntohl
(
d
[
i
+
1
].
value
))
{
/* if the first parameter is B_TIMEZONE, and the above
* test was false, it must be a :zone tag, and we
* don't have :index.
*/
has_index
=
0
;
}
else
{
/* if the first parameter is not B_TIMEZONE, it must
* be an :index tag, and we don't have :zone.
*/
has_index
=
1
;
}
break
;
default
:
/* if the 5th parameter is not a comparator, the 6th is,
* and we have both :index and :zone
*/
has_index
=
1
;
}
}
}
++
i
;
/* skip opcode */
if
(
BC_DATE
==
opcode
)
{
printf
(
"date ["
);
}
else
{
printf
(
"currentdate ["
);
}
/* index */
index
=
has_index
?
ntohl
(
d
[
i
++
].
value
)
:
0
;
if
(
index
!=
0
)
{
printf
(
" Index: %d %s
\n
"
,
abs
(
index
),
index
<
0
?
"[LAST]"
:
""
);
}
/* zone tag */
{
printf
(
"Zone-Tag: "
);
switch
(
ntohl
(
d
[
i
++
].
value
))
{
case
B_TIMEZONE
:
printf
(
"Specific timezone: offset by %d minutes.
\n
"
,
ntohl
(
d
[
i
++
].
value
));
break
;
case
B_ORIGINALZONE
:
printf
(
"Original zone.
\n
"
);
break
;
}
}
i
=
printComparison
(
d
,
i
);
printf
(
" Date-Type: "
);
switch
(
ntohl
(
d
[
i
++
].
value
))
{
case
B_YEAR
:
printf
(
"year
\n
"
);
break
;
case
B_MONTH
:
printf
(
"month
\n
"
);
break
;
case
B_DAY
:
printf
(
"day
\n
"
);
break
;
case
B_DATE
:
printf
(
"date
\n
"
);
break
;
case
B_JULIAN
:
printf
(
"julian
\n
"
);
break
;
case
B_HOUR
:
printf
(
"hour
\n
"
);
break
;
case
B_MINUTE
:
printf
(
"minute
\n
"
);
break
;
case
B_SECOND
:
printf
(
"second
\n
"
);
break
;
case
B_TIME
:
printf
(
"time
\n
"
);
break
;
case
B_ISO8601
:
printf
(
"iso8601
\n
"
);
break
;
case
B_STD11
:
printf
(
"std11
\n
"
);
break
;
case
B_ZONE
:
printf
(
"zone
\n
"
);
break
;
case
B_WEEKDAY
:
printf
(
"weekday
\n
"
);
break
;
}
/* header name */
if
(
BC_DATE
==
opcode
)
{
const
char
*
data
;
int
len
;
i
=
unwrap_string
(
d
,
i
,
&
data
,
&
len
);
printf
(
" Header Name: {%d}%s
\n
"
,
len
,
data
);
}
printf
(
" Key List: "
);
i
=
write_list
(
ntohl
(
d
[
i
].
len
),
i
+
1
,
d
);
printf
(
" ]
\n
"
);
break
;
case
BC_MAILBOXEXISTS
:
/*16*/
case
BC_METADATAEXISTS
:
/*18*/
case
BC_SERVERMETADATAEXISTS
:
/*20*/
++
i
;
/* skip opcode */
if
(
BC_MAILBOXEXISTS
==
opcode
)
{
printf
(
"MailboxExists ["
);
}
else
if
(
BC_SERVERMETADATAEXISTS
==
opcode
)
{
printf
(
"ServerMetaDataExists ["
);
}
else
{
const
char
*
data
;
int
len
;
printf
(
"MetaDataExists ["
);
i
=
unwrap_string
(
d
,
i
,
&
data
,
&
len
);
printf
(
" Mailbox Name: {%d}%s
\n
"
,
len
,
data
);
}
printf
(
" Key List: "
);
i
=
write_list
(
ntohl
(
d
[
i
].
len
),
i
+
1
,
d
);
printf
(
" ]
\n
"
);
break
;
case
BC_METADATA
:
/*17*/
case
BC_SERVERMETADATA
:
/*19*/
{
const
char
*
data
;
int
len
;
if
(
BC_METADATA
==
opcode
)
{
printf
(
"MetaData ["
);
}
else
{
printf
(
"ServerMetaData ["
);
}
i
=
printComparison
(
d
,
i
+
1
);
if
(
BC_METADATA
==
opcode
)
{
i
=
unwrap_string
(
d
,
i
,
&
data
,
&
len
);
printf
(
" Mailbox Name: {%d}%s
\n
"
,
len
,
data
);
}
i
=
unwrap_string
(
d
,
i
,
&
data
,
&
len
);
printf
(
" Key Name: {%d}%s
\n
"
,
len
,
data
);
printf
(
" Key List: "
);
i
=
write_list
(
ntohl
(
d
[
i
].
len
),
i
+
1
,
d
);
printf
(
" ]
\n
"
);
break
;
}
default
:
printf
(
"WERT %d "
,
ntohl
(
d
[
i
].
value
));
}
return
i
;
}
static
void
dump2
(
bytecode_input_t
*
d
,
int
bc_len
)
{
int
i
;
int
version
;
const
char
*
data
;
int
len
;
if
(
!
d
)
return
;
if
(
memcmp
(
d
,
BYTECODE_MAGIC
,
BYTECODE_MAGIC_LEN
))
{
printf
(
"not a bytecode file [magic number test failed]
\n
"
);
return
;
}
i
=
BYTECODE_MAGIC_LEN
/
sizeof
(
bytecode_input_t
);
version
=
ntohl
(
d
[
i
].
op
);
printf
(
"Sievecode version %d
\n
"
,
version
);
if
(
version
>=
0x11
&&
ntohl
(
d
[
++
i
].
value
)
&
BFE_VARIABLES
)
{
printf
(
"Require Variables
\n
"
);
}
for
(
i
++
;
i
<
bc_len
;)
{
int
op
;
int
list
=
0
;
int
copy
=
0
;
int
create
=
0
;
int
supports_variables
=
0
;
printf
(
"%d: "
,
i
);
op
=
ntohl
(
d
[
i
++
].
op
);
switch
(
op
)
{
case
B_STOP
:
/*0*/
printf
(
"STOP
\n
"
);
break
;
case
B_KEEP
:
/*22*/
printf
(
"KEEP FLAGS {%d}
\n
"
,
ntohl
(
d
[
i
].
listlen
));
i
=
write_list
(
ntohl
(
d
[
i
].
listlen
),
i
+
1
,
d
);
copy
=
ntohl
(
d
[
i
++
].
value
);
printf
(
" COPY(%d)
\n
"
,
copy
);
break
;
case
B_KEEP_ORIG
:
/*1*/
printf
(
"KEEP
\n
"
);
break
;
case
B_DISCARD
:
/*2*/
printf
(
"DISCARD
\n
"
);
break
;
case
B_REJECT
:
/*3*/
case
B_EREJECT
:
/*31*/
i
=
unwrap_string
(
d
,
i
,
&
data
,
&
len
);
printf
(
"%s {%d}%s
\n
"
,
(
op
==
B_EREJECT
)
?
"EREJECT"
:
"REJECT"
,
len
,
data
);
break
;
case
B_FILEINTO
:
/*24*/
create
=
ntohl
(
d
[
i
++
].
value
);
/* fall through */
case
B_FILEINTO_FLAGS
:
/*23*/
printf
(
"FILEINTO FLAGS {%d}
\n
"
,
ntohl
(
d
[
i
].
listlen
));
i
=
write_list
(
ntohl
(
d
[
i
].
listlen
),
i
+
1
,
d
);
copy
=
ntohl
(
d
[
i
++
].
value
);
i
=
unwrap_string
(
d
,
i
,
&
data
,
&
len
);
printf
(
" CREATE(%d) COPY(%d) FOLDER({%d}%s)
\n
"
,
create
,
copy
,
len
,
data
);
break
;
case
B_FILEINTO_COPY
:
/*19*/
copy
=
ntohl
(
d
[
i
++
].
value
);
/* fall through */
case
B_FILEINTO_ORIG
:
/*4*/
i
=
unwrap_string
(
d
,
i
,
&
data
,
&
len
);
printf
(
"FILEINTO COPY(%d) CREATE(%d) FOLDER({%d}%s)
\n
"
,
copy
,
create
,
len
,
data
);
break
;
case
B_REDIRECT
:
/*32*/
list
=
ntohl
(
d
[
i
++
].
value
);
/* fall through */
case
B_REDIRECT_COPY
:
/*20*/
copy
=
ntohl
(
d
[
i
++
].
value
);
/* fall through */
case
B_REDIRECT_ORIG
:
/*5*/
i
=
unwrap_string
(
d
,
i
,
&
data
,
&
len
);
printf
(
"REDIRECT COPY(%d) LIST(%d) ADDRESS({%d}%s)
\n
"
,
copy
,
list
,
len
,
data
);
break
;
case
B_IF
:
/*6*/
printf
(
"IF (ends at %d)"
,
ntohl
(
d
[
i
].
value
));
/* there is no short circuiting involved here*/
i
=
dump2_test
(
d
,
i
+
1
,
version
);
printf
(
"
\n
"
);
break
;
case
B_MARK
:
/*7*/
printf
(
"MARK
\n
"
);
break
;
case
B_UNMARK
:
/*8*/
printf
(
"UNMARK
\n
"
);
break
;
case
B_ADDFLAG
:
/*26*/
case
B_SETFLAG
:
/*27*/
case
B_REMOVEFLAG
:
/*28*/
i
=
unwrap_string
(
d
,
i
,
&
data
,
&
len
);
supports_variables
=
1
;
/* fall through */
case
B_ADDFLAG_ORIG
:
/*9*/
case
B_SETFLAG_ORIG
:
/*10*/
case
B_REMOVEFLAG_ORIG
:
/*11*/
switch
(
op
)
{
case
B_ADDFLAG_ORIG
:
case
B_ADDFLAG
:
printf
(
"ADDFLAG "
);
break
;
case
B_SETFLAG
:
case
B_SETFLAG_ORIG
:
printf
(
"SETFLAG "
);
break
;
case
B_REMOVEFLAG
:
case
B_REMOVEFLAG_ORIG
:
printf
(
"REMOVEFLAG "
);
break
;
}
if
(
supports_variables
)
{
printf
(
"VARIABLE({%d}%s) "
,
len
,
data
);
}
printf
(
"FLAGS {%d}
\n
"
,
ntohl
(
d
[
i
].
len
));
i
=
write_list
(
ntohl
(
d
[
i
].
len
),
i
+
1
,
d
);
break
;
case
B_DENOTIFY
:
/*13*/
printf
(
"DENOTIFY
\n
"
);
printf
(
" PRIORITY(%d) Comparison type %d (relat %d)
\n
"
,
ntohl
(
d
[
i
].
value
),
ntohl
(
d
[
i
+
1
].
value
),
ntohl
(
d
[
i
+
2
].
value
));
i
+=
3
;
i
=
unwrap_string
(
d
,
i
,
&
data
,
&
len
);
printf
(
" ({%d}%s)
\n
"
,
len
,
(
!
data
?
"[nil]"
:
data
));
break
;
case
B_ENOTIFY
:
/*33*/
case
B_NOTIFY
:
/*12*/
i
=
unwrap_string
(
d
,
i
,
&
data
,
&
len
);
printf
(
"NOTIFY METHOD({%d}%s)
\n
"
,
len
,
data
);
i
=
unwrap_string
(
d
,
i
,
&
data
,
&
len
);
printf
(
" %s({%d}%s) OPTIONS "
,
(
op
==
B_ENOTIFY
?
"FROM"
:
"ID"
),
len
,
(
!
data
?
"[nil]"
:
data
));
i
=
write_list
(
ntohl
(
d
[
i
].
len
),
i
+
1
,
d
);
printf
(
" %s(%d)
\n
"
,
(
op
==
B_ENOTIFY
?
"IMPORTANCE"
:
"PRIORITY"
),
ntohl
(
d
[
i
].
value
));
i
++
;
i
=
unwrap_string
(
d
,
i
,
&
data
,
&
len
);
printf
(
" MESSAGE({%d}%s)
\n
"
,
len
,
data
);
break
;
case
B_VACATION_ORIG
:
/*14*/
case
B_VACATION
:
/*22*/
printf
(
"VACATION
\n
"
);
/*add address list here!*/
i
=
write_list
(
ntohl
(
d
[
i
].
len
),
i
+
1
,
d
);
i
=
unwrap_string
(
d
,
i
,
&
data
,
&
len
);
printf
(
"%d SUBJ({%d}%s)
\n
"
,
i
,
len
,
(
!
data
?
"[nil]"
:
data
));
i
=
unwrap_string
(
d
,
i
,
&
data
,
&
len
);
printf
(
"%d MESG({%d}%s)
\n
"
,
i
,
len
,
(
!
data
?
"[nil]"
:
data
));
printf
(
"SECONDS(%d) MIME(%d)
\n
"
,
ntohl
(
d
[
i
].
value
)
*
(
op
==
B_VACATION
?
1
:
24
*
60
*
60
/* 1 day */
),
ntohl
(
d
[
i
+
1
].
value
));
i
+=
2
;
if
(
version
>=
0x05
)
{
i
=
unwrap_string
(
d
,
i
,
&
data
,
&
len
);
printf
(
"%d FROM({%d}%s)
\n
"
,
i
,
len
,
(
!
data
?
"[nil]"
:
data
));
i
=
unwrap_string
(
d
,
i
,
&
data
,
&
len
);
printf
(
"%d HANDLE({%d}%s)
\n
"
,
i
,
len
,
(
!
data
?
"[nil]"
:
data
));
}
break
;
case
B_NULL
:
/*15*/
printf
(
"NULL
\n
"
);
break
;
case
B_JUMP
:
/*16*/
printf
(
"JUMP %d
\n
"
,
ntohl
(
d
[
i
].
jump
));
i
+=
1
;
break
;
case
B_INCLUDE
:
/*17*/
printf
(
"INCLUDE "
);
switch
(
ntohl
(
d
[
i
].
value
)
&
63
)
{
case
B_PERSONAL
:
printf
(
"Personal"
);
break
;
case
B_GLOBAL
:
printf
(
"Global"
);
break
;
}
printf
(
" once:%s optional:%s"
,
ntohl
(
d
[
i
].
value
)
&
64
?
"yes"
:
"no"
,
ntohl
(
d
[
i
].
value
)
&
128
?
"yes"
:
"no"
);
i
=
unwrap_string
(
d
,
i
+
1
,
&
data
,
&
len
);
printf
(
" {%d}%s
\n
"
,
len
,
data
);
break
;
case
B_SET
:
/*25*/
{
int
m
=
ntohl
(
d
[
i
++
].
value
);
i
=
unwrap_string
(
d
,
i
,
&
data
,
&
len
);
printf
(
"SET "
);
printf
(
"LOWER(%d) UPPER(%d) LOWERFIRST(%d) UPPERFIRST(%d) "
"QUOTEWILDCARD(%d) ENCODEURL(%d) LENGTH(%d)
\n
"
,
m
&
BFV_LOWER
,
m
&
BFV_UPPER
,
m
&
BFV_LOWERFIRST
,
m
&
BFV_UPPERFIRST
,
m
&
BFV_QUOTEWILDCARD
,
m
&
BFV_ENCODEURL
,
m
&
BFV_LENGTH
);
printf
(
" VARS({%d}%s)"
,
len
,
data
);
i
=
unwrap_string
(
d
,
i
,
&
data
,
&
len
);
printf
(
" VALS({%d}%s)
\n
"
,
len
,
data
);
}
break
;
case
B_ADDHEADER
:
/*29*/
{
int
m
=
ntohl
(
d
[
i
++
].
value
);
printf
(
"ADDHEADER "
);
printf
(
"INDEX(%d)
\n
"
,
m
);
i
=
unwrap_string
(
d
,
i
,
&
data
,
&
len
);
printf
(
" NAME({%d}%s)"
,
len
,
data
);
i
=
unwrap_string
(
d
,
i
,
&
data
,
&
len
);
printf
(
" VAL({%d}%s)
\n
"
,
len
,
data
);
}
break
;
case
B_DELETEHEADER
:
/*30*/
{
int
m
=
ntohl
(
d
[
i
++
].
value
);
printf
(
"DELETEHEADER "
);
printf
(
"INDEX(%d)
\n
"
,
m
);
i
=
printComparison
(
d
,
i
);
i
=
unwrap_string
(
d
,
i
,
&
data
,
&
len
);
printf
(
" NAME({%d}%s)
\n
"
,
len
,
data
);
printf
(
" VALS("
);
i
=
write_list
(
ntohl
(
d
[
i
].
len
),
i
+
1
,
d
);
printf
(
")
\n
"
);
}
break
;
case
B_RETURN
:
/*18*/
printf
(
"RETURN
\n
"
);
break
;
default
:
printf
(
"%d (NOT AN OP)
\n
"
,
ntohl
(
d
[
i
-1
].
op
));
exit
(
1
);
}
}
printf
(
"full len is: %d
\n
"
,
bc_len
);
}
File Metadata
Details
Attached
Mime Type
text/x-c
Expires
Mon, Apr 6, 2:24 AM (1 w, 4 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
18795660
Default Alt Text
sieved.c (26 KB)
Attached To
Mode
R111 cyrus-imapd
Attached
Detach File
Event Timeline